Solitre is a traditional Chinese word game, it has a long history, also has a broad social basis, is suitable for the old and young folk cultural entertainment! General party will play this game to do interaction, there is a QQ idiom catch a dragon red envelope, sometimes because of their own idiom reserve is not enough, and can not go on.

So have you ever thought of yourself to achieve an idiom solitaire procedure? Next, I will use Python to achieve an idiom solitre small program, nonsense does not say, start ~~~~

Idiom to prepare

When it comes to idiom solitators, we must first ensure that we have enough idioms, this condition is not satisfied, I have no idioms ah, farewell ~

Joking, as a Python code farmer, climbing data is no problem, no idiom does not matter, there is a way, I found a website :chengyu.t086.com/list/A_1.ht… There are a lot of idioms and explanations on this website, I don’t say much nonsense, I will give it down.

Analysis of climbing ideas:

Caught over the web, analyze the following features: each request send out: http://chengyu.t086.com/list/ {a-z} _ {number}. The HTML this request, the following figure, is the first letter of the first page of A.

If there is a “next page” in the parsing page, turn the page in a loop, such as from chengyu.t086.com/list/A_1.ht… Flip to chengyu.t086.com/list/A_2.ht… , when the parsing page parsing is not “next page”, will request pinyin first letter of the next chengyu.t086.com/list/B_1.ht… The cycle goes on until the climb is over.

So you have two layers of loops, the first layer of loops a-Z, the second layer of loops page number, and then you spellhttp://chengyu.t086.com/list/ {a-z} _ {} page Numbers. The HTMLTo request, when there is no next page, jump out of the second layer of loop, loop the next pinyin first letter.

The following tag content is the jump link for the specific information of the idiom, to send a request for the link, the return is the interpretation of the idiom and other specific information. That’s what we need. We need to get down.

The code is as follows:

import requests
from bs4 import BeautifulSoup


class Idiom:
    def __init__(self) :
        self.num = 0
        self.url = 'http://chengyu.t086.com/list/{}_{}.html'
        self.url_info = 'http://chengyu.t086.com/{}'
        self.headers = {
                        'User-Agent': 'the Mozilla / 5.0 (Windows NT 10.0; Win64; X64) AppleWebKit/537.36 (KHTML, like Gecko) '
                        'the Chrome / 81.0.4044.43 Safari / 537.36'.'Referer': 'http://chengyu.t086.com/'
                        }
        self.all_idiom = {}
        self.pinyin_initials = ['A'.'B'.'C'.'D'.'E'.'F'.'G'.'H'.'J'.'K'.'L'.'M'.'N'.'O'.'P'.'Q'.'R'.'S'
                                , 'T'.'W'.'X'.'Y'.'Z']

    def idiom_spider(self) :
        """ Crawl to all idioms """
        idiom_list = []
        for initial in self.pinyin_initials:
            page = 1
            while True:
                url = self.url.format(initial, page)
                print(url)
                start_html = requests.get(url, headers=self.headers)
                start_html.encoding = 'gb18030'
                soup = BeautifulSoup(start_html.text, "html.parser")
                Select * from div where class=listw
                listw = soup.find('div', class_='listw')
                a2 = soup.find("div", class_="a2")
                # find all a tags
                lista = listw.find_all('a')
                lastpage = a2.find_all('a')
                for p in lista:
                    print("Words", p.text)
                    print((p["href"]))
                    info_url = self.url_info.format(p["href"])
                    print("infourl", info_url)
                    info_html = requests.get(info_url, headers=self.headers)
                    info_html.encoding = 'gb18030'
                    soup = BeautifulSoup(info_html.text, "html.parser")
                    # find all td tags
                    td_list = soup.findAll('td')
                    # Idioms
                    print("Meaning:", td_list[5].text)
                    new_idiom = {"idiom": p.text, "paraphrase": td_list[5].text, "first_pinxin":initial}
                    idiom_list.append(new_idiom)
                if not lastpage or str(lastpage[-1]).find("Next page") = = -1:  If there is no hyperlink tag for the next page, break
                    break
                page += 1


idiom = Idiom()
idiom.idiom_spider()
Copy the code

Running process diagram:

Can be in accordance with their own needs to save the idiom specified format, I am all the idioms savedsqlite3Database, because It’s built-in in Pythonsqlite3Database, therefore, used in Pythonsqlite3, do not need to install anything, can be convenient direct use, a total of 30880 idioms, may not be full, but also enough.

