Python爬取新冠肺炎实时数据及其可视化分析

Iria ·
更新时间:2024-09-21
· 560 次阅读

点赞、关注再看,养成良好习惯
Life is short, U need Python
初学Python,快来点我吧
在这里插入图片描述

案例:Python爬取新冠肺炎实时数据及其可视化分析

作者:PyQuant
博客:https://blog.csdn.net/qq_33499889
慕课:https://mooc1-2.chaoxing.com/course/207443619.html

本案例适合作为大数据技术基础课程中数据爬取、清洗以及可视化部分的配套教学案例。通过本案例,能够达到以下教学效果:

培养学生爬取网站数据以及数据清洗、加工处理的能力。

案例中通过Python第三方库request获取网站实时数据,并利用pandas清洗数据为可视化数据做准备。

培养学生对真实数据进行可视化分析的能力。

案例中数据来源于网站爬取得到的新冠肺炎实时数据,对新冠肺炎感染者或疑似感染者等数据进行可视化分析。

帮助学生进一步掌握常用图表的绘制方法。

案例中涉及到折线图和柱状图等。

提高学生动手实践能力。

案例中使用Python中的常用可视化工具Matplotlib,提高学生绘制常用图表的实践能力。
1. 利用Python爬取实时数据

网站:https://news.qq.com/zt2020/page/feiyan.htm

原理:通过Requests获取Json请求,从而得到全国各省的疫情数据。

1.1 分析网站

通过浏览器 “审查元素” 查看源代码(右键单击网页地图选择‘审查元素’选项)及 “网络” 反馈的消息,如下图所示:
在这里插入图片描述
在这里插入图片描述

对应的HTTP信息如下所示:

在这里插入图片描述

1.2 发送请求并获取Json数据

通过分析url地址、请求方法、参数及响应格式,可以获取Json数据,注意url需要增加一个时间戳。

