Heim  >  Artikel  >  Backend-Entwicklung  >  Wie man mit Python ein Poesie-Solitärprogramm schreibt

Wie man mit Python ein Poesie-Solitärprogramm schreibt

PHPz
PHPznach vorne
2023-05-13 17:37:061653Durchsuche

Poesiekorpus

   Zuerst verwenden wir den Python-Crawler, um Gedichte zu crawlen und einen Korpus zu erstellen. Die gecrawlten Seiten lauten wie folgt:

Wie man mit Python ein Poesie-Solitärprogramm schreibt

Gecrawlte Gedichte

Da dieser Artikel hauptsächlich dazu dient, die Idee des Projekts zu zeigen, sind daher nur 300 Tang-Gedichte, 300 alte Gedichte und 3 Liedtexte aufgeführt Von dieser Seite wurden 100 ausgewählte Liedtexte gecrawlt, insgesamt mehr als 1.100 Gedichte. Um den Crawler zu beschleunigen, wird der Crawler gleichzeitig implementiert und in der Datei „poem.txt“ gespeichert. Das vollständige Python-Programm lautet wie folgt:

import re
import requests
from bs4 import BeautifulSoup
from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED

# 爬取的诗歌网址
urls = ['https://so.gushiwen.org/gushi/tangshi.aspx',
       'https://so.gushiwen.org/gushi/sanbai.aspx',
       'https://so.gushiwen.org/gushi/songsan.aspx',
       'https://so.gushiwen.org/gushi/songci.aspx'
       ]