Idiom solitaire program

The realization principle does not say in fact, you may have thought of, is according to the crawl of the idiom, and the specified idiom string first and last condition matching, if the pinyin can match, is the success of the solitaire.

To see if pinyin is the same, there is a third-party library in Python, pypinyin, which can be installed using PIP install pypinyin. Use the following code to get the pinyin of the specified character:

from pypinyin import lazy_pinyin


print(lazy_pinyin("All vegetable Engineer"))
Copy the code

Results: [‘ quan ‘, ‘CAI’, ‘gong’, ‘cheng’, ‘shi’], is a list. Below I will break down the idiom solitaire program:

Determine whether it is an idiom

The logic is simple, which is to query whether the specified string is in the crawling idiom library. If it is, it is an idiom. If it is not, it is not:

Sqlite3 = sqlite3 = sqlite3 = sqlite3 = sqlite3 = sqlite3

import sqlite3


def sqlite_conn() :
    try:
        conn = sqlite3.connect('meta.db')
        return conn
    except Exception as e:
        print(e)
Copy the code

So, the code to determine whether it is an idiom is:

def idiom_exist(user_idiom) :
    """ query whether a specified idiom is in the idiom library :param user_idiom: string :return: bool """
    
    cursor = sqlite_conn().cursor()
    
    db_res = cursor.execute("SELECT id, idiom, paraphrase, first_pinxin from idiom where idiom='{}'".format(user_idiom))
    for idiom in db_res:
        if idiom[1] :return True
    return False
Copy the code

solitaire

Solitaire is also very simple, according to the user input idiom, to obtain the first letter of the idiom pinyin, according to the pinyin first letter query into the language base of the conditions of the idiom, in the determination of the first word pinyin of these idioms and the user input the last word pinyin is the same, in accordance with the conditions of the idiom, randomly return a:

def solitaire(user_idiom) :
    """ """ """ """ """ """ """ """ """ """
    cursor = sqlite_conn().cursor()
    If you do not specify an idiom that requires solitaire, select one at random and return it
    if not user_idiom:
        random_num = random.randint(1.30880)
        random_idiom = cursor.execute("SELECT id, idiom, paraphrase, first_pinxin from idiom where id={}".format(random_num))
        for idiom in random_idiom:
            return idiom[1], idiom[2]

    player = lazy_pinyin(user_idiom)[-1] [0].upper()  # Get the last pinyin first letter entered by the player
    db_idiom = cursor.execute(
        "SELECT id, idiom, paraphrase, first_pinxin from idiom where first_pinxin='{}'".format(player))
    chioce_idiom = []  # Alternative idiom
    for idiom in db_idiom:
        if lazy_pinyin(user_idiom)[-1] == lazy_pinyin(idiom[1[])0]:
            chioce_idiom.append([idiom[1], idiom[2]])
    if not chioce_idiom:
        return None.None
    return random.choice(chioce_idiom)[0], random.choice(chioce_idiom)[1]
Copy the code

Determine whether the user solitaire is correct

The logic is to query whether the user input is an idiom, and if so, then determine whether it conforms to the solitaire rule. It is simple:

def judge(bot_idiom, user_idiom) :
    if lazy_pinyin(user_idiom)[0] == lazy_pinyin(bot_idiom)[-1] :return True
    return False
Copy the code

So far, idiom solitaire core code, has been completed, in order to interactive friendly, write an interactive function, because the code is too long, here only paste screenshots:

In the interaction function, we add the choice of the first hand or the second hand, and the memory set, which is used to judge whether the idiom is used repeatedly, and we also add the mechanism that can succeed after 10 times.

Here is a screenshot of the run:

It can be seen that the program may not be particularly perfect, single has been very good to achieve the expectation, against a few, because my idiom reserve is not high, all ended in failure, interested students can have a try, see if you can do, ha ha ha.

conclusion

The previous articles were always output in the form of knowledge points, but I found that if I wrote too much, it often became a summary of knowledge points, which was not interesting to me and I could not raise my interest in reading. In the future, TRY to add some interesting things to my articles to improve my writing ability, come on!!

Finally, I would like to thank my girlfriend for her tolerance, understanding and support in work and life.