import time import json import requests url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5&callback=&_=%d'%int(time.time()*1000) # 抓取腾讯疫情实时json数据 data = json.loads(requests.get(url=url).json()['data']) # 数据太多,打印一个键值对 print(data['lastUpdateTime']) 2020-03-11 16:46:29 2. 数据处理 2.1 认识数据 type(data),len(data) (dict, 12) print(data.keys()) dict_keys(['lastUpdateTime', 'chinaTotal', 'chinaAdd', 'isShowAdd', 'showAddSwitch', 'areaTree', 'chinaDayList', 'chinaDayAddList', 'dailyNewAddHistory', 'dailyHistory', 'wuhanDayList', 'articleList']) # data['areaTree'] # data['areaTree'][0] # 统计省份信息 num = data['areaTree'][0]['children'] # print(num) print(num[0]) # 数据太多,打印部分 {'name': '湖北', 'today': {'confirm': 13, 'confirmCuts': 0, 'isUpdated': True, 'tip': ''}, 'total': {'confirm': 67773, 'suspect': 0, 'dead': 3046, 'deadRate': '4.49', 'showRate': False, 'heal': 49056, 'healRate': '72.38', 'showHeal': True}, 'children': [{'name': '武汉', 'today': {'confirm': 13, 'confirmCuts': 0, 'isUpdated': True}, 'total': {'confirm': 49978, 'suspect': 0, 'dead': 2423, 'deadRate': '4.85', 'showRate': False, 'heal': 33041, 'healRate': '66.11', 'showHeal': True}}, {'name': '孝感', 'today': {'confirm': 0, 'confirmCuts': 0, 'isUpdated': True}, 'total': {'confirm': 3518, 'suspect': 0, 'dead': 126, 'deadRate': '3.58', 'showRate': False, 'heal': 3149, 'healRate': '89.51', 'showHeal': True}}, {'name': '黄冈', 'today': {'confirm': 0, 'confirmCuts': 0, 'isUpdated': True}, 'total': {'confirm': 2907, 'suspect': 0, 'dead': 125, 'deadRate': '4.30', 'showRate': False, 'heal': 2684, 'healRate': '92.33', 'showHeal': True}}, {'name': '荆州', 'today': {'confirm': 0, 'confirmCuts': 0, 'isUpdated': True}, 'total': {'confirm': 1580, 'suspect': 0, 'dead': 49, 'deadRate': '3.10', 'showRate': False, 'heal': 1442, 'healRate': '91.27', 'showHeal': True}}, {'name': '鄂州', 'today': {'confirm': 0, 'confirmCuts': 0, 'isUpdated': True}, 'total': {'confirm': 1394, 'suspect': 0, 'dead': 54, 'deadRate': '3.87', 'showRate': False, 'heal': 1127, 'healRate': '80.85', 'showHeal': True}}, {'name': '随州', 'today': {'confirm': 0, 'confirmCuts': 0, 'isUpdated': True}, 'total': {'confirm': 1307, 'suspect': 0, 'dead': 44, 'deadRate': '3.37', 'showRate': False, 'heal': 1151, 'healRate': '88.06', 'showHeal': True}}, {'name': '襄阳', 'today': {'confirm': 0, 'confirmCuts': 0, 'isUpdated': True}, 'total': {'confirm': 1175, 'suspect': 0, 'dead': 38, 'deadRate': '3.23', 'showRate': False, 'heal': 1094, 'healRate': '93.11', 'showHeal': True}}, {'name': '黄石', 'today': {'confirm': 0, 'confirmCuts': 0, 'isUpdated': True}, 'total': {'confirm': 1015, 'suspect': 0, 'dead': 38, 'deadRate': '3.74', 'showRate': False, 'heal': 917, 'healRate': '90.34', 'showHeal': True}}, {'name': '宜昌', 'today': {'confirm': 0, 'confirmCuts': 0, 'isUpdated': True}, 'total': {'confirm': 931, 'suspect': 0, 'dead': 35, 'deadRate': '3.76', 'showRate': False, 'heal': 800, 'healRate': '85.93', 'showHeal': True}}, {'name': '荆门', 'today': {'confirm': 0, 'confirmCuts': 0, 'isUpdated': True}, 'total': {'confirm': 928, 'suspect': 0, 'dead': 39, 'deadRate': '4.20', 'showRate': False, 'heal': 817, 'healRate': '88.04', 'showHeal': True}}, {'name': '咸宁', 'today': {'confirm': 0, 'confirmCuts': 0, 'isUpdated': True}, 'total': {'confirm': 836, 'suspect': 0, 'dead': 14, 'deadRate': '1.67', 'showRate': False, 'heal': 812, 'healRate': '97.13', 'showHeal': True}}, {'name': '十堰', 'today': {'confirm': 0, 'confirmCuts': 0, 'isUpdated': True}, 'total': {'confirm': 672, 'suspect': 0, 'dead': 8, 'deadRate': '1.19', 'showRate': False, 'heal': 604, 'healRate': '89.88', 'showHeal': True}}, {'name': '仙桃', 'today': {'confirm': 0, 'confirmCuts': 0, 'isUpdated': True}, 'total': {'confirm': 575, 'suspect': 0, 'dead': 22, 'deadRate': '3.83', 'showRate': False, 'heal': 520, 'healRate': '90.43', 'showHeal': True}}, {'name': '天门', 'today': {'confirm': 0, 'confirmCuts': 0, 'isUpdated': True}, 'total': {'confirm': 496, 'suspect': 0, 'dead': 15, 'deadRate': '3.02', 'showRate': False, 'heal': 473, 'healRate': '95.36', 'showHeal': True}}, {'name': '恩施州', 'today': {'confirm': 0, 'confirmCuts': 0, 'isUpdated': True}, 'total': {'confirm': 252, 'suspect': 0, 'dead': 7, 'deadRate': '2.78', 'showRate': False, 'heal': 235, 'healRate': '93.25', 'showHeal': True}}, {'name': '潜江', 'today': {'confirm': 0, 'confirmCuts': 0, 'isUpdated': True}, 'total': {'confirm': 198, 'suspect': 0, 'dead': 9, 'deadRate': '4.55', 'showRate': False, 'heal': 179, 'healRate': '90.40', 'showHeal': True}}, {'name': '神农架', 'today': {'confirm': 0, 'confirmCuts': 0, 'isUpdated': True}, 'total': {'confirm': 11, 'suspect': 0, 'dead': 0, 'deadRate': '0.00', 'showRate': False, 'heal': 11, 'healRate': '100.00', 'showHeal': True}}]} hubei = num[0] # 湖北省 hubei.keys() dict_keys(['name', 'today', 'total', 'children']) hubei['total'] {'confirm': 67773, 'suspect': 0, 'dead': 3046, 'deadRate': '4.49', 'showRate': False, 'heal': 49056, 'healRate': '72.38', 'showHeal': True} henan = num[2] # 河南省 henan.keys() dict_keys(['name', 'today', 'total', 'children']) henan['total'] {'confirm': 1273, 'suspect': 0, 'dead': 22, 'deadRate': '1.73', 'showRate': False, 'heal': 1249, 'healRate': '98.11', 'showHeal': True} 2.2 获取湖北省不同地区疫情确诊总数据 # hubei # 湖北所有数据信息 # hubei['children'] # 湖北不同地区数据 hubei['children'][0]['total'] # 武汉总数据 {'confirm': 49978, 'suspect': 0, 'dead': 2423, 'deadRate': '4.85', 'showRate': False, 'heal': 33041, 'healRate': '66.11', 'showHeal': True}