poem_links = []
# 诗歌的网址
for url in urls:
   # 请求头部
   headers = {: 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'}
   req = requests.get(url, headers=headers)

   soup = BeautifulSoup(req.text, "lxml")
   content = soup.find_all('div', class_="sons")[0]
   links = content.find_all('a')

   for link in links:
       poem_links.append('https://so.gushiwen.org'+link['href'])

poem_list = []
# 爬取诗歌页面
def get_poem(url):
   #url = 'https://so.gushiwen.org/shiwenv_45c396367f59.aspx'
   # 请求头部
   headers = {: 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'}
   req = requests.get(url, headers=headers)
   soup = BeautifulSoup(req.text, "lxml")
   poem = soup.find('div', class_='contson').text.strip()
   poem = poem.replace(' ', '')
   poem = re.sub(re.compile(r"([sS]*?)"), '', poem)
   poem = re.sub(re.compile(r"([sS]*?)"), '', poem)
   poem = re.sub(re.compile(r"。([sS]*?)"), '', poem)
   poem = poem.replace('!', '!').replace('?', '?')
   poem_list.append(poem)

# 利用并发爬取
executor = ThreadPoolExecutor(max_workers=10)  # 可以自己调整max_workers,即线程的个数
# submit()的参数: 第一个为函数, 之后为该函数的传入参数,允许有多个
future_tasks = [executor.submit(get_poem, url) for url in poem_links]
# 等待所有的线程完成,才进入后续的执行
wait(future_tasks, return_when=ALL_COMPLETED)

# 将爬取的诗句写入txt文件
poems = list(set(poem_list))
poems = sorted(poems, key=lambda x:len(x))
for poem in poems:
   poem = poem.replace('《','').replace('》','') 
              .replace(':', '').replace('“', '')
   print(poem)
   with open('F://poem.txt', 'a') as f:
       f.write(poem)
       f.write('
')

Dieses Programm crawlt mehr als 1100 Gedichte und speichert die Gedichte in der Datei „poem.txt“, um unseren Gedichtkorpus zu bilden. Natürlich können diese Gedichte nicht direkt verwendet werden, und die Daten müssen bereinigt werden. Beispielsweise haben einige Gedichte unregelmäßige Zeichensetzung, andere sind keine Gedichte, sondern nur das Vorwort von Gedichten usw. Dieser Vorgang erfordert jedoch einen manuellen Vorgang ist etwas mühsam, aber für die anschließende Formulierung von Gedichten lohnt sich der Effekt auch.

Gedichtsegmentierung

 Mit dem Gedichtkorpus müssen wir die Gedichte segmentieren. Der Standard für die Segmentierung ist: nach dem Ende. ? ! Bei der Klauselunterbrechung kann dies mithilfe regulärer Ausdrücke erreicht werden. Schreiben Sie anschließend die Gedichte mit guten Sätzen in ein Wörterbuch: Der Schlüssel (Schlüssel) ist das Pinyin des ersten Wortes des Satzes, der Wert (Wert) ist das dem Pinyin entsprechende Gedicht und speichern Sie das Wörterbuch als Pickle-Datei . Der vollständige Python-Code lautet wie folgt:

import re
import pickle
from xpinyin import Pinyin
from collections import defaultdict

def main():
   with open('F://poem.txt', 'r') as f:
       poems = f.readlines()

   sents = []
   for poem in poems:
       parts = re.findall(r'[sS]*?[。?!]', poem.strip())
       for part in parts:
           if len(part) >= 5:
               sents.append(part)

   poem_dict = defaultdict(list)
   for sent in sents:
       print(part)
       head = Pinyin().get_pinyin(sent, tone_marks='marks', splitter=' ').split()[0]
       poem_dict[head].append(sent)

   with open('./poemDict.pk', 'wb') as f:
       pickle.dump(poem_dict, f)

main()

Wir können einen Blick auf den Inhalt der Pickle-Datei (poemDict.pk) werfen:

Wie man mit Python ein Poesie-Solitärprogramm schreibt

Inhalt der Pickle-Datei (Teil)

Natürlich kann ein Pinyin entsprechen mehreren Gedichten.

Poetry Solitaire

  Lesen Sie die Pickle-Datei, schreiben Sie ein Programm und führen Sie das Programm als Exe-Datei aus. Um Fehler beim Kompilieren der exe-Datei zu vermeiden, müssen wir die Datei init.py des xpinyin-Moduls neu schreiben, den gesamten Code der Datei nach mypinyin.py kopieren und den folgenden Code

data_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                            'Mandarin.dat')

im Code neu schreiben Für

data_path = os.path.join(os.getcwd(), 'Mandarin.dat')

ist damit unsere mypinyin.py-Datei vervollständigt. Als nächstes müssen wir den Code für Poetry Solitaire schreiben (Poem_Jielong.py). Der vollständige Code lautet wie folgt:

import pickle
from mypinyin import Pinyin
import random
import ctypes

STD_INPUT_HANDLE = -10
STD_OUTPUT_HANDLE = -11
STD_ERROR_HANDLE = -12

FOREGROUND_DARKWHITE = 0x07  # 暗白色
FOREGROUND_BLUE = 0x09  # 蓝色
FOREGROUND_GREEN = 0x0a  # 绿色
FOREGROUND_SKYBLUE = 0x0b  # 天蓝色
FOREGROUND_RED = 0x0c  # 红色
FOREGROUND_PINK = 0x0d  # 粉红色
FOREGROUND_YELLOW = 0x0e  # 黄色
FOREGROUND_WHITE = 0x0f  # 白色

std_out_handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)

# 设置CMD文字颜色
def set_cmd_text_color(color, handle=std_out_handle):
   Bool = ctypes.windll.kernel32.SetConsoleTextAttribute(handle, color)
   return Bool

# 重置文字颜色为暗白色
def resetColor():
   set_cmd_text_color(FOREGROUND_DARKWHITE)

# 在CMD中以指定颜色输出文字
def cprint(mess, color):
   color_dict = {
                 : FOREGROUND_BLUE,
                 : FOREGROUND_GREEN,
                 : FOREGROUND_SKYBLUE,
                 : FOREGROUND_RED,
                 : FOREGROUND_PINK,
                 : FOREGROUND_YELLOW,
                 : FOREGROUND_WHITE
                }
   set_cmd_text_color(color_dict[color])
   print(mess)
   resetColor()

color_list = ['蓝色','绿色','天蓝色','红色','粉红色','黄色','白色']

# 获取字典
with open('./poemDict.pk', 'rb') as f:
   poem_dict = pickle.load(f)

#for key, value in poem_dict.items():
   #print(key, value)

MODE = str(input('Choose MODE(1 for 人工接龙, 2 for 机器接龙): '))

while True:
   try:
       if MODE == '1':
           enter = str(input('
请输入一句诗或一个字开始:'))
           while enter != 'exit':
               test = Pinyin().get_pinyin(enter, tone_marks='marks', splitter=' ')
               tail = test.split()[-1]
               if tail not in poem_dict.keys():
                   cprint('无法接这句诗。
', '红色')
                   MODE = 0
                   break
               else:
                   cprint('
机器回复:%s'%random.sample(poem_dict[tail], 1)[0], random.sample(color_list, 1)[0])
                   enter = str(input('你的回复:'))[:-1]

           MODE = 0

       if MODE == '2':
           enter = input('
请输入一句诗或一个字开始:')

           for i in range(10):
               test = Pinyin().get_pinyin(enter, tone_marks='marks', splitter=' ')
               tail = test.split()[-1]
               if tail not in poem_dict.keys():
                   cprint('------>无法接下去了啦...', '红色')
                   MODE = 0
                   break
               else:
                   answer = random.sample(poem_dict[tail], 1)[0]
                   cprint('(%d)--> %s' % (i+1, answer), random.sample(color_list, 1)[0])
                   enter = answer[:-1]

           print('
(*****最多展示前10回接龙。*****)')
           MODE = 0

   except Exception as err:
       print(err)
   finally:
       if MODE not in ['1','2']:
           MODE = str(input('
Choose MODE(1 for 人工接龙, 2 for 机器接龙): '))

Die Struktur des gesamten Projekts ist nun wie folgt (die Datei Mandarin.dat wird aus dem entsprechenden Ordner kopiert). das xpinyin-Modul):

Wie man mit Python ein Poesie-Solitärprogramm schreibt

Projektdatei

Wechseln Sie in diesen Ordner und geben Sie den folgenden Befehl ein, um die Exe-Datei zu generieren:

pyinstaller -F Poem_jielong.py

Die generierte Exe-Datei ist Poem_jielong.exe und befindet sich im dist-Ordner dieses Ordners. Damit die Exe-Datei erfolgreich ausgeführt werden kann, müssen die Dateien „poemDict.pk“ und „Mandarin.dat“ in den Ordner „dist“ kopiert werden.

Testlauf

  Führen Sie die Datei Poem_jielong.exe aus. Die Seite sieht wie folgt aus:

Wie man mit Python ein Poesie-Solitärprogramm schreibt

Startseite der Exe-Datei

In diesem Projekt gibt es zwei Modi für Poesie-Solitär, einer ist manueller Solitaire, also Sie Geben Sie zuerst ein Gedicht oder ein Wort ein, und dann antwortet der Computer mit einem Satz, und Sie antworten mit einem Satz, der für die Regeln von Poetry Solitaire verantwortlich ist. Der andere Modus ist Machine Solitaire, das heißt, Sie geben zuerst ein Gedicht ein oder Geben Sie ein Wort ein und das Gerät gibt automatisch die folgenden Solitaire-Verse (bis zu 10) aus. Testen Sie zuerst den manuellen Solitaire-Modus:

Wie man mit Python ein Poesie-Solitärprogramm schreibt

Manueller Solitaire

 Testen Sie dann den maschinellen Solitaire-Modus:

Wie man mit Python ein Poesie-Solitärprogramm schreibt

Das obige ist der detaillierte Inhalt vonWie man mit Python ein Poesie-Solitärprogramm schreibt. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen