最近疫情终于放开,导师立刻成立新的课题组:预测各个城市需要多久才能恢复正常的通勤水平。这就需要各个城市的城内、跨城的OD数据了。我被分配到城际部分的工作,于是开始接触百度迁徙数据。
具体任务目标是收集北上广深的历史迁徙数据,并对其进行预测
1.百度迁徙数据介绍
首先打开百度迁徙数据的官网:https://qianxi.baidu.com
可以看到的页面正下方是一个迁徙趋势,里面的数值叫迁徙指数。
右侧则显示了全国各个热门迁入地还有比例啥的,但是我们的研究范围与尺度是城市,所以我们需要改一下研究的范围,这里我们以深圳市为例。
深圳市迁入指数值得注意的是页面下方的注释,迁徙规模指数是可以城市间横向对比的。这句话十分重要,因为我们以后可以进行城际OD计算。
2.历史迁徙数据来源
在网页上看到的趋势图毕竟只是可视化出来的数据,那我们可不可以获取到其中的数据呢?答案是肯定的。
我们需要点击键盘上的F12,在弹出的DevTools中点击Network选项
点击Network
接下来我们可能会看到一个空白的页面
Network选项下的显示
这时候我们刷新一下页面,就可以看到密密麻麻的东西弹了出来。
我们需要找到这个historycurve的文件,点击。
hisorycurve
可以看到右侧的general中有一个request URL,这其实就是这些数据的来源。我们可以之间将这个url输入到浏览器中,但这个url的参数其实有点杂乱,这里推荐大家可以直接输入这个url:https://huiyan.baidu.com/migration/historycurve.jsonp?dt=city&id=440300&type=move_in
然后你就可以看到一个非常完美的数据:
image.png
为了确保这个数据是否准确,你可以回到百度迁徙的页面,对里面的数据进行核验。
3.数据获取
我们可以看到百度迁徙数据记录了这个城市从2019年1月12日到今天的所有迁徙指数,那我们如何获取这些数据呢?复制黏贴肯定是行不通的,这里我们掏出python来解决:
(需要有request,pandas,json库)
import pandas as pd
import requests
import json
import os
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
def Country_scaler(direction):
#简单的反爬措施
session = requests.Session()
retry = Retry(connect=5, backoff_factor=0.5)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
#保存路径
fp = r'./'
response = session.get(f'https://huiyan.baidu.com/migration/historycurve.jsonp?dt=city&id=440300&type=move_in')
r = response.text[4:-1] # 去头去尾
data_dict = json.loads(r) # 字典化
if data_dict['errmsg'] == 'SUCCESS':
data_list = data_dict['data']['list']
data = data_dict['data']['list']
file = pd.DataFrame({'广州市':data}).T
file.to_csv(fp+f'广州历史迁入指数.csv',encoding='gb18030')
Country_scaler('move_in')
可以看到成功爬取到广州市的数据啦。如果研究其他数据,只需要在url那输入对应的城市编号即可。
广州市是440300,需要对应更改。
下面附上主要城市的ID编号:
CitiesCode = {
'北京市': 110000, '天津市': 120000,
'石家庄市': 130100, '唐山市': 130200, '秦皇岛市': 130300, '邯郸市': 130400, '邢台市': 130500, '保定市': 130600, '张家口市': 130700, '承德市': 130800, '沧州市': 130900, '廊坊市': 131000, '衡水市': 131100,
'太原市': 140100, '大同市': 140200, '阳泉市': 140300, '长治市': 140400, '晋城市': 140500, '朔州市': 140600, '晋中市': 140700, '运城市': 140800, '忻州市': 140900, '临汾市': 141000, '吕梁市': 141100,
'呼和浩特市': 150100, '包头市': 150200, '乌海市': 150300, '赤峰市': 150400, '通辽市': 150500, '鄂尔多斯市': 150600, '呼伦贝尔市': 150700, '巴彦淖尔市': 150800, '乌兰察布市': 150900, '兴安盟': 152200, '锡林郭勒盟': 152500, '阿拉善盟': 152900,
'沈阳市': 210100, '大连市': 210200, '鞍山市': 210300, '抚顺市': 210400, '本溪市': 210500, '丹东市': 210600, '锦州市': 210700, '营口市': 210800, '阜新市': 210900, '辽阳市': 211000, '盘锦市': 211100, '铁岭市': 211200, '朝阳市': 211300, '葫芦岛市': 211400,
'长春市': 220100, '吉林市': 220200, '四平市': 220300, '辽源市': 220400, '通化市': 220500, '白山市': 220600, '松原市': 220700, '白城市': 220800, '延边朝鲜族自治州': 222400,
'哈尔滨市': 230100, '齐齐哈尔市': 230200, '鸡西市': 230300, '鹤岗市': 230400, '双鸭山市': 230500, '大庆市': 230600, '伊春市': 230700, '佳木斯市': 230800, '七台河市': 230900, '牡丹江市': 231000, '黑河市': 231100, '绥化市': 231200, '大兴安岭地区': 232700,
'上海市': 310000,
'南京市': 320100, '无锡市': 320200, '徐州市': 320300, '常州市': 320400, '苏州市': 320500, '南通市': 320600, '连云港市': 320700, '淮安市': 320800, '盐城市': 320900, '扬州市': 321000, '镇江市': 321100, '泰州市': 321200, '宿迁市': 321300,
'杭州市': 330100, '宁波市': 330200, '温州市': 330500, '嘉兴市': 330400, '湖州市': 330500, '绍兴市': 330600, '金华市': 330700, '衢州市': 330800, '舟山市': 330900, '台州市': 331000, '丽水市': 331100,
'合肥市': 340100, '芜湖市': 340200, '蚌埠市': 340300, '淮南市': 340400, '马鞍山市': 340500, '淮北市': 340600, '铜陵市': 340700, '安庆市': 340800, '黄山市': 341000, '滁州市': 341100, '阜阳市': 341200, '宿州市': 341300, '六安市': 341500, '亳州市': 341600, '池州市': 341700, '宣城市': 341800,
'福州市': 350100, '厦门市': 350200, '莆田市': 350300, '三明市': 350400, '泉州市': 350500, '漳州市': 350600, '南平市': 350700, '龙岩市': 350800, '宁德市': 350900,
'南昌市': 360100, '景德镇市': 360200, '萍乡市': 360300, '九江市': 360400, '新余市': 360500, '鹰潭市': 360600, '赣州市': 360700, '吉安市': 360800, '宜春市': 360900, '抚州市': 361000, '上饶市': 361100,
'济南市': 370100, '青岛市': 370200, '淄博市': 370300, '枣庄市': 370400, '东营市': 370500, '烟台市': 370600, '潍坊市': 370700, '济宁市': 370800, '泰安市': 370900, '威海市': 371000, '日照市': 371100, '临沂市': 371300, '德州市': 371400, '聊城市': 371500, '滨州市': 371600, '菏泽市': 371700,
'郑州市': 410100, '开封市': 410200, '洛阳市': 410300, '平顶山市': 410400, '安阳市': 410500, '鹤壁市': 410600, '新乡市': 410700, '焦作市': 410800, '濮阳市': 410900, '许昌市': 411000, '漯河市': 411100, '三门峡市': 411200, '南阳市': 411300, '商丘市': 411400, '信阳市': 411500, '周口市': 411600, '驻马店市': 411700, '济源市': 419001,
'武汉市': 420100, '黄石市': 420200, '十堰市': 420300, '宜昌市': 420500, '襄阳市': 420600, '鄂州市': 420700, '荆门市': 420800, '孝感市': 420900, '荆州市': 421000, '黄冈市': 421100, '咸宁市': 421200, '随州市': 421300, '恩施土家族苗族自治州': 422800, '仙桃市': 429004, '潜江市': 429005, '天门市': 429006, '神农架林区': 429021,
'长沙市': 430100, '株洲市': 430200, '湘潭市': 430300, '衡阳市': 430400, '邵阳市': 430500, '岳阳市': 430600, '常德市': 430700, '张家界市': 430800, '益阳市': 430900, '郴州市': 431000, '永州市': 431100, '怀化市': 431200, '娄底市': 431300, '湘西土家族苗族自治州': 433100,
'广州市': 440100, '韶关市': 440200, '深圳市': 440300, '珠海市': 440400, '汕头市': 440500, '佛山市': 440600, '江门市': 440700, '湛江市': 440800, '茂名市': 440900, '肇庆市': 441200, '惠州市': 441300, '梅州市': 441400, '汕尾市': 441500, '河源市': 441600, '阳江市': 441700, '清远市': 441800, '东莞市': 441900, '中山市': 442000, '潮州市': 445100, '揭阳市': 445200, '云浮市': 445300,
'南宁市': 450100, '柳州市': 450200, '桂林市': 450300, '梧州市': 450400, '北海市': 450500, '防城港市': 450600, '钦州市': 450700, '贵港市': 450800, '玉林市': 450900, '百色市': 451000, '贺州市': 451100, '河池市': 451200, '来宾市': 451300, '崇左市': 451400,
'海口市': 460100, '三亚市': 460200, '三沙市': 460300, '儋州市': 460400, '五指山市': 469001, '琼海市': 469002, '文昌市': 469005, '万宁市': 469006, '东方市': 469007, '定安县': 469021, '屯昌县': 469022, '澄迈县': 469023, '临高县': 469024, '白沙黎族自治县': 469025, '昌江黎族自治县': 469026, '乐东黎族自治县': 469027, '陵水黎族自治县': 469028, '保亭黎族苗族自治县': 469029, '琼中黎族苗族自治县': 469030,
'重庆市': 500000,
'成都市': 510100, '自贡市': 510300, '攀枝花市': 510400, '泸州市': 510500, '德阳市': 510600, '绵阳市': 510700, '广元市': 510800, '遂宁市': 510900, '内江市': 511000, '乐山市': 511100, '南充市': 511300, '眉山市': 511400, '宜宾市': 511500, '广安市': 511600, '达州市': 511700, '雅安市': 511800, '巴中市': 511900, '资阳市': 512000, '阿坝藏族羌族自治州': 513200, '甘孜藏族自治州': 513300, '凉山彝族自治州': 513400,
'贵阳市': 520100, '六盘水市': 520200, '遵义市': 520300, '安顺市': 520400, '毕节市': 520500, '铜仁市': 520600, '黔西南布依族苗族自治州': 522300, '黔东南苗族侗族自治州': 522600, '黔南布依族苗族自治州': 522700,
'昆明市': 530100, '曲靖市': 530300, '玉溪市': 530400, '保山市': 530500, '昭通市': 530600, '丽江市': 530700, '普洱市': 530800, '临沧市': 530900, '楚雄彝族自治州': 532300, '红河哈尼族彝族自治州': 532500, '文山壮族苗族自治州': 532600, '西双版纳傣族自治州': 532800, '大理白族自治州': 532900, '德宏傣族景颇族自治州': 533100, '怒江傈僳族自治州': 533300, '迪庆藏族自治州': 533400,
'拉萨市': 540100, '日喀则市': 540200, '昌都市': 540300, '林芝市': 540400, '山南市': 540500, '那曲市': 540600, '阿里地区': 542500,
'西安市': 610100, '铜川市': 610200, '宝鸡市': 610300, '咸阳市': 610400, '渭南市': 610500, '延安市': 610600, '汉中市': 610700, '榆林市': 610800, '安康市': 610900, '商洛市': 611000,
'兰州市': 620100, '嘉峪关市': 620200, '金昌市': 620300, '白银市': 620400, '天水市': 620500, '武威市': 620600, '张掖市': 620700, '平凉市': 620800, '酒泉市': 620900, '庆阳市': 621000, '定西市': 621100, '陇南市': 621200, '临夏回族自治州': 622900, '甘南藏族自治州': 623000,
'西宁市': 630100, '海东市': 630200, '海北藏族自治州': 632200, '黄南藏族自治州': 632300, '海南藏族自治州': 632500, '果洛藏族自治州': 632600, '玉树藏族自治州': 632700, '海西蒙古族藏族自治州': 632800,
'银川市': 640100, '石嘴山市': 640200, '吴忠市': 640300, '固原市': 640400, '中卫市': 640500,
'乌鲁木齐市': 650100, '克拉玛依市': 650200, '吐鲁番市': 650400, '哈密市': 650500, '昌吉回族自治州': 652300, '博尔塔拉蒙古自治州': 652700, '巴音郭楞蒙古自治州': 652800, '阿克苏地区': 652900, '克孜勒苏柯尔克孜自治州': 653000, '喀什地区': 653100, '和田地区': 653200, '伊犁哈萨克自治州': 654000, '塔城地区': 654200, '阿勒泰地区': 654300,
'石河子市': 659001, '阿拉尔市': 659002, '图木舒克市': 659003, '五家渠市': 659004, '北屯市': 659005, '铁门关市': 659006, '双河市': 659007, '可克达拉市': 659008, '昆玉市': 659009,
'台湾省': 710000, '香港特别行政区': 810000, '澳门特别行政区': 820000
}
想要批量爬取多个城市的同学可以参考这段代码:
import pandas as pd
import requests
import json
import os
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
def Country_scaler(direction,id):
#简单的反爬措施
session = requests.Session()
retry = Retry(connect=5, backoff_factor=0.5)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
#保存路径
fp = r'./'
response = session.get(f'https://huiyan.baidu.com/migration/historycurve.jsonp?dt=city&id={id}&type={direction}')
r = response.text[4:-1] # 去头去尾
data_dict = json.loads(r) # 字典化
if data_dict['errmsg'] == 'SUCCESS':
data_list = data_dict['data']['list']
data = data_dict['data']['list']
file = pd.DataFrame({id:data}).T
file.to_csv(fp+f'{id}历史迁入指数.csv',encoding='gb18030')
cities = [110000,120000,130000]
for i in cities:
Country_scaler('move_in',i)
把想要的城市编号在cities列表中写上就可以了。
可以打开csv文件,看到我们数据爬取成功。
广州市历史迁徙
4.数据可视化
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib as mpl
mpl.rcParams['text.color'] = 'white'
plt.style.use('default')
sns.set(color_codes=True)
sns.set()
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
figure = plt.figure(1,(16,8),dpi = 300)
ax = plt.subplot(111)
f.T.plot(ax = ax)
可以看到迁徙历史数据的变化趋势:
数据变化情况
网友评论