一、目标
利用爬虫收集足够多的古诗词,筛选诗词中含有数字的句子后,再按照圆周率中的数字顺序对这些诗词进行排序。最后形成下图所示的统计结果:

二、步骤及代码

2.1 爬虫获取古诗词

import urllib.request
import urllib.parse
from lxml import etree
import random
import time
"""
爬取古诗词网
"""# 可用的代理地址
proxy_lists = ["163.204.240.213:9999","117.69.200.74:9999","47.112.218.30:8000","121.226.188.148:9999","121.40.108.76:80","223.241.78.159:8010","219.147.157.98:443","117.69.200.167:9999"]def url_open(url):proxy_support = urllib.request.ProxyHandler({"http": random.choice(proxy_lists)})opener_1 = urllib.request.build_opener(proxy_support)headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"}req = urllib.request.Request(url, headers=headers)response = opener_1.open(req)page = response.read()html = etree.HTML(page)return htmldef create_text(url, save_path):current_html = url_open(url)name = current_html.xpath('/html/body//div[@class="son1"]/h1')  # 作品名data_main = current_html.xpath('/html/body//div[@class="son2"]')[1].xpath('string(.)').strip()data_main = data_main.replace(" ", "").replace("\t", "").replace("'", "").replace("\n", "").replace("\r", "")p_dynasty = data_main.find("朝代:")p_author = data_main.find("作者:")dynasty = data_main[p_dynasty+3:p_author]author = data_main[p_author+3:p_author+6].replace("\xa0", "")p_start = data_main.find(author) + len(author)p_end = data_main.find("精彩推荐")with open(save_path, 'a+') as f_obj:f_obj.writelines("{0}\n".format(name[0].text))f_obj.writelines("{0}]\n".format(dynasty))f_obj.writelines("{0}\n".format(author))f_obj.writelines("{0}\n".format(data_main[p_start:p_end].replace("\xa0", "").replace("\ue78e", "")))f_obj.writelines("\n")if __name__ == "__main__":page_start = 1page_end = 77000file_name = 'test.txt'for i in range(page_start, page_end):try:url_1 = "http://www.haoshiwen.org/view.php?id=" + str(i)create_text(url_1, file_name)except Exception as e:print("Error")finally:print("{0}/{1}".format(i, page_end))time.sleep(0.15)

初学爬虫,异常处理和xpath用的很粗糙,见谅!运行程序后,爬取的古诗词保存在test.txt文件中,信息包括诗词名、朝代、作者、正文,板式如下所示:

删除部分元杂剧的部分,最终得到大约70000首古诗,其中少数由于爬取网页的html结构改变,造成了板式的异常,在此先不考虑,之后再剔除。

2.2 统计古诗词中含有数字的情况

import re
from itertools import compress
import pandas as pd
from collections import Counter# 待寻找的汉字
search_char = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"]
file_name = "test.txt"def judge(in_article):r = ':'for i in in_article:if i.find(search_char[0]) != -1:r += '0'if i.find(search_char[1]) != -1:r += '1'if i.find(search_char[2]) != -1:r += '2'if i.find(search_char[3]) != -1:r += '3'if i.find(search_char[4]) != -1:r += '4'if i.find(search_char[5]) != -1:r += '5'if i.find(search_char[6]) != -1:r += '6'if i.find(search_char[7]) != -1:r += '7'if i.find(search_char[8]) != -1:r += '8'if i.find(search_char[9]) != -1:r += '9'return r# 读取文件
with open(file_name) as obj:all = [i for i in obj.readlines()]# 作品名
title = [all[i] for i in range(len(all)) if i % 5 == 0]
# 朝代
dynasty = [all[i] for i in range(len(all)) if i % 5 == 1]
# 作者
author = [all[i] for i in range(len(all)) if i % 5 == 2]
# 正文,去除正文中的英文字符等,并划分成句
article = [re.sub("[A-Za-z0-9\<\\n\>]", "", all[i]).split("。") for i in range(len(all)) if i % 5 == 3]# 结果,含有数字则赋值为0~9,若无则赋值为-1
result = [judge(art) for art in article]
# 判断,是否包含汉字,true代表包含,false代表不包含
judge = [i != ':' for i in result]# 筛选序列中的元素
filter_result = list(compress(result, judge))
filter_title = list(compress(title, judge))
filter_dynasty = list(compress(dynasty, judge))
filter_author = list(compress(author, judge))
filter_article = list(compress(article, judge))# 存储到excel文件
out_xls = {"结果": filter_result,"作品名": filter_title,"朝代": filter_dynasty,"作者": filter_author,"正文": filter_article}
data = pd.DataFrame(out_xls)
data.to_excel("带有数字的古诗v2.xlsx", index=False)# 统计各数字出现的次数
filter_result = [i[1:] for i in filter_result]
str_result = ''.join(filter_result)
word_counts = Counter(str_result[:])
top_10 = word_counts.most_common()
print(top_10)

