介绍

本文将展示如何利用Python爬虫来实现诗歌接龙。

该项目的思路如下:利用爬虫爬取诗歌,制作诗歌语料库;

将诗歌分句,形成字典:键(key)为该句首字的拼音,值(value)为该拼音对应的诗句,并将字典保存为pickle文件;

读取pickle文件,编写程序,以exe文件形式运行该程序。

该项目实现的诗歌接龙,规则为下一句的首字与上一句的尾字的拼音(包括声调)一致。下面将分步讲述该项目的实现过程。

诗歌语料库

首先,我们利用Python爬虫来爬取诗歌,制作语料库。爬取的网址为:https://www.gushiwen.org,页面如下:

爬取的诗歌

由于本文主要为试了展示该项目的思路,因此,只爬取了该页面中的唐诗三百首、古诗三百、宋词三百、宋词精选,一共大约1100多首诗歌。为了加速爬虫,采用并发实现爬虫,并保存到poem.txt文件。完整的Python程序如下:import reimport requestsfrom bs4 import BeautifulSoupfrom 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 = {'User-Agent': '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 = {'User-Agent': '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"\([\s\S]*?\)"), '', poem)

poem = re.sub(re.compile(r"([\s\S]*?)"), '', poem)

poem = re.sub(re.compile(r"。\([\s\S]*?)"), '', 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('\n')

该程序爬取了1100多首诗歌,并将诗歌保存至poem.txt文件,形成我们的诗歌语料库。当然,这些诗歌并不能直接使用,需要清理数据,比如有些诗歌标点不规范,有些并不是诗歌,只是诗歌的序等等,这个过程需要人工操作,虽然稍显麻烦,但为了后面的诗歌分句效果,也是值得的。

诗歌分句

有了诗歌语料库,我们需要对诗歌进行分句,分句的标准为:按照结尾为。?!进行分句,这可以用正则表达式实现。之后,将分句好的诗歌写成字典:键(key)为该句首字的拼音,值(value)为该拼音对应的诗句,并将字典保存为pickle文件。完整的Python代码如下:import reimport picklefrom xpinyin import Pinyinfrom collections import defaultdictdef main():

with open('F://poem.txt', 'r') as f:

poems = f.readlines()

sents = []    for poem in poems:

parts = re.findall(r'[\s\S]*?[。?!]', 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()

我们可以看一下该pickle文件(poemDict.pk)的内容:

pickle文件的内容(部分)

当然,一个拼音可以对应多个诗歌。

诗歌接龙

读取pickle文件,编写程序,以exe文件形式运行该程序。

为了能够在编译形成exe文件的时候不出错,我们需要改写xpinyin模块的_init_.py文件,将该文件的全部代码复制至mypinyin.py,并将代码中的下面这句代码data_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),                             'Mandarin.dat')

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

这样我们就完成了mypinyin.py文件。

接下来,我们需要编写诗歌接龙的代码(Poem_Jielong.py),完整代码如下:import picklefrom mypinyin import Pinyinimport randomimport ctypes

STD_INPUT_HANDLE = -10STD_OUTPUT_HANDLE = -11STD_ERROR_HANDLE = -12FOREGROUND_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('\n请输入一句诗或一个字开始:'))            while enter != 'exit':

test = Pinyin().get_pinyin(enter, tone_marks='marks', splitter=' ')

tail = test.split()[-1]                if tail not in poem_dict.keys():

cprint('无法接这句诗。\n', '红色')

MODE = 0

break

else:

