想知道自己30分钟能“走”多远嘛?
想知道自己30分鐘能“走”多遠(yuǎn)嘛?
- 前言
- 一、獲取數(shù)據(jù)
- 1. 交通生活圈數(shù)據(jù)
- 2. 城市區(qū)域數(shù)據(jù)
- 3. 城市數(shù)據(jù)
- 4. 完整代碼
- 二、30分鐘交通生活圈
- 1. 數(shù)據(jù)分析
- 2. 完整代碼
- 寫在最后
前言
昨天在網(wǎng)上瞎逛的時(shí)候,看到了一個(gè)概念——交通生活圈,經(jīng)過(guò)一番查閱后,約模知道了它的意思:在現(xiàn)有交通狀況下,在一定的時(shí)間內(nèi)乘坐現(xiàn)有交通工具你能抵達(dá)的范圍(ps.通常是指駕車)。
簡(jiǎn)單來(lái)說(shuō),就是:“30分鐘內(nèi)你能走多遠(yuǎn)?”
正好某德地圖上也有類似的數(shù)據(jù),效果如下:
它包含了20分鐘、30分鐘、45分鐘、60分鐘、90分鐘這5類數(shù)據(jù),它范圍即對(duì)應(yīng)的交通生活圈。感覺很厲害的鴨子~
于是,我決定自己探索一番…
一、獲取數(shù)據(jù)
1. 交通生活圈數(shù)據(jù)
打開瀏覽器的F12調(diào)試工具,監(jiān)聽網(wǎng)絡(luò)請(qǐng)求:
其接口地址為:
有3個(gè)參數(shù),對(duì)應(yīng)的說(shuō)明如下:
| districtId | 表示區(qū)域的ID |
| dir | 0表示出發(fā)地,1表示目的地 |
| timeIndex | 表示數(shù)據(jù)的時(shí)間 |
那么,可以定義獲取數(shù)據(jù)的函數(shù):
def get_data(disID):'''獲得交通生活圈數(shù)據(jù)'''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())) # 當(dāng)前小時(shí)params = (('districtId', disID),('dir', '0'),('timeIndex', hour),)res = requests.get(url, headers=headers, params=params)data = res.json()return data返回的數(shù)據(jù)為JSON格式,為一個(gè)列表,包含5個(gè)子列表,每個(gè)列表分別表示20分鐘、30分鐘、45分鐘、60分鐘、90分鐘的數(shù)據(jù)。
本以為到這里就大功告成了,然而我們發(fā)現(xiàn)districtId為類似“B0FFFDS1JU”的字符串編碼,不便于直接利用,因此需要找到它的來(lái)源。
2. 城市區(qū)域數(shù)據(jù)
同樣是通過(guò)F12抓包分析,可以找到一個(gè)請(qǐng)求,它可以返回每個(gè)城市對(duì)應(yīng)的區(qū)域及相關(guān)信息(包括了我們苦苦尋找的districtId)。那么,便可以定義相應(yīng)的函數(shù):
def get_id(cityID):'''獲得城市區(qū)域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通過(guò)傳入城市ID,便可得到其下區(qū)域的相關(guān)信息:
如出一轍,傳入的參數(shù)為城市ID,這并不直觀,我們無(wú)法很快知道每個(gè)城市對(duì)應(yīng)的ID是什么。
正所謂:“探索尚未結(jié)束,同志仍需努力…”
3. 城市數(shù)據(jù)
如法炮制,我們找到了獲取城市數(shù)據(jù)的接口,并定義如下函數(shù):
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其結(jié)果如是:
4. 完整代碼
為了更加方便地獲取數(shù)據(jù),將以上函數(shù)整合在一起,完整的代碼如下:
# -*- coding: utf-8 -*- """ Created on Mon Dec 21 15:14:42 2020@author: kimol_love """ import os import time import json import requestsdef 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 datadef get_id(cityID):'''獲得城市區(qū)域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 datadef get_data(disID):'''獲得交通生活圈數(shù)據(jù)'''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())) # 當(dāng)前小時(shí)params = (('districtId', disID),('dir', '0'),('timeIndex', hour),)res = requests.get(url, headers=headers, params=params)data = res.json()return dataif __name__ == '__main__':# 獲取城市信息cityInfo = get_city()# 輸入城市及片區(qū)while True:cityName = input('請(qǐng)輸入城市:')flag = 0for city in cityInfo:if cityName == city['name']:cityID = city['code']disIDs = get_id(cityID)if len(disIDs) == 0:flag = 1else:flag = 2breakif flag == 0: # 如果沒有該城市print('未找到相關(guān)城市!')elif flag == 1: # 如果該城市沒有數(shù)據(jù)print('該城市無(wú)數(shù)據(jù)!:')elif flag == 2: breakprint('-'*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('請(qǐng)選擇:'))if index not in range(len(disIDs)+1):print('輸入錯(cuò)誤!:')else:break# 下載數(shù)據(jù)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']) # 加入中心點(diǎn)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']) # 加入中心點(diǎn)data = json.dumps(data)with open('./data/%s.json'%disIDs[i]['name'], 'w') as f:f.write(data)print('"%s"獲取成功!'%disIDs[i]['name'])注:為了便于后續(xù)地分析,我們將數(shù)據(jù)append了一個(gè)列表(區(qū)域的中心位置),因此data一共包含6個(gè)列表:5類數(shù)據(jù)+中心點(diǎn)位置。
俗話說(shuō)得好,好用不好用,拉出來(lái)run一run:
電閃雷鳴之間,只見所有的數(shù)據(jù)默默地躺入了我溫暖的懷抱~
至此,數(shù)據(jù)獲取的探索便可暫告于段落。
二、30分鐘交通生活圈
1. 數(shù)據(jù)分析
有了數(shù)據(jù),通過(guò)分析我們便可知道30分鐘自己能“走”多遠(yuǎn)了。這里我們用到了Python中的folium庫(kù),它是一個(gè)交互式地圖庫(kù),允許我們調(diào)用地圖接口進(jìn)行可視化分析。其安裝方法如下:
pip install folium首先,定義讀取數(shù)據(jù)的函數(shù):
def read_data(path, Type=30):'''讀取交通生活圈數(shù)據(jù)(有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)讀取數(shù)據(jù)(以成都的牛王廟為例):
center, data = read_data('./data/成都/牛王廟.json') data.append(data[0]) for i in range(len(data)): # 交換經(jīng)緯度,很重要data[i] = [data[i][1],data[i][0]]data.append(data[0])是為了使數(shù)據(jù)形成一個(gè)閉環(huán),這樣方便在地圖上表示出來(lái)。
定義地圖,并設(shè)定相關(guān)參數(shù):
在地圖上標(biāo)出起始點(diǎn):
folium.Marker([center[1],center[0]],popup=folium.Popup('牛王廟',max_width=1000),tooltip='出發(fā)點(diǎn)').add_to(Map)在地圖上畫出30分鐘交通生活的區(qū)域:
folium.Polygon(data,color='#7C9F59',fill=True).add_to(Map)將地圖保存到本地:
Map.save('30分鐘交通生活圈.html')打開HTML之后,效果如下:
綠色區(qū)域意味著,在當(dāng)前的交通情況下,我從牛王廟出發(fā),我可以到達(dá)的范圍,即30分鐘我能“走”多遠(yuǎn)~
2. 完整代碼
這一部分的完整代碼如下:
# -*- coding: utf-8 -*- """ Created on Mon Dec 21 18:58:34 2020@author: kimol_love """ import json import foliumdef read_data(path, Type=30):'''讀取交通生活圈數(shù)據(jù)(有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)): # 交換經(jīng)緯度,很重要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='出發(fā)點(diǎn)').add_to(Map)folium.Polygon(data,color='#7C9F59',fill=True).add_to(Map)Map.save('30分鐘交通生活圈.html')寫在最后
至此,我們大致知道了30分鐘自己能“走”多遠(yuǎn)了~
這里主要是從交通通行情況的角度出發(fā),如果非得說(shuō)坐飛機(jī)、坐火箭、坐大炮啥的。別問我,問了我也不知道(手動(dòng)捂臉)~
其實(shí),這個(gè)數(shù)據(jù)還可以嘗試從更多地角度分析,比如可以計(jì)算出30分鐘最大抵達(dá)半徑,并進(jìn)一步比較不同城市的大小等等。如果有感興趣的小伙伴,可以試試哦。
我是kimol君,咋們下次再會(huì)~
創(chuàng)作不易,大俠請(qǐng)留步… 動(dòng)起可愛的雙手,來(lái)個(gè)贊再走唄 (???←?)
總結(jié)
以上是生活随笔為你收集整理的想知道自己30分钟能“走”多远嘛?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言程序设计周记,C语言学习日记
- 下一篇: 腾讯企业邮箱收费标准多少钱一年 腾讯企业