将统计结果保存到带有数字的古诗v2.xlsx文件中,输出如下:

图中红框内为结果一栏,例如,:555表示诗句中汉字"五"出现的次数为3,:73表示诗句中含有汉字"七"和"三"各一次。
各汉字统计结果如下:
[(‘1’, 25621), (‘3’, 9228), (‘5’, 4770), (‘4’, 4195), (‘2’, 3688), (‘9’, 3575), (‘6’, 2226), (‘8’, 1761), (‘7’, 1383), (‘0’, 1072)]

可以看出,各汉字出现次数按从小到大排序为:零<七<八<六<九<二<四<五<三<一

2.3 统计圆周率中各个数字出现的次数

from collections import Counter
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd# 设置标签为负号可显示,坐标轴可显示中文
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False# 读取存储圆周率位数的文本
file_name = "pi.txt"
with open(file_name) as obj:pi_value = obj.read()num_limit = 10000 # 待统计的圆周率位数限制
# 用collection类中的Counter类统计序列中各元素出现的次数,结果保存到top_10中
word_counts = Counter(pi_value[:num_limit])
top_10 = word_counts.most_common()def draw_tar(turple_list, title="圆周率前{0}位各数出现的次数分布图"):""":param turple_list: 由元组(数字,数字出现的次数)构成的列表:param title: 柱状图的标题:return: """# x为值,y为值对应的次数x = np.array([i[0] for i in turple_list])y = np.array([i[1] for i in turple_list])# 绘图plt.bar(x, y, label="次数")# 设置数据标签for a, b in zip(x, y):plt.text(a, b, b, ha="center", va="bottom", fontsize=10)# 坐标轴、标题设置plt.title(str.format(title, num_limit))plt.xlabel("值")plt.ylabel("次数")plt.legend()plt.show()if __name__ == "__main__":draw_tar(top_10)

结果如下图:

对应代码中top_10的值:
[(‘5’, 1046), (‘1’, 1026), (‘2’, 1021), (‘6’, 1021), (‘9’, 1014), (‘4’, 1012), (‘3’, 975), (‘7’, 969), (‘0’, 968), (‘8’, 948)]

2.4 分析可能性
由于飞花令规则中一首古诗只能出现一次,所以为了生成更长的飞花令需要确定一个优先级问题,例如《小明》含有数字的情况为:20,正文中有两句含有数字的古诗—— ‘月初吉,载离寒暑’ 和 ‘念彼共人,涕如雨’。由于全体诗句集中含有"零"的诗句最少,故将这首诗作为圆周率中的某一位零来使用。用程序解释如下:

def func(in_str):# 按照数字的优先级,修改结果if in_str.find('0') != -1:return '0'elif in_str.find('7') != -1:return '7'elif in_str.find('8') != -1:return '8'elif in_str.find('6') != -1:return '6'elif in_str.find('9') != -1:return '9'elif in_str.find('2') != -1:return '2'elif in_str.find('4') != -1:return '4'elif in_str.find('5') != -1:return '5'elif in_str.find('3') != -1:return '3'elif in_str.find('1') != -1:return '1'

据上文中,圆周率10000位与数据集中各数字的统计结果对比,由于圆周率中8出现的次数最少为948,因此只要满足“数据集中每一个数字出现次数大于948”这一条件就可以初步认为具备实现10000位圆周率飞花令的条件。

2.5 按数字使用优先级修改结果
按优先级对之前得到的带有数字的古诗v2.xlsx进行处理得到带有数字的古诗v3.xlsx,结果如下:

2.6 生成按照圆周率排序的数据集

import pandas as pd# 读取存储圆周率位数的文本
file_name = "pi.txt"
with open(file_name) as obj:pi_value = obj.read()# 确定每一行对应的位置file_3 = r"带有数字的古诗v3.xlsx"pd_1 = pd.read_excel(file_3)pd_2 = pd.DataFrame({'pi': list(pi_value)})temp_1 = [str(i) for i in list(pd_1["分配"].values)]  # 提取表格中"分配"一列作为一个列表temp_2 = ['' for i in range(len(temp_1))]for i, v in enumerate(pi_value):for j, r in enumerate(temp_1):  # 遍历“分配”列if r == v and temp_2[j] == '':temp_2[j] = ibreakxls_3 = pd.read_excel(file_3)xls_3.insert(1, "位置", temp_2)xls_3.to_excel("带有数字的古诗v4.xlsx", index=False)

得到带有数字的古诗v4.xlsx

三、结果展示

视频展示见1~1000位圆周率飞花令