其数据包括当日数据(today)和累计数据(total),confirm表示确诊、suspect表示疑似、dead表示死亡、heal表示治愈。

# 解析湖北省不同地区确诊的总数据 hubei_children_total_data = {} for item in hubei['children']: if item['name'] not in hubei_children_total_data: hubei_children_total_data.update({item['name']:0}) hubei_children_total_data[item['name']] += int(item['total']['confirm']) print(hubei_children_total_data) {'武汉': 49978, '孝感': 3518, '黄冈': 2907, '荆州': 1580, '鄂州': 1394, '随州': 1307, '襄阳': 1175, '黄石': 1015, '宜昌': 931, '荆门': 928, '咸宁': 836, '十堰': 672, '仙桃': 575, '天门': 496, '恩施州': 252, '潜江': 198, '神农架': 11} 2.3 获取河南省不同地区疫情确诊总数据 # henan # 河南所有数据信息 # henan['children'] # 河南不同地区分数据 henan['children'][1]['total'] # 郑州总数据 {'confirm': 158, 'suspect': 0, 'dead': 5, 'deadRate': '3.16', 'showRate': False, 'heal': 152, 'healRate': '96.20', 'showHeal': True} # 解析河南省不同地区确诊的总数据 henan_children_total_data = {} for item in henan['children']: if item['name'] not in henan_children_total_data: henan_children_total_data.update({item['name']:0}) henan_children_total_data[item['name']] += int(item['total']['confirm']) print(henan_children_total_data) {'信阳': 274, '郑州': 158, '南阳': 156, '驻马店': 139, '商丘': 91, '周口': 76, '平顶山': 58, '新乡': 57, '安阳': 53, '许昌': 39, '漯河': 35, '焦作': 32, '洛阳': 31, '开封': 26, '鹤壁': 19, '濮阳': 17, '三门峡': 7, '济源示范区': 5, '地区待确认': 0} 2.4 获取全国各省疫情确诊总数据 num[0]['total'] # 湖北省总数据 {'confirm': 67773, 'suspect': 0, 'dead': 3046, 'deadRate': '4.49', 'showRate': False, 'heal': 49056, 'healRate': '72.38', 'showHeal': True} # 解析每个省份确诊的总人数 total_data = {} for item in num: if item['name'] not in total_data: total_data.update({item['name']:0}) for city_data in item['children']: total_data[item['name']] += int(city_data['total']['confirm']) print(total_data) {'湖北': 67773, '广东': 1353, '河南': 1273, '浙江': 1215, '湖南': 1018, '安徽': 990, '江西': 935, '山东': 760, '江苏': 631, '重庆': 576, '四川': 539, '黑龙江': 482, '北京': 435, '上海': 344, '河北': 318, '福建': 296, '广西': 252, '陕西': 245, '云南': 174, '海南': 168, '贵州': 146, '天津': 136, '山西': 133, '香港': 126, '甘肃': 125, '辽宁': 125, '吉林': 93, '新疆': 76, '内蒙古': 75, '宁夏': 75, '台湾': 48, '青海': 18, '澳门': 10, '西藏': 1} 3. Matplotlib绘制柱状图 3.1 绘制湖北省不同地区确诊总数据的柱状图 print(hubei_children_total_data) {'武汉': 49978, '孝感': 3518, '黄冈': 2907, '荆州': 1580, '鄂州': 1394, '随州': 1307, '襄阳': 1175, '黄石': 1015, '宜昌': 931, '荆门': 928, '咸宁': 836, '十堰': 672, '仙桃': 575, '天门': 496, '恩施州': 252, '潜江': 198, '神农架': 11} hb_names = hubei_children_total_data.keys() hb_numbers = hubei_children_total_data.values() import matplotlib.pyplot as plt import numpy as np plt.rcParams['font.sans-serif'] = ['simhei'] # 用来正常显示中文标签 # 绘图 plt.figure(figsize=[12,8]) plt.bar(hb_names,hb_numbers) plt.xlabel("地区", size=12) plt.ylabel("人数", fontproperties='SimHei', rotation=90, size=12) plt.title("湖北省不同地区疫情确诊数对比图", size=16) plt.xticks(list(hb_names), rotation=90, size=12) plt.show()