cprint('\n机器回复:%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('\n请输入一句诗或一个字开始:')            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('\n(*****最多展示前10回接龙。*****)')

MODE = 0

except Exception as err:

print(err)    finally:        if MODE not in ['1','2']:

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

现在整个项目的结构如下(Mandarin.dat文件从xpinyin模块对应的文件夹下复制过来):

项目文件

切换至该文件夹,输入以下命令即可生成exe文件:pyinstaller -F Poem_jielong.py

生成的exe文件为Poem_jielong.exe,位于该文件夹的dist文件夹下。为了能够让exe成功运行,需要将poemDict.pk和Mandarin.dat文件复制到dist文件夹下。

测试运行

运行Poem_jielong.exe文件,页面如下:

exe文件开始页面

本项目的诗歌接龙有两种模式,一种为人工接龙,就是你先输入一句诗或一个字,然后就是计算机回复一句,你回复一句,负责诗歌接龙的规则;另一种模式为机器接龙,就是你先输入一句诗或一个字,机器会自动输出后面的接龙诗句(最多10个)。

先测试人工接龙模式:

人工接龙

再测试机器接龙模式:

机器接龙

作者:但盼风雨来_jc

链接:https://www.jianshu.com/p/8b08e87bb81b

如何用python编程能实现输入诗句的上句显示下句_Python爬虫之诗歌接龙相关推荐

  1. python作业题目用户输入行数、输出倒的等腰三角形_Python爬虫作业 | Python 程序逻辑训练3题...

    操作环境:Python版本,2.7.13:PyCharm版本,2017.1:电脑:Win 10 1703 1. 打印三角形 分为三角形,倒三角形和等腰三角形 #coding:utf-8 rows = ...

  2. python计算bmi_Python编程语言:如何用Python编程来判断体重指数BMI是否健康

    上一篇小编分享了自己学习Python语言有关字符串和模块time使用的相关知识,这一篇小编分享给大家的是比较有趣的运用,那就是如何用Python编程来表示自己体重BMI. 用Python程序来算出我们 ...

  3. python随机生成100内的10个整数_用python随机生成数字教程_如何用Python编程随机产生10个随机整数,并输出这10个整数的和�9�3...

    如何用Python编程随机产生10个随机整数,并输出这10个整数的和 用Python编程产生10个随机整数,并整数的和,方法如下 准备材料python.电脑 1.需要加载的模块是:random. 2. ...

  4. 《读九章算术学Python》如何用Python编程实现阿拉伯数字转换成汉字数字?

    第6章 数量转换 Python编程基础 字典 字符串操作 if-elif-else语句 递归 前面的输入和输出都是阿拉伯数字,这一章我们来看一下如何实现阿拉伯数字和汉字数字之间的相互转换. 6.1 阿 ...

  5. 《读九章算术学Python》如何用Python编程实现盈不足术?附图解分析、代码实现和习题解答

    卷七 盈不足 以御隐杂互见 主要讲述了以盈亏问题为中心的一种双假设算法. 第20章 盈不足术 Python编程要点 列表操作 嵌套元组的列表 20.1 图解九章 李籍<音义>说:" ...

  6. 如何用Python编程实现算术割圆术?

    第10章 割圆术 Python编程要点 from - import -语句 math模块的sqrt()函数 round()函数 10.1 图解九章 {:–}觚( gū ):正多边形."六觚& ...

  7. 《读九章学Python》如何用Python编程实现图解九章乘分术?

    第5章 乘分术 Python编程基础 元组(Tuples) 列表(list) for 循环语句 嵌套的if-else语句 5.1 图解九章 "乘分"即分数相乘."乘分术& ...

  8. 《读九章学python》如何用Python编程实现少广术?

    卷四 少广 以御积幂方圆 随着人工智能概念的大火,其重要的支持语言Python也一路高歌猛,Python的设计哲学是"优雅.明确.简单". <九章算术>我国现存的最古老 ...

  9. 一周新书榜:西瓜书伴侣、Python编程快速上手第2版上榜

    3月份的程序员专业书很多,好书也多,上榜书更多,真是万物复苏,好书排排站,刚给大家推荐完Linux新书,又迎来周志华教授"西瓜书"<机器学习>公式完全解析指南的< ...

最新文章

  1. 用StatSVN统计SVN服务器项目的代码量
  2. windows扩展C盘空间
  3. 语法:MySQL中INSERT IGNORE INTO和REPLACE INTO的使用
  4. Java 序列化Serializable详解(附详细例子)
  5. hdu 4004 二分查找
  6. vim QuickFix 窗口
  7. Filecoin网络目前总质押量约为3314万枚FIL
  8. 二维数组找鞍点c语言,怎么求一个二维数组的鞍点
  9. Oracle NID工具修改数据库DBID和数据库名称
  10. 创建一个对象和i++是否原子性的理解
  11. 乐高机器人编程和编程的区别
  12. 如何擦除计算机连接网络的记录,如何清除上网记录 清除上网记录方法汇总
  13. python flag=1_python中flag什么意思
  14. 深信服研发、市场等大量岗位社招、校招内推
  15. html中input type什么意思,HTML中type是什么意思
  16. JAVA常用数据结构
  17. 【Python数据挖掘课程】八.关联规则挖掘及Apriori实现购物推荐
  18. 2021届校招求职流程全解析(IT企业和国企)
  19. 正在更新office,请稍后 然后报错 解决办法
  20. mp4视频测试地址url

热门文章

  1. 【妙python】按照元素长度排序列表
  2. 复杂字云简单做,随时做好装逼的准备
  3. 精雕细琢见真章《STM32Cube高效开发教程》
  4. Qt中SQL QSqlQuery 对象中prepare() 函数的用法
  5. iPython清屏命令
  6. 前端必备:五大css自动化生成网站(稀有级别!)
  7. LRUCache算法
  8. Linux platform
  9. 什么是TRIZ理论?
  10. PTA-- 快速排序(25)