Python突破高德API限制爬取交通态势数据+GIS可视化(超详细)

一、需求:

       爬取高德的交通态势API,将数据可视化为含有交通态势信息的矢量路网数据。

二、使用的工具:

       Python IDLE、记事本编辑器、ArcGIS 10.2、申请的高德开发者KEY(免费)。

三、主要思路:

       本文的思路是使用Python的requests模块爬取高德API的返回信息,将返回的信息数据(JSON),通过代码解析的方式存入CSV文件中,再导入ArcGIS中进行可视化处理。

四、分析阶段:

       根据高德提供的交通态势信息API文档,注意到高德提供了两种获取交通态势信息的方式,一种是通过设定矩形区域(传入左下角以及右上角坐标)的方式,一种是通过设定圆形区域的方式(设定圆心坐标和半径),本文使用的是设定矩形区域的方式。 但是问题来了,高德对用户的API行为进行了限制,要求设定的矩形区域的对角线长度不超过10公里,但这是难不倒程序猿的,可以使用网格的思想来突破这一限制,如下图:

《Python突破高德API限制爬取交通态势数据+GIS可视化(超详细)》

        即将爬取区域分成多个网格,每个网格在高德规定的10公里范围之内即可,这样虽然增加了API的调用次数,但不得不说是较为合适的解决方案,本思想同样也适用于POI信息的爬取,在本文中笔者使用了简单的for循环来实现网格爬取,当然读者也可以参考:

        百度地图POI数据爬取,突破百度地图API爬取数目“400条“的限制 

        这篇博文中的LocaDiv类来实现更为复杂化的网格爬取方式。

五、编写代码:

        由于本文的爬虫程序比较简单,因此笔者为了方便直接使用Python自带的IDLE进行程序编写,代码如下:

import requests
import pandas as pd
import json
import time

#初始API的URL
url="https://restapi.amap.com/v3/traffic/status/rectangle?key=申请的key&extensions=all&rectangle="

#设定整个网格左下角坐标的经纬度值
baselng=116.927748
baselat=36.62361
#设定每个网格单元的经纬度宽
widthlng=0.05
widthlat=0.04
#用于储存数据
x=[]
#用于标识交通态势线段
num=0

#爬取过程可能会出错中断,因此增加异常处理
try:
    #循环每个网格进行数据爬取,在这里构建了3X3网格
    for i in range(0,3):
        #设定网格单元的左下与右上坐标的纬度值
        #在这里对数据进行处理,使之保留6位小数(不保留可能会莫名其妙出错)
        startlat=round(baselat+i*widthlat,6)
        endlat=round(startlat+widthlat,6)
        for j in range(0,3):
            #设定网格单元的左下与右上坐标的经度值
            startlng=round(baselng+j*widthlng,6)
            endlng=round(startlng+widthlng,6)
            #设置API的URL并进行输出测试
            locStr=str(startlng)+","+str(startlat)+";"+str(endlng)+","+str(endlat)
            thisUrl=url+locStr
            print(thisUrl)
            #爬取数据
            data=requests.get(thisUrl)
            s=data.json()
            a=s["trafficinfo"]["roads"]
            #注意,提取数值需要使用XXX.get()的方式来实现,如a[k].get('speed')
            #若使用a[k]['speed']来提取,或会导致KeyError错误
            for k in range(0,len(a)):
                s2=a[k]["polyline"]
                s3=s2.split(";")
                for l in range(0,len(s3)):
                    s4=s3[l].split(",")
                    x.append([a[k].get('name'),a[k].get('status'),a[k].get('speed'),num,float(s4[0]),float(s4[1])])
                num=num+1
            #若爬取网格较多,可使用time.sleep(秒数)来避免高德的单秒API调用次数的限制
except Exception  as e:
    pass

#将数据结构化存储至规定目录的CSV文件中
c = pd.DataFrame(x)
c.to_csv('E:/BigRoads.csv',encoding='utf-8-sig')#感谢网友weixin_43475766的提醒

六、CSV数据处理:

        在相关目录下找到爬取的CSV文件,用记事本打开,删除第一行的内容(,0,1,2,3,4,5),否则会导致导入ArcGIS时出错。

七、交通态势信息可视化:

        1、打开Arcmap,在右侧的catlog(目录)中找到爬取的CSV文件直接拖入左侧的内容列表中,如图:    

《Python突破高德API限制爬取交通态势数据+GIS可视化(超详细)》

        2、右键点击该CSV数据,选择“显示XY数据”:

《Python突破高德API限制爬取交通态势数据+GIS可视化(超详细)》

        3、在弹出的设置框中,进行如下设置:

《Python突破高德API限制爬取交通态势数据+GIS可视化(超详细)》

        需要注意的是,本文中爬取的高德数据的坐标值使用的是GCJ-02坐标系,若要应用至项目中,需要转换为WGS-84坐标系,本文为了省事,且为了与高德在线底图对比验证,直接当作WGS84坐标来处理。点击两次确定,即可看到CSV文件成功的转换为了点要素文件。

《Python突破高德API限制爬取交通态势数据+GIS可视化(超详细)》

        4、接下来的一步十分重要,打开生成要素的属性表可以发现,属性表并没有FID(objectID)字段,若无该字段,该点要素将无法转换为线要素,因此需要将该要素导出为SHP文件,方法是右键单击该要素,选择数据->导出数据,如下图:

《Python突破高德API限制爬取交通态势数据+GIS可视化(超详细)》

        然后进行如下设置,注意要导出为shp格式:

《Python突破高德API限制爬取交通态势数据+GIS可视化(超详细)》

        5、接下来是将交通态势点转换为线,在toolbox中找到“点集转线”工具(数据管理工具->要素->点集转线),在弹出的设置界面进行如下设置:

《Python突破高德API限制爬取交通态势数据+GIS可视化(超详细)》

        注意线字段选择Field5(即代码中的num变量),排序字段选择FID。

        6、等待片刻,完整的路网呈现在眼前:

《Python突破高德API限制爬取交通态势数据+GIS可视化(超详细)》

        看到了路网是不是一阵狂喜,但是打开属性表,似乎笑不出来了,原来的交通态势属性去哪了!!!

《Python突破高德API限制爬取交通态势数据+GIS可视化(超详细)》

        不要着急,接下来一步,将属性完美的找回来。

        7、右键路网数据,选择连接和关联->连接,如下图:

《Python突破高德API限制爬取交通态势数据+GIS可视化(超详细)》

        在弹出的设置框中进行如下设置:

《Python突破高德API限制爬取交通态势数据+GIS可视化(超详细)》

        第二个选项可以是原始的CSV表,也可以是用来转线的点文件(即本文的jinan.shp),点击确定,再打开属性表,属性是不是回来了呢?

        8、分级渲染可视化一下,美滋滋~

《Python突破高德API限制爬取交通态势数据+GIS可视化(超详细)》

        什么?为什么这么丑?不要在意这些细节………..

    原文作者:郑允豪@Smart3S
    原文地址: https://blog.csdn.net/Smart3S/article/details/83010397
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