在这里插入图片描述

3.2 绘制河南省不同地区确诊总数据的柱状图 print(henan_children_total_data) {'信阳': 274, '郑州': 158, '南阳': 156, '驻马店': 139, '商丘': 91, '周口': 76, '平顶山': 58, '新乡': 57, '安阳': 53, '许昌': 39, '漯河': 35, '焦作': 32, '洛阳': 31, '开封': 26, '鹤壁': 19, '濮阳': 17, '三门峡': 7, '济源示范区': 5, '地区待确认': 0} hn_names = henan_children_total_data.keys() hn_numbers = henan_children_total_data.values() import matplotlib.pyplot as plt import numpy as np plt.rcParams['font.sans-serif'] = ['simhei'] # 用来正常显示中文标签 # 绘图 plt.figure(figsize=[12,8]) plt.bar(hn_names,hn_numbers) plt.xlabel("地区", size=12) plt.ylabel("人数", fontproperties='SimHei', rotation=90, size=12) plt.title("河南省不同地区疫情确诊数对比图", size=16) plt.xticks(list(hn_names), rotation=90, size=12) plt.show()

在这里插入图片描述

3.3 绘制中国不同省份确诊总数据的柱状图 names = total_data.keys() print(names) dict_keys(['湖北', '广东', '河南', '浙江', '湖南', '安徽', '江西', '山东', '江苏', '重庆', '四川', '黑龙江', '北京', '上海', '河北', '福建', '广西', '陕西', '云南', '海南', '贵州', '天津', '山西', '香港', '甘肃', '辽宁', '吉林', '新疆', '内蒙古', '宁夏', '台湾', '青海', '澳门', '西藏']) numbers = total_data.values() print(numbers) dict_values([67773, 1353, 1273, 1215, 1018, 990, 935, 760, 631, 576, 539, 482, 435, 344, 318, 296, 252, 245, 174, 168, 146, 136, 133, 126, 125, 125, 93, 76, 75, 75, 48, 18, 10, 1]) import matplotlib.pyplot as plt import numpy as np plt.rcParams['font.sans-serif'] = ['simhei'] # 用来正常显示中文标签 # 绘图 plt.figure(figsize=[12,8]) plt.bar(names,numbers) plt.xlabel("地区", size=12) plt.ylabel("人数", fontproperties='SimHei', rotation=90, size=12) plt.title("中国不同省份疫情确诊数对比图", size=16) plt.xticks(list(names), rotation=90, size=12) plt.show()

