在上次博客中写道 我们已经明确了数据分析的方向——距离和人口流动对疫情传播的影响。
第二步就是从网上爬取能帮助我们完成数据分析的数据。
我们主要分析国内的两次大规模爆发的疫情1:WH疫情 2:SH疫情 我们用两次爆发的中心城市做为中心源研究距离和人口流动对疫情传播的影响。
数据获取和处理
一:距离数据
针对两地之间距离的数据有很多种,比如两点之间的直线距离,两点之间的汽车,火车,飞机等等的距离数据都是不同的,针对不同的数据有不同的爬取方法。如果要爬取火车,汽车,飞机的数据需要在高德地图上进行api的申请,而我认为两点之间的数据以两点的直线距离为最好。
所以如何获得两点之间的直线距离就是我们要决解的第一个问题。我想到如下两个方案,
1:直接爬取两点的直线距离数据。
http://www.china6636.com/from/04-27071629-04
这个方案是可行的,但我在网址上只找到一个网址,这个网址()要进行三次跳转和搜索才能找到相关数据,爬虫做起来太麻烦(时间成本问题)。所以我采用了第二种方法。
2:通过爬取经纬度和函数计算出两点之间的距离
中国各主要大城市经纬度数据
爬取两点之间的经纬度要比爬距离简单很多,通过这个网址直接就能爬取到,中国城市的经纬度。
(爬取结果如上图)
然后使用计算地球上两点的距离,使用haversine公式就可以计算出两点的距离。
# 将十进制度数转化为弧度
lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
# haversine公式
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * asin(sqrt(a))
r = 6371 # 地球平均半径,单位为公里
return c * r * 1000
二:人口流量数据:
人口流量数据我在网上并没有找到(很有可能是现在很重视隐私),这点阻碍了我很久,最终我在网上看到了大佬留言,可以使用百度迁徙数据。
百度迁徙数据记录了每天中国各地人口迁入和迁出的比例,而且去向也包含在内,所以百度迁徙的数据是我们理想数据,只要爬到了人口迁出的比例,再用比例乘以总的人口迁徙量就可以取得我们所需要的人口流量的数据了。
爬取过程:
我们首先打开网页的检查,找到相应的json文件 观察url格式 。https://huiyan.baidu.com/migration/cityrank.jsonp?dt=province&id=420000&type=move_in&date=20220414
以此为例 dt=province 代表省 city代表城市 id=****代表要查的省名 type=(move_in 代表迁入)(move_out 代表迁出) data= (后面跟上日期)
id = 经实验 得出('北京': '110000', '上海': '310000', '广州': '440100', '深圳': '440300', '杭州': '330100', '南京': '320100', '天津': '120000', '成都': '510100', '武汉': '420100', '苏州': '320500')
所以我们爬虫的准备工作就完成了,接下来就可以直接代码实现了。
url = 'http://huiyan.baidu.com/migration/cityrank.jsonp?dt=country&id=420100&type=move_out&&date={}'.format(
date)
re = requests.get(url, timeout=10)
url 编写, 因为我们需要爬取的是 (武汉,上海)两点的迁出人口流量,所以分两次爬取。
id = 420100(武汉) id= 31000(上海) type= move_out data 需要我们循环来输入
for i in range(20220301, 20220332):
date_list.append(str(i))
header.append(str(i))
上海 我选择爬取 从 2022 年3月1号,到3月31号的所有数据。
for i in range(20200110, 20200123):
date_list.append(str(i))
header.append(str(i))
武汉我选择爬取的是 从 2020年1月11号 到 1月22号(武汉封城日)的所有数据。
r = r[1:]
data_dict = json.loads(r) # 字典化
将 爬取的数据去掉无用信息(不去掉字典化会失败),再字典化。
for i in range(len(data_list)):
a.append(data_list[i]['city_name']) #城市名
a.append(data_list[i]['province_name']) #省份名
a.append(data_list[i]['value'])
将 数据按照日期 城市名,省份名,值 的格式保存在list中
with open("E:\机器学习\疫情分析\WH.csv.xls", "w+", newline="") as csv_file:
writer = csv.writer(csv_file)
header = ["市", "省", "流量率"]
writer.writerow(header)
对数据进行爬虫和读写处理:
data_dict = json.loads(r) # 字典化
if data_dict['errmsg'] == 'SUCCESS':
data_list = data_dict['data']['list']
a = []
a.append(date)
for i in range(len(data_list)):
a.append(data_list[i]['city_name'])
a.append(data_list[i]['province_name'])
a.append(data_list[i]['value'])
cun.append(a)
with open("E:\机器学习\疫情分析\WH.csv.xls", "w+", newline="") as csv_file:
writer = csv.writer(csv_file)
header = ["市", "省", "流量率"]
# 写入表头
writer.writerow(header)
# 按照时间进行拷贝
for i in range(len(cun)):
writer.writerow([cun[i][0]])
for j in range(0, int(len(cun[i])/3)):
city_name = cun[i][j*3+1]
province_name = cun[i][j*3+2]
value = cun[i][j*3+3]
writer.writerow([city_name, province_name, value])
将爬取的数据保存在csv表格中。
(上海数据)
(武汉数据)
现在我们就已经完成对所需的数据的爬取,接下来就要进行数据的处理以及数据的机器学习的分析 ,已到达我们所要的距离和人口流动对疫情传播的影响。