python编程练习:10000位的圆周率飞花令相关推荐

  1. 小白也学得会!Python编程超简单方法算圆周率

    我们都知道,圆周率是3.1415926也就是π,但你有没有想过,圆周率是怎么算出来的呢? 这个是德国数学家莱布尼兹发明的算圆周率的方法,公式为:π=4(1-1/3+1/5+1/7+1/9-1/11-- ...

  2. python数码管倒计时程序_树莓派Python编程用1位数码管显示数字倒计时

    用1位数码管显示数字倒计时 概述 上一篇 我们学习了使用 PWM 来控制 LED 的亮度,这次我们学习使用1位数码管显示个位数字倒计时. 通过本节课,我们能学习到: 1位数码管的显示原理 所需硬件 树 ...

  3. 用Python+小程序实现诗词大会的飞花令 !

    写在前面 在2018年下半年的某一天,偶然观看了<中国诗词大会>节目的飞花令环节.当时作为语音行业一员对此十分感兴趣,想着能不能用程序实现一个,思考技术方案的时候发现最大难度就是数据,遂求 ...

  4. 使用Python+小程序实现诗词大会的飞花令

    前言 在2018年下半年的某一天,偶然观看了<中国诗词大会>节目的飞花令环节.当时作为语音行业一员对此十分感兴趣,想着能不能用程序实现一个,思考技术方案的时候发现最大难度就是数据,遂求助 ...

  5. python查看圆周率π的后10000位

    普通的math模块只能显示π的后15位,就像这样 我们可以使用sympy模块查看π\piπ的后任意位(其实也不是,比如我想看到π\piπ的后十亿位,运行起来就非常吃力了) 关于sympy的安装就直接p ...

  6. python小数点后任意位_Python计算开方、立方、圆周率,精确到小数点后任意位的方法...

    Python计算的位数 在电脑上做了一个实验,看看python能计算到多少位,一下是结果. x = math.sqrt((3)) print ("%.53f"%(x)) print ...

  7. c语言 圆周率10000位,圆周率小数点后第10000位是多少 - 圆周率 - 911查询

    圆周率10000位 1415926535 8979323846 2643383279 5028841971 6939937510 | 圆周率50位 5820974944 5923078164 0628 ...

  8. 圆周率π的前10000位是什么?

    相信你一定很早就学过有关圆周率π的知识,但是你可能对π的准确值只了解到π≈3.1415926,今天小编要给大家带来圆周率π的前10000位的值. 圆周率(小数点后10000位)=3.141592653 ...

  9. 电脑自带python编程软件下载_Python下载_Python for windows 64位正式版下载[编程软件]-下载之家...

          Python for windows 64位正式版是款优秀且面向对象.直译式计算机程序设计语言,Python for windows 64位正式版也是一种功能强大而完善的通用型语言,已经具 ...

最新文章

  1. [Android] 使用Include布局+Fragment滑动切换屏幕
  2. KMS安装后激活机器
  3. vue项目中如何引入ElementUI
  4. python replace替换多个字符_关于python:使用string.replace(x,y)替换所有
  5. kubesphere_KubeSphere容器混合云一个人也能轻松运维的K8s
  6. UWP 使用exe程序
  7. 引用父类成员的关键字是java_[Java] super关键字:引用父类成员
  8. IDC:全球将步入数字经济时代,安全可控成数字经济战略关键词
  9. PPLIVE加速器导致无法正常上网
  10. 锤炼腹肌的好方法:健腹轮的折叠刀式俯卧撑
  11. java百度地图逆地址解析_百度地图逆地址解析
  12. 常用CASE工具介绍 ZZ
  13. 游戏AI行为选择算法一览
  14. 关于OC取名循环渐进的申明
  15. 手握多样算力,从容面对下一代互联网的百样创新
  16. 知了猴的营养成分和作用
  17. Windows移动硬盘修复工具C源代码
  18. Android音乐播放器开发(5)—播放界面(播放、暂停、上一首、下一首,顺序播放、随机播放、拖拽进度条…)
  19. excel创建下拉列表多选_如何在Excel中创建下拉列表?
  20. html表白 知乎,知乎故事 | 暗恋一个人最心酸的事情是什么?

热门文章

  1. lr中的lr_output_message,Lr_debug_message,Lr_error_message,Lrd_stmt,Lrd_fetch函数
  2. 计算机基本配置实验方案,实验4 计算机配置方案.doc
  3. 数据库 之带子查询的操作--插入子查询结果、带子查询的修改语句、带子查询的删除语句
  4. JavaScript (mp3、mp4、jpg、doc、txt、rar)单个、多文件批量下载
  5. 前端批量下载七牛云文件
  6. 小牛采购管理系统 v3.01 bt
  7. 深度解析高通RF360移动射频前端解决方案
  8. Science:工具使用和语言句法在基底神经节共享计算机制和神经表征
  9. 用震盘实现中性笔这一大类笔的笔帽的定向上料设计(SolidWorks模型讲解)
  10. 3节点Fate集群实战记录(全网最详细)--横向联邦学习