在这里插入图片描述

补充

同样可以获得其他省份的柱状图(只要做适当调整即可); 同样也可以获得不同数据对应的柱状图(如疑似数据、死亡数据和出院数据等)。 4. 绘制中国疫情趋势图

类似以上方法可以爬取到中国疫情不同日期的历史数据资料(只要把下图中步骤5下面的URL替换掉即可)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BUtcM3Gz-1583918215651)(D:\zgq\Anaconda3\3–网络爬虫–经典案例\22.png)]

from pandas.plotting import register_matplotlib_converters register_matplotlib_converters() import time import json import requests from datetime import datetime url = 'https://view.inews.qq.com/g2/getOnsInfo?name=wuwei_ww_cn_day_counts&callback=&_=%d'%int(time.time()*1000) data = json.loads(requests.get(url=url).json()['data']) data.sort(key=lambda x:x['date']) date_list = list() # 日期 confirm_list = list() # 确诊 suspect_list = list() # 疑似 dead_list = list() # 死亡 heal_list = list() # 治愈 for item in data: month, day = item['date'].split('/') date_list.append(datetime.strptime('2020-%s-%s'%(month, day), '%Y-%m-%d')) confirm_list.append(int(item['confirm'])) suspect_list.append(int(item['suspect'])) dead_list.append(int(item['dead'])) heal_list.append(int(item['heal'])) import matplotlib.pyplot as plt import matplotlib.dates as mdates plt.rcParams['font.sans-serif'] = ['simhei'] # 用来正常显示中文标签 plt.figure(figsize=(12, 8)) plt.title('2019-2020年新冠肺炎疫情曲线图', fontsize=16) plt.plot(date_list, confirm_list, 'r-', label='确诊') plt.plot(date_list, confirm_list, 'rs') plt.plot(date_list, suspect_list, 'b-',label='疑似') plt.plot(date_list, suspect_list, 'b*') plt.plot(date_list, dead_list, 'y-', label='死亡') plt.plot(date_list, dead_list, 'y+') plt.plot(date_list, heal_list, 'g-', label='治愈') plt.plot(date_list, heal_list, 'gd') plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m-%d')) # 格式化时间轴标注 plt.gcf().autofmt_xdate() # 优化标注(自动倾斜) plt.grid(axis='x') # 显示网格 plt.legend() # 显示图例 plt.show()

在这里插入图片描述

5. 小结

以上就是通过Python爬取新冠肺炎数据并进行可视化分析的实战案例,由于时间关系暂时先分析到这里,后续将会对河南省不同时期的新冠肺炎历史数据进行可视化分析(利用PyEcharts包进行动态图分析)!

迫不及待中。。。

补充:

Matplotlib中不同参数可以得到不同的效果,更加美观的绘图方法参见 官网。

Matplotlib官网:https://matplotlib.org/ Seaborn官网:https://seaborn.pydata.org/ Pandas官网:https://pandas.pydata.org/ Plotly官网:https://plot.ly/ 写作不易,切勿白剽 博友们的点赞关注就是对博主坚持写作的最大鼓励 持续更新,未完待续…
作者:PyQuant



肺炎 数据 可视化 可视化分析 Python

需要 登录 后方可回复, 如果你还没有账号请 注册新账号