文章预览
前言
昨天在网上瞎逛的时候,看到了一个概念——
交通生活圈
,经过一番查阅后,约模知道了它的意思:在现有交通状况下,在一定的时间内乘坐现有交通工具你能抵达的范围(ps.通常是指驾车)。
简单来说,就是:“
30分钟内你能走多远?
”
正好某德地图上也有类似的数据,效果如下:
它包含了20分钟、30分钟、45分钟、60分钟、90分钟这5类数据,它范围即对应的交通生活圈。感觉很厉害的鸭子~
于是,我决定自己探索一番…
一、获取数据
1. 交通生活圈数据
打开浏览器的F12调试工具,监听网络请求:
其接口地址为:
https: // report. amap. com/ ajax/ life/ circle. do
有3个参数,对应的说明如下:
参数
说明
districtId
表示区域的ID
dir
0表示出发地,1表示目的地
timeIndex
表示数据的时间
那么,可以定义获取数据的函数:
def get_data ( disID) :
'''
获得交通生活圈数据
'''
url = 'https://report.amap.com/ajax/life/circle.do'
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0' ,
'Accept' : 'application/json, text/javascript, */*; q=0.01' ,
'Accept-Language' : 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2' ,
'X-Requested-With' : 'XMLHttpRequest' ,
'Connection' : 'keep-alive' ,
'TE' : 'Trailers' ,
}
hour = time. strftime( '%H' , time. localtime( time. time( ) ) )
params = (
( 'districtId' , disID) ,
( 'dir' , '0' ) ,
( 'timeIndex' , hour) ,
)
res = requests. get( url, headers= headers, params= params)
data = res. json( )
return data
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
返回的数据为JSON格式,为一个列表,包含5个子列表,每个列表分别表示20分钟、30分钟、45分钟、60分钟、90分钟的数据。
本以为到这里就大功告成了,然而我们发现
districtId
为类似“B0FFFDS1JU”的字符串编码,不便于直接利用,因此需要找到它的来源。
2. 城市区域数据
同样是通过F12抓包分析,可以找到一个请求,它可以返回每个城市对应的区域及相关信息(包括了我们苦苦寻找的
districtId
)。那么,便可以定义相应的函数:
def get_id ( cityID) :
'''
获得城市区域ID
'''
url = 'https://report.amap.com/ajax/life/districts.do'
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0' ,
'Accept' : 'application/json, text/javascript, */*; q=0.01' ,
'Accept-Language' : 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2' ,
'X-Requested-With' : 'XMLHttpRequest' ,
'Connection' : 'keep-alive' ,
'Referer' : 'https://report.amap.com/life.do?city=420100' ,
'TE' : 'Trailers' ,
}
params = (
( 'cityCode' , cityID) ,
)
res = requests. get( url, headers= headers, params= params)
data = res. json( )
return data
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
通过传入城市ID,便可得到其下区域的相关信息:
如出一辙,传入的参数为城市ID,这并不直观,我们无法很快知道每个城市对应的ID是什么。
正所谓:“探索尚未结束,同志仍需努力…”
3. 城市数据
如法炮制,我们找到了获取城市数据的接口,并定义如下函数:
def get_city ( ) :
'''
获取城市信息(城市名、城市ID等)
'''
url = 'https://report.amap.com/ajax/getCityInfo.do'
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0' ,
'Accept' : 'application/json, text/javascript, */*; q=0.01' ,
'Accept-Language' : 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2' ,
'X-Requested-With' : 'XMLHttpRequest' ,
'Connection' : 'keep-alive' ,
}
res = requests. get( url, headers= headers)
data = res. json( )
return data
其结果如是:
4. 完整代码
为了更加方便地获取数据,将以上函数整合在一起,完整的代码如下:
"""
Created on Mon Dec 21 15:14:42 2020
@author: kimol_love
"""
import os
import time
import json
import requests
def get_city ( ) :
'''
获取城市信息(城市名、城市ID等)
'''
url = 'https://report.amap.com/ajax/getCityInfo.do'
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0' ,
'Accept' : 'application/json, text/javascript, */*; q=0.01' ,
'Accept-Language' : 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2' ,
'X-Requested-With' : 'XMLHttpRequest' ,
'Connection' : 'keep-alive' ,
}
res = requests. get( url, headers= headers)
data = res. json( )
return data
def get_id ( cityID) :
'''
获得城市区域ID
'''
url = 'https://report.amap.com/ajax/life/districts.do'
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0' ,
'Accept' : 'application/json, text/javascript, */*; q=0.01' ,
'Accept-Language' : 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2' ,
'X-Requested-With' : 'XMLHttpRequest' ,
'Connection' : 'keep-alive' ,
'Referer' : 'https://report.amap.com/life.do?city=420100' ,
'TE' : 'Trailers' ,
}
params = (
( 'cityCode' , cityID) ,
)
res = requests. get( url, headers= headers, params= params)
data = res. json( )
return data
def get_data ( disID) :
'''
获得交通生活圈数据
'''
url = 'https://report.amap.com/ajax/life/circle.do'
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0' ,
'Accept' : 'application/json, text/javascript, */*; q=0.01' ,
'Accept-Language' : 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2' ,
'X-Requested-With' : 'XMLHttpRequest' ,
'Connection' : 'keep-alive' ,
'TE' : 'Trailers' ,
}
hour = time. strftime( '%H' , time. localtime( time. time( ) ) )
params = (
( 'districtId' , disID) ,
( 'dir' , '0' ) ,
( 'timeIndex' , hour) ,
)
res = requests. get( url, headers= headers, params= params)
data = res. json( )
return data
if __name__ == '__main__' :
cityInfo = get_city( )
while True :
cityName = input ( '请输入城市:' )
flag = 0
for city in cityInfo:
if cityName == city[ 'name' ] :
cityID = city[ 'code' ]
disIDs = get_id( cityID)
if len ( disIDs) == 0 :
flag = 1
else :
flag = 2
break
if flag == 0 :
print ( '未找到相关城市!' )
elif flag == 1 :
print ( '该城市无数据!:' )
elif flag == 2 :
break
print ( '-' * 20 )
print ( ( '0==>所有' ) . ljust( 10 ) )
for i in range ( len ( disIDs) ) :
print ( ( '%d==>%s' % ( i+ 1 , disIDs[ i] [ 'name' ] ) ) . ljust( 10 ) )
print ( '-' * 20 )
while True :
index = int ( input ( '请选择:' ) )
if index not in range ( len ( disIDs) + 1 ) :
print ( '输入错误!:' )
else :
break
if not os. path. exists( './data' ) :
os. mkdir( './data' )
if index == 0 :
if not os. path. exists( './data/%s' % cityName) :
os. mkdir( './data/%s' % cityName)
for i in range ( len ( disIDs) ) :
disID = disIDs[ i] [ 'id' ]
data = get_data( disID)
data. append( disIDs[ i] [ 'center' ] )
data = json. dumps( data)
with open ( './data/%s/%s.json' % ( cityName, disIDs[ i] [ 'name' ] ) , 'w' ) as f:
f. write( data)
print ( '"%s"获取成功!' % disIDs[ i] [ 'name' ] )
else :
disID = disIDs[ index- 1 ] [ 'id' ]
data = get_data( disID)
data. append( disIDs[ index- 1 ] [ 'center' ] )
data = json. dumps( data)
with open ( './data/%s.json' % disIDs[ i] [ 'name' ] , 'w' ) as f:
f. write( data)
print ( '"%s"获取成功!' % disIDs[ i] [ 'name' ] )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
注:
为了便于后续地分析,我们将数据append了一个列表(区域的中心位置),因此data一共包含6个列表:5类数据+中心点位置。
俗话说得好,好用不好用,拉出来run一run:
电闪雷鸣之间,只见所有的数据默默地躺入了我温暖的怀抱~
至此,数据获取的探索便可暂告于段落。
二、30分钟交通生活圈
1. 数据分析
有了数据,通过分析我们便可知道30分钟自己能“走”多远了。这里我们用到了Python中的
folium库
,它是一个交互式地图库,允许我们调用地图接口进行可视化分析。其安装方法如下:
pip install folium
首先,定义读取数据的函数:
def read_data ( path, Type= 30 ) :
'''
读取交通生活圈数据(有20分钟、30分钟、45分钟、60分钟、90分钟)
'''
typeMap = { 20 : 0 ,
30 : 1 ,
45 : 2 ,
60 : 3 ,
90 : 4 }
with open ( path, 'r' ) as f:
data = f. read( )
data = json. loads( data)
center = data[ - 1 ]
data = data[ typeMap[ Type] ]
return ( center, data)
读取数据(以成都的牛王庙为例):
center, data = read_data( './data/成都/牛王庙.json' )
data. append( data[ 0 ] )
for i in range ( len ( data) ) :
data[ i] = [ data[ i] [ 1 ] , data[ i] [ 0 ] ]
data.append(data[0])是为了使数据形成一个闭环,这样方便在地图上表示出来。
定义地图,并设定相关参数:
Map= folium. Map( location= [ center[ 1 ] , center[ 0 ] ] ,
zoom_start= 11 ,
tiles= 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}' ,
attr= 'default'
)
在地图上标出起始点:
folium. Marker( [ center[ 1 ] , center[ 0 ] ] ,
popup= folium. Popup( '牛王庙' , max_width= 1000 ) ,
tooltip= '出发点'
) . add_to( Map)
在地图上画出30分钟交通生活的区域:
folium. Polygon( data,
color= '#7C9F59' ,
fill= True ) . add_to( Map)
将地图保存到本地:
Map. save( '30分钟交通生活圈.html' )
打开HTML之后,效果如下:
绿色区域
意味着,在当前的交通情况下,我从牛王庙出发,我可以到达的范围,即30分钟我能“走”多远~
2. 完整代码
这一部分的完整代码如下:
"""
Created on Mon Dec 21 18:58:34 2020
@author: kimol_love
"""
import json
import folium
def read_data ( path, Type= 30 ) :
'''
读取交通生活圈数据(有20分钟、30分钟、45分钟、60分钟、90分钟)
'''
typeMap = { 20 : 0 ,
30 : 1 ,
45 : 2 ,
60 : 3 ,
90 : 4 }
with open ( path, 'r' ) as f:
data = f. read( )
data = json. loads( data)
center = data[ - 1 ]
data = data[ typeMap[ Type] ]
return ( center, data)
if __name__ == '__main__' :
center, data = read_data( './data/成都/牛王庙.json' )
data. append( data[ 0 ] )
for i in range ( len ( data) ) :
data[ i] = [ data[ i] [ 1 ] , data[ i] [ 0 ] ]
Map= folium. Map( location= [ center[ 1 ] , center[ 0 ] ] ,
zoom_start= 11 ,
tiles= 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}' ,
attr= 'default'
)
folium. Marker( [ center[ 1 ] , center[ 0 ] ] ,
popup= folium. Popup( '牛王庙' , max_width= 1000 ) ,
tooltip= '出发点'
) . add_to( Map)
folium. Polygon( data,
color= '#7C9F59' ,
fill= True ) . add_to( Map)
Map. save( '30分钟交通生活圈.html' )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
写在最后
至此,我们大致知道了30分钟自己能“走”多远了~
这里主要是从交通通行情况的角度出发,如果非得说坐飞机、坐火箭、坐大炮啥的。别问我,问了我也不知道(手动捂脸)~
其实,这个数据还可以尝试从更多地角度分析,比如可以计算出30分钟最大抵达半径,并进一步比较不同城市的大小等等。如果有感兴趣的小伙伴,可以试试哦。
我是kimol君,咋们下次再会~
创作不易,大侠请留步… 动起可爱的双手,来个赞再走呗 (๑◕ܫ←๑)
………………………………