新型冠状病毒数据抓取及整理详细流程
前言
- 数据源:腾讯新闻肺炎疫情
- 数据爬取工具:requests-html (python 3.5及以上版本)
- 360极速浏览器 (其他浏览器可以类似找到‘开发者工具’)
需要注意的是,数据源之所以选择腾讯新闻,是因为腾讯新闻最容易抓取。你可以直接通过分析URL得到数据网址,并将这些数据存储为json文件。但是同样的过程,你并不能在其他门户新闻网站上进行。因此,腾讯新闻是最容易抓取疫情数据的网站。(或许有爬虫大佬能告诉我怎么在其他网站,比如百度新闻网站上爬取疫情数据,抱拳,感激不尽~)
步骤一:分析URL
首先,打开开发者工具,可以看到这样的画面:
其次,找到指向数据的URL。有两种方式:
1、如下图,我们分别标记aaa, bbb, ccc和ddd。aaa: 点击‘Network’(不同浏览器可能名字不同);bbb:在Search搜索框内输入在页面上看到的数据,比如,全国确诊数’34664’;ccc:搜索框下方会出现URL;双击,点击ddd。
经过上面的操作,可以看到下面图片的内容:
抄录其中的’Request URL’,为
URL=https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5&callback=jQuery34104299452223702189_1581164803507&_=1581164803508
参考大佬们(大佬A,大佬B)的博客,知道
- name=disease_h5 是数据位置
- callback=jQuery34104299452223702189_1581164803507&_=1581164803508返回当前时间戳的一个函数
我们只需要知道数据位置就行,因此,我们得到
URL=https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5
步骤二:数据采集
数据采集部分将主要参考@Hakuna_Matata_001的内容。
第一步:导入第三方库
import time
import json
import pandas as pd
import numpy as np
from datetime import datetime
# 这里requests-html需要python3.5以上版本
from requests_html import HTMLSession
第二步:抓取数据
# 创建会话
session = HTMLSession();
url = r'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5';
# 从目标网址中读取数据
r = session.get(url).json();
# 将数据存储为json格式
data = json.loads(r['data']);
看看data里面都是什么
print(data.keys());
输出结果为
dict_keys(['chinaTotal', 'chinaAdd', 'lastUpdateTime', 'areaTree', 'chinaDayList', 'chinaDayAddList', 'isShowAdd', 'articleList'])
从输出结果可以看出来,data是一个字典,其中键有[‘国内总量’, ‘国内新增’, ‘更新时间’, ‘地区数据’, ‘每日数据’, ‘每日增加数据’, ‘是否显示增加’, ‘文章列表’]。
第三步:数据处理
我们最终想要什么样的数据?
- 国内疫情关于时间的变化序列
- 当天中国地区和世界其他地区的疫情情况
第一类数据储存在‘每日数据’和‘每日增加数据’中,第二类数据储存在‘地区数据’中。
在正式处理数据之前,我们不妨来看看 ‘国内总量’, ‘国内新增’, ‘更新时间’, ‘是否显示增加’和‘文章列表’这些数据分别是什么样子:
# 国内总量
print(data['chinaTotal']);
# 国内新增
print(data['chinaAdd']);
# 更新时间
print(data['lastUpdateTime']);
# 文章列表
print(data['articleList']);
打印出来,是这样的
# 国内总量
{'confirm': 37251, 'suspect': 28942, 'dead': 812, 'heal': 2651};
# 国内新增
{'confirm': 2653, 'suspect': 1285, 'dead': 89, 'heal': 599};
# 更新时间
2020-02-09 10:25:01;
# 文章列表太长,各位大佬可以自行打印~
下面,我们将国内疫情关于时间的变化序列存储成dataframe。
# 每日数据(将'date'列排在第一列)
chinaDayData = pd.DataFrame(data['chinaDayList'])[['date', 'confirm', 'suspect', 'dead', 'heal', 'deadRate', 'healRate']];
print(chinaDayData);
# 每日新增数据(将'date'列排在第一列)
chinaDayAddData = pd.DataFrame(data['chinaDayAddList'])[['date', 'confirm', 'suspect', 'dead', 'heal', 'deadRate', 'healRate']];
print(chinaDayAddData);
输出结果为
# 每日数据date confirm suspect dead heal deadRate healRate
0 01.13 41 0 1 0 2.4 0.0
1 01.14 41 0 1 0 2.4 0.0
2 01.15 41 0 2 5 4.9 12.2
3 01.16 45 0 2 8 4.4 17.8
4 01.17 62 0 2 12 3.2 19.4
5 01.18 198 0 3 17 1.5 8.6
6 01.19 275 0 4 18 1.5 6.5
7 01.20 291 54 6 25 2.1 8.6
8 01.21 440 37 9 25 2.0 5.7
9 01.22 571 393 17 25 3.0 4.4
10 01.23 830 1072 25 34 3.0 4.1
11 01.24 1287 1965 41 38 3.2 3.0
12 01.25 1975 2684 56 49 2.8 2.5
13 01.26 2744 5794 80 51 2.9 1.9
14 01.27 4515 6973 106 60 2.3 1.3
15 01.28 5974 9239 132 103 2.2 1.7
16 01.29 7711 12167 170 124 2.2 1.6
17 01.30 9692 15238 213 171 2.2 1.8
18 01.31 11791 17988 259 243 2.2 2.1
19 02.01 14380 19544 304 328 2.1 2.3
20 02.02 17236 21558 361 475 2.1 2.8
21 02.03 20471 23214 425 632 2.1 3.1
22 02.04 24363 23260 491 892 2.0 3.7
23 02.05 28060 24702 564 1153 2.0 4.1
24 02.06 31211 26359 637 1542 2.0 4.9
25 02.07 34598 27657 723 2052 2.1 5.9
26 02.08 37251 28942 812 2651 2.2 7.1# 每日新增数据date confirm suspect dead heal deadRate healRate
0 01.20 77 27 0 0 0.0 0.0
1 01.21 149 53 3 0 2.0 0.0
2 01.22 131 257 8 0 6.1 0.0
3 01.23 259 680 8 6 3.1 2.3
4 01.24 444 1118 16 3 3.6 0.7
5 01.25 688 1309 15 11 2.2 1.6
6 01.26 769 3806 24 2 3.1 0.3
7 01.27 1771 2077 26 9 1.5 0.5
8 01.28 1459 3248 26 43 1.8 2.9
9 01.29 1737 4148 38 21 2.2 1.2
10 01.30 1982 4812 43 47 2.2 2.4
11 01.31 2102 5019 46 72 2.2 3.4
12 02.01 2590 4562 45 85 1.7 3.3
13 02.02 2829 5173 57 147 2.0 5.2
14 02.03 3235 5072 64 157 2.0 4.9
15 02.04 3893 3971 65 262 1.7 6.7
16 02.05 3697 5328 73 261 2.0 7.1
17 02.06 3143 4833 73 387 2.3 12.3
18 02.07 3401 4214 86 510 2.5 15.0
19 02.08 2657 3916 89 600 3.3 22.6
通过观察,我们发现 每日新增数据 可以通过 每日数据 得到,而且 每日新增数据 记录日期还较少,因此,我们仅用 每日数据 。
我们还需要看看每一列的数据类型,如下:
print(chinaDayData.info());
Data columns (total 7 columns):
date 20 non-null object
confirm 20 non-null int64
suspect 20 non-null int64
dead 20 non-null int64
heal 20 non-null int64
deadRate 20 non-null object
healRate 20 non-null object
dtypes: int64(4), object(3)
memory usage: 1.2+ KB
None
可以看到,不但’data’是object类型,'deadRate’和’healRate’同样也是object类型。为了后面处理方便,我们需要将’deadRate’和’healRate’的数据类型改成float,操作如下:
# 将'deadRate'列的数据类型改成float
chinaDayData.deadRate = chinaDayData.deadRate.map(float);
# 将'healRate'列的数据类型改成float
chinaDayData.healRate = chinaDayData.healRate.map(float);
接下来,我们根据 每日数据 的第一列生成 每日增加数据 列,默认第一天增加数为0。鉴于当天确认数都是凌晨以后,所以当天增加计算公式为 当天增加数=当天确认数-昨天确认数。
# 计算第二天直到最后一天的每天增加数
add = [chinaDayData['confirm'][i]-chinaDayData['confirm'][i-1] for i in range(1, len(chinaDayData['confirm']))];
# 默认第一天增加数为0
add.insert(0, 0);
# 创建新的列add
chinaDayData['add'] = add;
# 打印数据
print(chinaDayData);
date confirm suspect dead heal deadRate healRate add
0 01.13 41 0 1 0 2.4 0.0 0
1 01.14 41 0 1 0 2.4 0.0 0
2 01.15 41 0 2 5 4.9 12.2 0
3 01.16 45 0 2 8 4.4 17.8 4
4 01.17 62 0 2 12 3.2 19.4 17
5 01.18 198 0 3 17 1.5 8.6 136
6 01.19 275 0 4 18 1.5 6.5 77
7 01.20 291 54 6 25 2.1 8.6 16
8 01.21 440 37 9 25 2.0 5.7 149
9 01.22 571 393 17 25 3.0 4.4 131
10 01.23 830 1072 25 34 3.0 4.1 259
11 01.24 1287 1965 41 38 3.2 3.0 457
12 01.25 1975 2684 56 49 2.8 2.5 688
13 01.26 2744 5794 80 51 2.9 1.9 769
14 01.27 4515 6973 106 60 2.3 1.3 1771
15 01.28 5974 9239 132 103 2.2 1.7 1459
16 01.29 7711 12167 170 124 2.2 1.6 1737
17 01.30 9692 15238 213 171 2.2 1.8 1981
18 01.31 11791 17988 259 243 2.2 2.1 2099
19 02.01 14380 19544 304 328 2.1 2.3 2589
20 02.02 17236 21558 361 475 2.1 2.8 2856
21 02.03 20471 23214 425 632 2.1 3.1 3235
22 02.04 24363 23260 491 892 2.0 3.7 3892
23 02.05 28060 24702 564 1153 2.0 4.1 3697
24 02.06 31211 26359 637 1542 2.0 4.9 3151
25 02.07 34598 27657 723 2052 2.1 5.9 3387
26 02.08 37251 28942 812 2651 2.2 7.1 2653
我们接着处理 地区数据(areaData=data[‘areaTree’])。 地区数据是一个字典list,一个国家用一个字典储存。
# 地区数据
areaData=data['areaTree']
print('总共有%d个国家,包括' % len(areaData));
for country in areaData:print(country['name']);
总共有25个国家,包括
中国
日本
新加坡
泰国
韩国
马来西亚
澳大利亚
越南
德国
美国
法国
阿联酋
加拿大
英国
印度
意大利
菲律宾
俄罗斯
芬兰
斯里兰卡
西班牙
瑞典
柬埔寨
尼泊尔
比利时
中国地区作为一个整体,里面包含整个中国的整体数据,以及每个省份及城市的具体数据。我们将直接提取各个省份及城市的信息。
# 地区数据,是一个列表
areaData=data['areaTree'];
# 中国数据,是一个字典,其中,各省份信息储存在'children'里面
chinaData = areaData[0];
# 取出各省份信息,是一个列表
provinces = chinaData['children'];
print('总共有%d个省份,包括' % len(provinces));
for province in provinces:print(province['name']);
总共有34个省份,包括
湖北
广东
浙江
河南
湖南
安徽
江西
江苏
重庆
山东
四川
北京
黑龙江
上海
福建
陕西
河北
广西
云南
海南
山西
辽宁
贵州
天津
甘肃
吉林
内蒙古
宁夏
新疆
香港
青海
台湾
澳门
西藏
以湖北省为例,每一个省份又是一个字典,包含该省每个城市的信息。
Hubei = provinces[0];city = [];
province = [];
total_confirm = [];
total_dead = [];
total_heal = [];
total_deadRate = [];
total_healRate = [];
for c in Hubei['children']:# 城市名称city.append(c['name']);# 确诊总数total_confirm.append(c['total']['confirm']);# 治愈总数total_heal.append(c['total']['heal']);# 死亡总数total_dead.append(c['total']['dead']);# 总体死亡率total_deadRate.append(c['total']['deadRate']);# 总体治愈率total_healRate.append(c['total']['healRate']);Hubei_info = pd.DataFrame({'city': city, 'confirm': total_confirm, 'heal': total_heal, 'dead': total_dead, 'healRate(%)': total_healRate, 'deadRate(%)': total_deadRate});print(Hubei_info);
city confirm heal dead healRate(%) deadRate(%)
0 武汉 14982 877 608 5.85 4.06
1 孝感 2436 45 29 1.85 1.19
2 黄冈 2141 135 43 6.31 2.01
3 荆州 997 40 13 4.01 1.30
4 襄阳 988 40 7 4.05 0.71
5 随州 984 23 9 2.34 0.91
6 黄石 760 54 2 7.11 0.26
7 宜昌 711 36 8 5.06 1.13
8 荆门 663 48 19 7.24 2.87
9 鄂州 639 42 21 6.57 3.29
10 咸宁 493 23 4 4.67 0.81
11 十堰 467 40 0 8.57 0.00
12 仙桃 379 16 5 4.22 1.32
13 天门 197 1 10 0.51 5.08
14 恩施州 171 20 0 11.70 0.00
15 潜江 82 2 2 2.44 2.44
16 神农架 10 2 0 20.00 0.00
17 地区待确认 0 3 0 NaN NaN
通过类似的操作,现在直接将整个中国的数据转化成dataframe进行输出,代码如下:
city = [];
province = [];
total_confirm = [];
total_dead = [];
total_heal = [];
total_deadRate = [];
total_healRate = [];for p in provinces:for c in p['children']:# 省份名称province.append(p['name']);# 城市名称city.append(c['name']);# 确诊总数total_confirm.append(c['total']['confirm']);# 治愈总数total_heal.append(c['total']['heal']);# 死亡总数total_dead.append(c['total']['dead']);# 总体死亡率total_deadRate.append(c['total']['deadRate']);# 总体治愈率total_healRate.append(c['total']['healRate']);china_info = pd.DataFrame({'city': city, 'province': province, 'confirm': total_confirm, 'heal': total_heal, 'dead': total_dead, 'healRate(%)': total_healRate, 'deadRate(%)': total_deadRate});print(china_info);
city province confirm heal dead healRate(%) deadRate(%)
0 武汉 湖北 14982 877 608 5.85 4.06
1 孝感 湖北 2436 45 29 1.85 1.19
2 黄冈 湖北 2141 135 43 6.31 2.01
3 荆州 湖北 997 40 13 4.01 1.30
4 襄阳 湖北 988 40 7 4.05 0.71
.. ... ... ... ... ... ... ...
421 西宁 青海 15 3 0 20.00 0.00
422 海北州 青海 3 0 0 0.00 0.00
423 地区待确认 台湾 18 1 0 5.56 0.00
424 地区待确认 澳门 10 1 0 10.00 0.00
425 地区待确认 西藏 1 0 0 0.00 0.00[426 rows x 7 columns]
检查每列的数据类型
print(china_info.info());
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 426 entries, 0 to 425
Data columns (total 7 columns):
city 426 non-null object
province 426 non-null object
confirm 426 non-null int64
heal 426 non-null int64
dead 426 non-null int64
healRate(%) 417 non-null float64
deadRate(%) 417 non-null float64
dtypes: float64(2), int64(3), object(2)
memory usage: 23.4+ KB
None
最后,将其他国家的数据作为一个整体,用dataframe输出
foreign_country = [];
foreign_confirm = [];
foreign_dead = [];
foreign_heal = [];
foreign_deadRate = [];
foreign_healRate = [];for i in range(1, len(areaData)):# 国名foreign_country.append(areaData[i]['name']);# 确认总数foreign_confirm.append(areaData[i]['total']['confirm']);# 死亡总数foreign_dead.append(areaData[i]['total']['dead']);# 治愈总数foreign_heal.append(areaData[i]['total']['heal']);# 总体死亡率foreign_deadRate.append(areaData[i]['total']['deadRate']);# 总体治愈率foreign_healRate.append(areaData[i]['total']['healRate']);foreigns = pd.DataFrame({'country': foreign_country, 'confirm': foreign_confirm, 'dead': foreign_dead, 'heal': foreign_heal, 'deadRate': foreign_deadRate, 'healRate': foreign_healRate});print(foreigns);
country confirm dead heal deadRate healRate
0 中国 37263 813 2767 2.18 7.43
1 日本 89 0 1 0.00 1.12
2 新加坡 40 0 2 0.00 5.00
3 泰国 32 0 8 0.00 25.00
4 韩国 25 0 3 0.00 12.00
5 马来西亚 17 0 2 0.00 11.76
6 澳大利亚 15 0 5 0.00 33.33
7 越南 14 0 3 0.00 21.43
8 德国 13 0 0 0.00 0.00
9 美国 12 0 1 0.00 8.33
10 法国 11 0 0 0.00 0.00
11 加拿大 7 0 0 0.00 0.00
12 阿联酋 7 0 0 0.00 0.00
13 英国 3 0 0 0.00 0.00
14 菲律宾 3 1 0 33.33 0.00
15 意大利 3 0 0 0.00 0.00
16 印度 3 0 0 0.00 0.00
17 俄罗斯 2 0 0 0.00 0.00
18 芬兰 1 0 1 0.00 100.00
19 斯里兰卡 1 0 1 0.00 100.00
20 西班牙 1 0 0 0.00 0.00
21 瑞典 1 0 0 0.00 0.00
22 柬埔寨 1 0 0 0.00 0.00
23 尼泊尔 1 0 0 0.00 0.00
24 比利时 1 0 0 0.00 0.00
检查每一列的数据类型
print(foreigns.info());
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 25 entries, 0 to 24
Data columns (total 6 columns):
country 25 non-null object
confirm 25 non-null int64
dead 25 non-null int64
heal 25 non-null int64
deadRate 25 non-null float64
healRate 25 non-null float64
dtypes: float64(2), int64(3), object(1)
memory usage: 1.3+ KB
None
至此,我们将所需数据存入三个DataFrame中
- 中国疫情历史数据:chinaDayData
- 中国各省份城市的当天疫情数据:china_info
- 其他发生疫情的国家整体疫情数据:foreigns
步骤三:可视化
抱歉,这里请转到大佬@Hakuna_Matata_001的博文,大佬的博文里用到pyecharts,可以作出地图,非常棒,但是本人目前运行pyecharts遇到问题,暂时无法解决,等后面定补上pyecharts的内容!抱拳!~
新型冠状病毒数据抓取及整理详细流程相关推荐
- RPA机器人数据抓取典型案例全流程详解
数据抓取是实现流程自动化最关键的技能之一,尤其是Web数据抓取,但面对每个具体的业务场景和网站,如何稳定.高效地实现数据抓取? 在实战中进行数据抓取时,需要注意哪些问题? 这篇文章我们就来通过一个企查 ...
- 数据抓取之数据抓取流程
公司的数据抓取系统也写了一阵子了,是时候总结下了,不然凭我的记性,过一段时间就忘的差不多了.打算写一个系列将其中踩过的坑都记录下来.暂时定一个目录,按照这个系列来写: 数据抓取流程,以公示网四川为例子 ...
- python中国大学排名爬虫写明详细步骤-Python爬虫--2019大学排名数据抓取
Python爬虫--2019大学排名数据抓取 准备工作 输入:大学排名URL连接 输出:大学排名信息屏幕输出 所需要用到的库:requests,bs4 思路 获取网页信息 提取网页中的内容并放到数据结 ...
- 怎么获取web开发怎么获取手机的唯一标识_PYTHON实现北京住宅小区数据抓取-(Web服务API-地点检索服务)
最近工作需要整理了一些百度地图接口查询北京住宅小区的相关信息.该篇文章主要从如下3个方面的说明:Web服务API -地点检索服务.需求分析 和 PYTHON实现 . Web服务API -地点检索服务: ...
- 数据抓取工具有哪些-数据抓取工具免费推荐的有哪些
随着社会的进步,科技的发展.不管是企业还是个人都清楚地明白了数据的重要性.不仅可以让我们掌握一手资源,同时还能通过数据更清楚竞争对手.同时也告别了手动复制粘贴的痛苦. 企业人员 通过爬取动态网页数据分 ...
- 查询数据 抓取 网站数据_有了数据,我就学会了如何在几个小时内抓取网站,您也可以...
查询数据 抓取 网站数据 I had a shameful secret. It is one that affects a surprising number of people in the da ...
- python数据抓取之pyquery包
最近由于公司业务上的需求,要网络采集一些数据,并格式化以供应用的调取,前期想到用正则表达式来对网页格式串进行过滤和抓取,在进行了一系列尝试之后放弃, 原因是太繁琐了,而且对于每种网页都需要写特定的表达 ...
- 干货!链家二手房数据抓取及内容解析要点
"本文对链家官网网页进行内容分析,可以作为一般HTTP类应用协议进行协议分析的参考,同时,对链家官网的结构了解后,可以对二手房相关信息进行爬取,并且获取被隐藏的近期成交信息." 另 ...
- 如何用fiddler抓取HTTPS的详细教程(附fiddler安装教学)
对于想抓取HTTPS的测试初学者来说,常用的工具就是fiddler,可是在初学时,大家对于fiddler如何抓取HTTPS真是伤了脑筋,可能你一步步按着网上的帖子成功了,那当然是极好的,有可能没有成功 ...
最新文章
- 洛谷P3122 [USACO15FEB]圈住牛Fencing the Herd(计算几何+CDQ分治)
- hql 语法与详细解释转
- deepin 远程linux,在Deepin Linux操作系统中如何连接Microsoft OneDrive
- CEDD(Color and Edge Directivity Descriptor)学习篇
- 如何去设计硬件与程序之间的通信协议
- Groovy在Spring中的简单使用实例
- vuex modules ajax,VUE项目爬坑---6、vuex的真正存在的意义是什么
- 取消语法检测_中考取消了考纲,学生要如何得高分
- Lucene就是这么简单
- 网络 TCP三次握手及滑动窗口
- 深度神经进化大有可为?Uber详解如何用它优化强化学习 | 5篇论文
- 开启和关闭HBase的thrift进程
- 白领最低生存技能手册
- C# 人民币大小写转换正则表达式
- win8卸载java环境_Win8.1系统如何解压/卸载install.wim文件
- 聊聊 C++ 中的四种类型转换符
- MTK平台 配置GNSS的不同模式
- 【一】ODB - C++ 访问数据库的利器--Hello World On Windows(Version-24)
- 小程序一个简单的订单界面
- Python中文件操作(读、写、关闭)