python编写小程序(手把手教你用20行Python代码制作飞花令小程序)
python编写小程序(手把手教你用20行Python代码制作飞花令小程序)往下翻页后会发现只能获取前 2 页内容,到第 3 页会出现以下提示:我们注意到,返回的结果是一整首诗或词,关键字所在的句子仅为其中一句。后面我们爬取信息时也需要做到过滤。今天,我们就利用 Python 定制一款“飞花令”小程序:给定一个关键字或者关键词,就能够返回许多含有这个关键字的诗句,跟朋友玩再也不怕输了!要利用爬虫完成这项工作需要先选择一个合适的网站,这里我们选择了 古诗文网在右上角的方框中输入关键词,如酒,就能够返回相应的结果:
来源:早起Python
作者:陈熹
飞花令是古时候人们经常玩一种“行酒令”的游戏,是中国古代酒令之一,属雅令。“飞花”一词则出自唐代诗人韩翃《寒食》中 春城无处不飞花 一句。行飞花令时选用诗和词,也可用曲,但选择的句子一般不超过7个字。
在《中国诗词大会》中改良了“飞花令”,不再仅用 花 字,而是增加了 云、 春、月、夜 等诗词中的高频字,轮流背诵含有关键字的诗句,直至决出胜负。
今天,我们就利用 Python 定制一款“飞花令”小程序:给定一个关键字或者关键词,就能够返回许多含有这个关键字的诗句,跟朋友玩再也不怕输了!
网页分析要利用爬虫完成这项工作需要先选择一个合适的网站,这里我们选择了 古诗文网
在右上角的方框中输入关键词,如酒,就能够返回相应的结果:
我们注意到,返回的结果是一整首诗或词,关键字所在的句子仅为其中一句。后面我们爬取信息时也需要做到过滤。
往下翻页后会发现只能获取前 2 页内容,到第 3 页会出现以下提示:
也就是说要完整获取全部诗文需要下载 App,本文简化问题只爬取前 2 页的内容,后续有机会再分享 App 相关爬虫推文。在翻页的过程中我们注意一下 URL 的改变:
“
第 1 页:https://so.gushiwen.cn/search.aspx?value=酒
第 2 页:https://so.gushiwen.cn/search.aspx?type=title&page=2&value=酒
”
其中经过测试 type=title 可以去除,而page=2 显然是页码,那么 page=1 能否获取到第 1 页呢?
答案是可以的,因此不需要用 requests 的 post 请求,直接 get 下面的 URL 就可到达指定页面:https://so.gushiwen.cn/search.aspx?page=页码&value=关键字
大致分析完就可以写代码了
代码实现首先导入库,设置请求头
importrequests
fromlxmlimporthtml
headers={'user-ageNT':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML likeGecko)Chrome/74.0.3729.169Safari/537.36'}
以关键字酒为例,尝试获取第一页全部内容:
importrequests
fromlxmlimporthtml
headers={'user-agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML likeGecko)Chrome/74.0.3729.169Safari/537.36'}
html_data=requests.get('https://so.gushiwen.cn/search.aspx?page=1&value=酒' headers=headers).text
print(html_data)
返回的文本中有我们需要的内容,说明组合而成的请求是没有问题的。接下来就可以解析文本获取具体内容了,本文采用 Xpath:
selector=html.fromstring(html_data)
poets=selector.xpath("/html/body/div[2]/div[1]/div[@class='sons']")
forpoetinpoets:
title=''.join(poet.xpath("div[1]/p[1]/a/b//text()")).strip()
print(title)
诗人和朝代被分隔至两行,说明之间存在换行符及空格,可以用包含.strip()的列表推导式去除:
forpoetinpoets:
title=''.join(poet.xpath("div[1]/p[1]/a/b//text()")).strip()
source=''.join(poet.xpath('div[1]/p[2]//text()'))
source=''.join([i.strip()foriinsource])
print(title source)
最后是对诗句的解析。为了获取关键字真正在的句子,我们要通过句号或者问号将整首诗断开成多个完整句:
forpoetinpoets:
title=''.join(poet.xpath("div[1]/p[1]/a/b//text()")).strip()
source=''.join(poet.xpath('div[1]/p[2]//text()'))
source=''.join([i.strip()foriinsource])
contents=''.join(poet.xpath('div[1]/div[@class="contson"]//text()')).strip().replace('\n' '。').replace('?' '。').split('。')
print(title source contents)
对每一首诗逐渐判断是否包含关键字:
forpoetinpoets:
title=''.join(poet.xpath("div[1]/p[1]/a/b//text()")).strip()
source=''.join(poet.xpath('div[1]/p[2]//text()'))
source=''.join([i.strip()foriinsource])
contents=''.join(poet.xpath('div[1]/div[@class="contson"]//text()')).strip().replace('\n' '。').replace('?' '。').split('。')
content_lst=[]
foriincontents:
if'酒'ini:
content=i.strip() '。'
content_lst.append(content)
#有的诗可能有两句都包含关键字,这两句诗就都是需求
ifnotcontent_lst:#有可能只有题目中含有关键词,这种诗就跳过
continue
forjinlist(set(content_lst)):#有可能有的诗虽然有两句都包含关键字,但这两句是一样的,需要去重
print(j title source)
大部分需求已经满足,最后只需要利用循环结构组装 URL 达到范围多页的目的,同时关键字可以修改为 input 交互输入,代码如下:
importrequests
fromlxmlimporthtml
headers={'user-agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML likeGecko)Chrome/74.0.3729.169Safari/537.36'}
defpoet_content(keyword num url):
html_data=requests.get(url headers=headers).text
selector=html.fromstring(html_data)
poets=selector.xpath("/html/body/div[2]/div[1]/div[@class='sons']")
forpoetinpoets:
title=''.join(poet.xpath("div[1]/p[1]/a/b//text()")).strip()
source=''.join(poet.xpath('div[1]/p[2]//text()'))
source=''.join([i.strip()foriinsource])
contents=''.join(poet.xpath('div[1]/div[@class="contson"]//text()')).strip().replace('\n' '。').replace('?' '。').split('。')
content_lst=[]
foriincontents:
ifkeywordini:
content=i.strip() '。'
content_lst.append(content)
ifnotcontent_lst:
continue
forjinlist(set(content_lst)):
print(num j)
print(f'<{title}>' source)
print('')
num =1
returnnum
if__name__=='__main__':
keyword=input('>请输入关键词:')
print('')
num=1
foriinrange(1 3):
url=f'https://so.gushiwen.org/search.aspx?page={i}&value={keyword}'
num=poet_content(keyword num url)
至此,我们就通过 Python 爬虫就成功制作了一款“飞花令”小工具,感兴趣的读者可以自己尝试一下!