20191113 2019-2020-2 《Python程序设计》实验四报告
课程:《Python程序设计》
班级: 1911
姓名: 林紫欣
学号:20191113
实验教师:王志强
实验日期:2020年6月1日
必修/选修: 公选课
1.实验内容
- 利用爬虫爬取世界及中国疫情数据并利用pyecharts实现疫情数据可视化
2.实验设计
简单的三步走战略
- 爬取数据
- 数据处理
- 数据可视化
- 地图
- 柱状图
- 词云图
- 折线图
3. 实验过程及结果
爬取世界疫情数据及其地图可视化
1.爬取数据
- 选择爬取的网页
经过多方的数据比较最终选择了新浪新闻|新型冠状病毒肺炎疫情
- 查看网页源代码
- 寻找所要爬虫的信息
根据所爬取的网页链接观察得出规律,可知所要爬取的最新数据的网址可设置为
new_time = int(time.time() * 1000)
url = 'https://gwpre.sina.cn/ncp/foreign?_={}'.format(new_time)
- 进行数据爬取
new_time = int(time.time() * 1000)
url = 'https://gwpre.sina.cn/ncp/foreign?_={}'.format(new_time)
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36'}
res = requests.get(url,headers=headers)
2.数据的处理
- 类型转换,json-->dict
data = json.loads(res.text)
- 提取所需数据
name = jsonpath.jsonpath(data,'$..name')
confirm = jsonpath.jsonpath(data,'$..value')
- 数据处理与存储
data_zip = zip(name,confirm)
data_list = [[a,b] for a,b in data_zip]
pd_data = pd.DataFrame(columns=['国家','累计确诊人数'],data = data_list)
pd_data.to_csv("Word.csv", encoding='utf-8-sig')
3.可视化地图
- 第一次可视化的时候发现地图上没有数据显示
经检查发现是所爬虫下来的数据国家是中文,而pyecharts的地图库中是英文,没有办法正常匹配。
故而百度获得了世界地图nameMap。
- 第二次可视化的时候有部分数据并没有在地图上显示,并且地图没有层级分别
讲过层层检查发现是百度得到的nameMap和新浪新闻所用的并不是同一个,有部分国家名字有略微不同。
修改过后开始设置地图层级。
- 第三次可视化发现数据除了中国其他国家皆数据翻倍
在代码中进行打印检查
所获数据一一对应,同时没有差错。
利用腾讯新闻网所爬取的数据并不会出现类似问题。但是腾讯新闻网的数据并不全面。
那是为什么呢?目前并未解决。
- 目前可视化代码
LEVEL_CLASSIFICATION = [
{'min': 0, 'max': 0, 'label': '0', 'color': '#FFFFFF'},
{'min': 1, 'max': 99, 'label': '1-99', 'color': '#FECFC6'},
{'min': 100, 'max': 999, 'label': '100-999', 'color': '#FD836B'},
{'min': 1000, 'max': 9999, 'label': '1000-9999', 'color': '#FC4824'},
{'min': 10000, 'max': 99999, 'label': '10000-99999', 'color': '#B62002'},
{'min': 100000, 'max': 999999, 'label': '100000-999999', 'color': '#731401'},
{'min': 1000000, 'max': 99999999, 'label': '1000000人以上', 'color': '#310901'}]
InitOpts = options.InitOpts(width='1200px',height='600px',page_title='世界疫情分布图',bg_color='white')
map = Map(InitOpts)
map.add(series_name='累计确诊人数',data_pair=data_zip,maptype='world',name_map=NAME_MAP,is_map_symbol_show=False)
map.set_series_opts(label_opts=options.LabelOpts(is_show=False)) # 设置系列配置项
map.set_global_opts(title_opts=options.TitleOpts(title='世界疫情分布情况'),
visualmap_opts = options.VisualMapOpts(max_=800, is_piecewise=True, pieces=LEVEL_CLASSIFICATION)) # 设置全局变量
map.render('世界疫情分布情况PLUS.html')
- 附上自己修改的最新世界地图nameMap
世界地图nameMap——配合新浪新闻
4.码云链接
爬取中国疫情数据及其可视化
1.爬取并处理数据
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36',
'Referer': 'https://news.sina.cn/zt_d/yiqing0121'
}
if __name__ == '__main__':
new_time = int(time.time() * 1000)
url = 'https://gwpre.sina.cn/interface/fymap2020_data.json?_={}&callback=dataAPIData'.format(new_time)
get_html(url)
def get_html(url):
html = requests.get(url, headers=headers)
take_json = re.compile('{"data_title":"fymap","data":(.*?)}}') # 用正则表达式取中间
new_json = take_json.findall(html.text)
new_json = json.loads(new_json[0] + '}}')
province_dict = {
'省份名字': [],
'省份英文名字': [],
'目前确诊人数': [],
'累计确诊人数': [],
'治愈人数': [],
'目前死亡人数': [],
'现存无症状人数': [],
'目前怀疑感染人数': [],
'目前境外输入人数': [],
'较昨日增加人数': [],
'连续无感染天数': [],
}
city_dict = {
'城市名字': [],
'目前确诊人数': [],
'累计确诊人数': [],
'目前治愈人数': [],
'目前死亡人数': [],
'现存无症状人数': [],
'目前怀疑感染人数': [],
'目前境外输入人数': [],
'较昨日增加人数': [],
'连续无感染天数': [],
}
for i in new_json['list']:
province_dict['省份名字'].append(i['name']) # 城市名字
province_dict['省份英文名字'].append(i['ename']) # 城市英文名字
province_dict['现存无症状人数'].append(i['asymptomNum']) # 现存无症状人数
province_dict['治愈人数'].append(i['cureNum']) # 治愈人数
province_dict['目前死亡人数'].append(i['deathNum']) # 目前死亡人数
province_dict['目前确诊人数'].append(i['econNum']) # 目前确诊人数
province_dict['累计确诊人数'].append(i['value']) # 累计确诊人数
province_dict['目前怀疑感染人数'].append(i['susNum']) # 目前怀疑感染人数
province_dict['目前境外输入人数'].append(i['jwsrNum']) # 目前境外输入人数
province_dict['较昨日增加人数'].append(i['conadd']) # 较昨日增加人数
province_dict['连续无感染天数'].append(i['zerodays']) # 连续无感染天数
for t in i['city']:
city_dict['城市名字'].append(t['mapName']) # 城市名字
city_dict['累计确诊人数'].append(t['conNum']) # 城市累计确诊人数
city_dict['目前治愈人数'].append(t['cureNum']) # 城市治愈人数
city_dict['目前死亡人数'].append(t['deathNum']) # 城市治愈人数
city_dict['目前确诊人数'].append(t['econNum']) # 目前确诊人数
city_dict['较昨日增加人数'].append(t['conadd']) # 较昨日增加人数
city_dict['连续无感染天数'].append(t['zerodays']) # 城连续无感染天数
city_dict['目前境外输入人数'].append(t['jwsr']) # 目前境外输入人数
city_dict['现存无症状人数'].append(t['asymptomNum']) # 现存无症状人数
city_dict['目前怀疑感染人数'].append(t['susNum']) # 目前怀疑感染人数
province_data = pd.DataFrame(province_dict)
city_data = pd.DataFrame(city_dict)
for i in province_dict: # 迭代数据 如果出现空数据则补0
province_data[i] = province_data[i].apply(lambda x: '0' if x == '' else x)
for i in city_dict: # 迭代数据 如果出现空数据则补0
city_data[i] = city_data[i].apply(lambda x: '0' if x == '' else x)
city_data = city_data[~city_data['城市名字'].isin(['境外', '外来', '0'])] # 取反 筛选掉没用数据
province_id = province_data['省份名字'].values.tolist() # .values.tolist()为转换为列表形式
province_set = province_data['累计确诊人数'].values.tolist()
2.生成文件夹及其相关可视化html
filename = 'Visualization in China'
if not os.path.exists(filename): # 生成文件夹
os.makedirs(filename)
di_tu(province_id, province_set) # 生成地图
zhu_zhuang(province_id, province_set) # 生成柱状图
city_id = city_data['城市名字'].values.tolist()
city_set = city_data['累计确诊人数'].values.tolist()
whole_id = province_id + city_id
whole_data = province_set + city_set
ci_yun(whole_id, whole_data) # 生成词云图
province_set = province_data['治愈人数'].values.tolist()
zhe_xian(province_id, province_set) # 生成折线图
province_data.to_csv("中国疫情省份分析.csv", encoding='utf-8-sig')
city_data.to_csv("中国疫情城市分析.csv", encoding='utf-8-sig')
3.可视化地图
def di_tu(your_id, your_data): # 地图 our_id为名字 your_id为数据
m = Map(opts.InitOpts(width='1260px',height='600px',page_title="中国新型冠状肺炎疫情分布地图"))
m.add("确诊人数", [list(z) for z in zip(your_id, your_data)], "china")
m.set_global_opts(title_opts=opts.TitleOpts(title="中国新型冠状肺炎疫情分布地图"),
visualmap_opts=opts.VisualMapOpts(max_=800))
m.render("./Visualization in China/Map.html")
4.可视化柱状图
def zhu_zhuang(your_id, your_data): # 柱状图 your_id为名字 your_id为数据
bar = Bar(
init_opts=opts.InitOpts(
theme=ThemeType.PURPLE_PASSION,
width="1260px",
height="600px",
page_title="中国新型冠状肺炎疫情情况柱状图"))
bar.add_xaxis(your_id)
bar.add_yaxis('确诊人数', your_data)
bar.set_global_opts(
title_opts=opts.TitleOpts(
title="中国新型冠状肺炎疫情情况柱状图"),
datazoom_opts=[opts.DataZoomOpts()], # ------窗口滑块
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=10))) # 旋转标签
bar.render("./Visualization in China/Histogram.html")
5.可视化词云图
def ci_yun(your_id, your_data): # 词云图 your_id为名字 your_id为数据
new = list(zip(your_id, your_data))
words = new
wordcloud = WordCloud(init_opts=opts.InitOpts(width="1260px", height='600px', page_title="中国新型冠状肺炎疫情情况词云图"))
wordcloud.add('', words, word_size_range=[20, 100])
wordcloud.set_global_opts(title_opts=opts.TitleOpts(title="中国新型冠状肺炎疫情情况词云图"))
wordcloud.render('./Visualization in China/WordCloud.html')
6.可视化渐变折线图
def zhe_xian(your_id, your_data): # 折线图 your_id为名字 your_id为数据
x_data = your_id
y_data = your_data
background_color_js = (
"new echarts.graphic.LinearGradient(0, 0, 0, 1, "
"[{offset: 0, color: '#c86589'}, {offset: 1, color: '#06a7ff'}], false)"
)
area_color_js = (
"new echarts.graphic.LinearGradient(0, 0, 0, 1, "
"[{offset: 0, color: '#eb64fb'}, {offset: 1, color: '#3fbbff0d'}], false)"
)
c = (
Line(init_opts=opts.InitOpts(bg_color=JsCode(background_color_js),width='1260px',height='600px',page_title="中国新型冠状肺炎疫情情况折线图"))
.add_xaxis(xaxis_data=x_data)
.add_yaxis(
series_name="治愈人数总量",
y_axis=y_data,
is_smooth=True,
is_symbol_show=True,
symbol="circle",
symbol_size=6,
linestyle_opts=opts.LineStyleOpts(color="#fff"),
label_opts=opts.LabelOpts(is_show=True, position="top", color="white"),
itemstyle_opts=opts.ItemStyleOpts(
color="red", border_color="#fff", border_width=3
),
tooltip_opts=opts.TooltipOpts(is_show=False),
areastyle_opts=opts.AreaStyleOpts(color=JsCode(area_color_js), opacity=1),
)
.set_global_opts(
title_opts=opts.TitleOpts(
title="目前治愈人数",
pos_bottom="5%",
pos_left="center",
title_textstyle_opts=opts.TextStyleOpts(color="#fff", font_size=16),
),
xaxis_opts=opts.AxisOpts(
type_="category",
boundary_gap=False,
axislabel_opts=opts.LabelOpts(margin=30, color="#ffffff63",interval=0,rotate=30),
axisline_opts=opts.AxisLineOpts(is_show=False),
axistick_opts=opts.AxisTickOpts(
is_show=True,
length=25,
linestyle_opts=opts.LineStyleOpts(color="#ffffff1f"),
),
splitline_opts=opts.SplitLineOpts(
is_show=True, linestyle_opts=opts.LineStyleOpts(color="#ffffff1f")
),
),
yaxis_opts=opts.AxisOpts(
type_="value",
position="right",
axislabel_opts=opts.LabelOpts(margin=20, color="#ffffff63"),
axisline_opts=opts.AxisLineOpts(
linestyle_opts=opts.LineStyleOpts(width=2, color="#fff")
),
axistick_opts=opts.AxisTickOpts(
is_show=True,
length=15,
linestyle_opts=opts.LineStyleOpts(color="#ffffff1f"),
),
splitline_opts=opts.SplitLineOpts(
is_show=True, linestyle_opts=opts.LineStyleOpts(color="#ffffff1f")
),
),
legend_opts=opts.LegendOpts(is_show=False),
)
)
c.render('./Visualization in China/LineChart.html')
7.码云链接
Visualization of COVID-19 in China
4.实验结果展示
插入了优酷视频,完全显示的话可能需要过长的时间。
还可以请点击链接20191113林紫欣综合实践报告成果展示
5.实验分析
- 本次实验结果算是全球战役的一个粗略答卷,是中国疫情战役的一个阶段性总结。全国省市基本控制,6月7日新增确诊仅4例,武汉更是零增长。武汉疫情控制了,中国疫情也就控制了,我们的抗疫歼灭战,已到最后收尾阶段。但于此同时境外输入有5例。中国情况越来越好,世界局势却不容容乐观。
时至今日全球累计确诊6925171人,新增83438人;美国累计总人数1988544人,高达两百万。 - 面对全球疫情,我们需要做好应对的三手准备:
- 一、我们首先要做好自我的防护,巩固我们的抗疫成果
“内防扩散,外防输入”,这是当前我们的政策。内部扩散的防护我们现在做得很好,未来随着武汉疫情的歼灭,国内疫情基本会呈现可控状态,不会再大规模扩散。但是,随着全球范围内的疫情扩散,外部输入疫情的压力必然大幅增加。在这种情况下,外防输入就成了我们的重点。对我们来说,必须采取措施防输入。而且,在如何识别病人和采取措施方面,我们还需要进一步提升能力。 - 二、我们要有计划地去帮助我们的朋友,展开抗疫国际合作
中国的经验和应对疫情的能力,对全球来说就是最宝贵的东西。一方面,作为负责任的大国,我们将我们的经验分享会获得国际上的广泛赞誉,譬如现在世卫组织的专家组对中国的应对措施非常认可,这就使得我们拥有了在应对疫情方面的权威。随着疫情爆发,我们是可以在国际上展开更多合作,为我们的友好国家逐渐提供相应的支持了。譬如,我们支援伊朗就是一个能起到很好作用的示范。接下来,随着我们自身疫情的控制,我们这种能力将会使得我们在世界上获得更大的领导力和影响力,有助于我们对冲国际反华势力对中国的抹黑与攻击。同时,这一系列合作,有助于我们打通更多我们的国际合作关节。 - 三、我们应研究制定全球疫情爆发背景下的系列应对方案
全球疫情爆发,如何在疫情爆发的情况下进行人员、经贸往来对世界来说是个重要课题,在这方面我们应该有更加详尽实用的方案。基于这样的实践,我们甚至可以建立一个疫情防控的国际合作组织,将中国的防控经验通过与世卫组织形成机制,这将有助于提升我国与其他国家的合作水平。 - 这次疫情,如果仅仅在中国爆发,那将成为敌对势力遏制中国的工具;反之,疫情现在全球面临爆发,我们因抗击疫情所做的努力就使得我们获得的更为强大的抗疫能力,此时这种能力就成了我们帮助世界的手段,而帮助世界将提升中国的影响力。现在,国际形势正在由对我们不利向对我们有利转变,亮剑!
5. 实验过程中遇到的问题和解决过程
- 问题1:世界疫情地图除中国外数据翻倍问题。
- 问题1解决方案:未解决,目前锁定为数据调用展示问题。
- 问题2:中国疫情折线图横坐标显示不完全。
- 问题2解决方案:在axislabel_opts中加入interval=0,rotate=30。加入rotate参数并倾斜30°避免横坐标重叠。
- 问题三:颜色不符合心中预期
- 问题解决方案:一开始是使用html颜色代码大全进行对照,后来发现了一个特别棒的网站Fontke,只要选择心仪的颜色然后复制16进制代码就可以了。
发现了一个更好用的HTML色彩提取利器,颜色不是固定的,就像是WPS里面的调色盘一样,可以自己调。
参考资料
全课总结
- 一学期的Python程序设计课程让我感触颇深。自感觉这门课程新鲜有趣到苦恼其难度之大,再到体会学习Python的乐趣。这每一步每一时期现在回忆起来都是积为宝贵的成长经历。
- 《Python程序设计》是实践性很强的课程,其中充满乐趣也极富有挑战性。我们必须亲手去做,才能够体会到该“如何做”,这要比整天在理论中寻找答案更有成就感。
- 通过学习这门课程,我懂得了许多,有如何从掌握问题,从问题出发做出可以解决问题的程序:
- 在程序中面临的问题通常用非形式的语言描述,或者直接来自于实际生活。其表述可能会不准确、不完全,甚至有错误。这就需要我们通过深入分析,把问题严格化。
- 明白了清晰的需求之后,我们需要设计好整个处理过程。
- 设法落实实现中各主要处理工作的算法,必须要考虑算法的性质与情况。
- 实现程序,即为编码,通过试验运行确认程序能完成所需的工作。
- 评价和改进程序。
- 对Python这种语言的特点及其内容也有了一定的了解。
Python是一种高级动态、完全面向对象的语言,函数、模块、数字、字符串都是对象,并且完全支持继承、重载、派生、多继承,有益于增强源代码的复用性。Python是一种计算机程序设计语言(解释型语言),具有代码少、简单、运行速度慢的特点。- 变量赋值及其命名规则
- 运算符及其优先级
- 基本数据类型
- 循环语句
- 列表、元组、字典、集合及其常用功能
- 字符串与正则表达式
- 函数
- 面向对象程序设计
- 文件操作及异常处理
- Python操作数据库
- Python网络编程及爬虫开发(Socket)
- 同时这门课程也让我的自我学习能力有了很大的提升。个人认为,知识海洋浩瀚,“上课”是完全无法解决问题的。学生所需要的正是学习的兴趣与自我探索的能力。这门课程在这两方面有一个比较好的作用。
- 优点有,缺点同样也有。想让学生自由地飞翔茁壮成长,翅膀的构建需要老师的努力,特别是在一些同学一开始并没有浓厚兴趣的时候,就让同学们自主看视频,会使得一些学习积极性不高的同学落下基础。这样上课的时候便全然不懂,面对课后作业与实验只剩下厌烦,这样又如何使学生真正飞翔起来呢?同时所需要看的视频数量实在是太多了,占用时间过多,作为一门选修课略有些过分。
- 个人建议:
- 前期放慢教学速度,或者说是老师提前将自己所做的课件以及总结放给同学,让其课前用较少的时间获取知识,在课堂上进行知识的深入与加工,最好是在课堂上督促同学们动手进行实验。因为本学期是网上授课,有多少同学在听课的时候同时对老师所说进行实践是不清楚的,这无疑需要老师偶尔的提醒与督促,使同学养成良好的学习习惯。
- 我很喜欢老师布置作业的难度与方式。很大程度上促使我努力学习课堂以外的知识,做完作业之后特别有成就感。这一点我希望可以发扬光大。
- 希望老师增设作业、实验验收课,对同学们的作业与实验成果进行一个点评。这样有了反馈之后,同学们才知道自己的一些不足和其他同学的闪光点。课程时间原因定然不能逐一进行点评,可以随机抽人进行。这样也可以提升同学们的认真用心程度。
- 将平时成绩公示化。至少要让每个同学能知道自己的平时成绩,有努力的方向。现在许多成绩并未公示明了。