简介针对高德交通态势数据的获取需求这套Python爬虫方案面向开发者、交通数据分析人员及地理信息系统应用学习者可调用高德地图API采集实时交通流量与拥堵指数解决路况数据获取与初步处理的难题。方案中包含请求间隔设置、User-Agent伪装等反爬策略以规避接口限制、提升抓取稳定性并给出数据清洗与格式转换的预处理思路。抓取结果支持存储为CSV、JSON或数据库可导入ArcGIS进行空间可视化与拥堵规律分析也能定期运行实现监测更新支撑交通管理、出行规划等场景。下载压缩包共包含2个文件以Python脚本为主辅以一个zip文件整体仅约2KB代码紧凑便于直接阅读和复用。目前已有1867人学习下载适合希望快速搭建轻量级交通态势采集与整理流程的参考者。1. 高德交通态势爬取一个脚本把实时路况变成 ArcGIS 能用的数据做交通数据分析的人大概率经历过这一步接到全城路况需求发现高德有现成的交通态势接口兴冲冲申请 key、调通接口结果返回的是一堆 JSON每条道路是一串 polyline 坐标加一个拥堵等级。丢给 ArcGIS 直接画图画不了。这份「高德交通态势爬取」资源做的就是把“调接口拿 JSON”和“进 ArcGIS 做空间分析”之间的空档填上——高德交通态势爬取.py负责爬取、解析、分区落盘配套的“导入 ArcGIS 前处理”说明负责把数据转成能用的线要素。适合想快速拿到全城实时路况、又不想从零折腾坐标和格式的交通规划、城市研究相关从业者。2. 交通态势接口选型矩形查询怎么调、返回字段怎么读、配额为什么是瓶颈做爬取之前先得搞清楚高德交通态势接口的几个硬约束。这一章把接口选型、参数含义和配额机制讲透后面用脚本时才不会翻车。2.1 矩形查询和圆形查询怎么选高德的交通态势接口有两类查询方式一类是矩形区域查询一类是圆形区域查询。矩形查询要求你传入一个矩形的左下角和右上角经纬度接口返回该矩形范围内所有有路况回报的道路圆形查询则传入中心点和半径。做全城路况分析矩形查询是唯一合理的选择——你能用几个矩形拼出一整个行政区而圆形查询在城区边界会有大量重叠数据去重很麻烦。接口地址是https://restapi.amap.com/v3/traffic/status/rectangle注意这是 v3 版本的 Web 服务接口。高德后来出过更新版本的交通态势服务但那个接口需要额外传diu参数普通个人开发者的 Web 服务 key 基本拿不到权限老项目走 v3 是最稳妥的。这个判断很重要——如果你按新接口文档去调第一步就会卡在参数上。先看一个最简单的请求长什么样curl https://restapi.amap.com/v3/traffic/status/rectangle?keyYOUR_KEYrectangle116.30,39.80,116.45,39.95extensionsalllevel6这里的四个参数是硬性配置key是你在高德开放平台申请的 Web 服务 key类型必须选“Web服务”不能选 Android/iOS 的 keyrectangle是左下角经度、左下角纬度、右上角经度、右上角纬度四个值用英文逗号分隔顺序固定extensions填all才能拿到速度和方向字段填base只有道路名和状态level是道路等级6 代表所有等级如果要单独分析高速可以填 1国道填 2省道填 3县道填 4。2.2 返回结构里真正要读的五个字段请求成功之后返回的是标准 JSON外层有status、info这些通用字段真正的数据在trafficinfo.roads数组里。每条 road 代表一段有独立路况回报的道路片段不是一整条路这点要心里有数。下面是一个典型返回的简化结构{ status: 1, info: OK, trafficinfo: { roads: [ { name: 北四环中路, status: 3, direction: 东, speed: 28, polyline: 116.32,39.91;116.33,39.91;116.34,39.91 } ] } }polyline是道路中心线的坐标串分号分隔坐标点、逗号分隔经纬度这是导入 ArcGIS 的核心素材。真正要读的字段整理如下字段类型含义与判断要点namestring道路名称可能有同名的不同路段不能当主键statusstring拥堵状态0 未知、1 畅通、2 缓行、3 拥堵、4 严重拥堵新版有 4老版只到 3speednumber平均速度单位 km/h可能为 0不一定是数据异常directionstring方向描述如“东”“西”部分路段为空polylinestring中心线坐标串导入 ArcGIS 时逐点解析成线注意status是字符串不是数字写代码时别直接拿int()去转有的响应里会带空字符串。2.3 配额是按公里算的不是按次数算的交通态势接口和其他高德 Web 服务最大的区别是配额机制。普通接口按调用次数扣配额交通态势接口按“道路里程”扣——你请求一次覆盖 10 公里的矩形就扣 10 公里的配额。个人开发者的默认配额非常少少到什么程度一次覆盖全市范围的请求可能直接把当天的配额烧掉大半。这是这个项目里最需要提前规划的点也是很多人在跑数据时中途夭折的原因。解法是在脚本里做两件事第一把大矩形拆成小矩形失败时能单块重试第二把每次请求的原始 JSON 落盘缓存后续分析全部从缓存里读绝不重复请求。下一章写爬取脚本时会把这套机制完整实现。3. 爬取脚本落地从 key 配置到 CSV 分区抓取的完整链路高德交通态势爬取.py的核心思路不复杂读配置、按矩形循环请求、解析 JSON、追加写入 CSV。但细节决定成败这一章给出可复现的完整链路并解释每个参数为什么这么设。3.1 读懂主流程请求函数、重试机制、解析落盘先看请求部分。常见做法是写一个带指数退避重试的请求函数因为交通态势接口对 QPS 很敏感偶尔超时是常态不要一失败就崩溃import requests import time import random KEY 你的高德Web服务Key RECT 116.30,39.80,116.45,39.95 # 左下经度,左下纬度,右上经度,右上纬度 url https://restapi.amap.com/v3/traffic/status/rectangle params { key: KEY, rectangle: RECT, extensions: all, level: 6 } def fetch_traffic(rect): params[rectangle] rect for attempt in range(3): try: resp requests.get(url, paramsparams, timeout10) data resp.json() if data.get(status) 1: return data else: print(f接口返回异常: {data.get(info)}) except Exception as e: print(f第{attempt 1}次请求异常: {e}) time.sleep(2 ** attempt random.random()) return None逻辑说明params[rectangle]在每次调用时动态替换方便循环遍历多个矩形重试采用 2 秒、4 秒、8 秒的指数退避最后加一个随机数是为了避免多个矩形同时失败后同步重试、再次打满 QPS。timeout10必须写不写的话接口假死会卡住整个循环。参数说明RECT这个变量现在只是默认值真正干活时会被rect参数覆盖level6表示取全等级道路如果只分析快速路就改成 1能显著减少数据量。解析函数负责把trafficinfo.roads展平成一行行记录。常见做法是把polyline原样保留再额外算一个中心点方便后面在 ArcGIS 里做点图层def flatten_roads(data): rows [] roads data.get(trafficinfo, {}).get(roads, []) or [] for road in roads: polyline road.get(polyline, ) points polyline.split(;) if polyline else [] center points[len(points) // 2] if points else rows.append({ name: road.get(name, ), status: road.get(status, 0), speed: road.get(speed, ), direction: road.get(direction, ), polyline: polyline, center_lng_lat: center }) return rows逻辑说明center_lng_lat取坐标串中间那个点的经纬度作为路段的近似中心。取中点而不是取第一个点是为了避免 polyline 首尾在路口附近时中心点偏移到马路外面。这个字段不进 ArcGIS 做线而是用来快速预览数据范围和检查矩形是否错位。3.2 参数不是越小越好矩形大小、请求间隔和失败重跑矩形拆多大是一个需要平衡的问题。拆太小请求次数大量增加当天总配额消耗反而更快每次请求有固定开销拆太大单次返回数据量爆炸容易触发接口截断或超时。我一般按经纬度 0.1 度到 0.2 度见方来切也就是大约 10 到 18 公里见方的一个格子。以北京市为例用五个矩形就能覆盖主要城区每个矩形的数据量在一两兆左右解析不会太慢。请求间隔同样要设置。交通态势接口对 QPS 的限制很严格连续快速请求很容易被限流。常见做法是每次循环后sleep(0.5)到sleep(1.5)随机抖动这个区间实测在大多数情况下能稳定跑完一轮rects [ 116.20,39.75,116.35,39.85, 116.35,39.75,116.50,39.85, 116.20,39.85,116.35,39.95 ] csv_file open(traffic_rows.csv, w, encodingutf-8-sig) fieldnames [name, status, speed, direction, polyline, center_lng_lat] writer csv.DictWriter(csv_file, fieldnamesfieldnames) writer.writeheader() for rect in rects: data fetch_traffic(rect) if data: rows flatten_roads(data) for row in rows: writer.writerow(row) print(f{rect} 抓取完成道路数: {len(rows)}) else: print(f{rect} 失败需手工重跑) time.sleep(random.uniform(0.5, 1.5)) csv_file.close()逻辑说明每个矩形独立抓取、独立打印结果失败的矩形会被记录下来而不是让整个流程中断。encodingutf-8-sig是给 Excel 和 ArcGIS 准备的带 BOM 的中文 CSV 在 Windows 下打开不容易乱码。参数说明rects这个列表需要你按照目标城市的地理范围自己定义。怎么确定边界一个偷懒但有效的方法是打开高德地图网页版用坐标拾取器找到城市左下角和右上角的经纬度按 0.1 度步长切成网格再把网格的边界填进列表。3.3 为 ArcGIS 前处理准备的 CSV 字段设计CSV 的字段设计直接决定后面导入 ArcGIS 的工作量。除了上面代码里的六个原始字段我建议你再加两个派生字段fetch_time和rect_id。fetch_time记录抓取时刻因为交通态势是实时数据多轮抓取合并分析时必须能按时间筛选rect_id标记这条数据来自哪个矩形排查问题时能快速定位是哪个区域的抓取逻辑出了问题。写入时在循环内补上这两个字段from datetime import datetime fetch_time datetime.now().strftime(%Y-%m-%d %H:%M:%S) row[fetch_time] fetch_time row[rect_id] rects.index(rect)逻辑说明rect_id直接用列表下标虽然简单但如果后续调整矩形顺序历史数据的 ID 会错乱更稳妥的做法是给每个矩形起一个可读的名字比如chaoyang_west这样 CSV 里看名字就知道是哪个片区。fetch_time建议精确到秒同一个矩形在一小时内多次抓取的数据可以用这个字段区分。到这一步你已经有了一个字段完整、格式规整的 CSV。接下来最大的坑才开始出现——坐标偏移、空字段、配额超限这些都在下一章的避坑手册里集中处理。4. 避坑手册五个必踩的坑和现场排查记录这一章写的是我在实际跑高德交通态势数据时踩过的坑每一条都是“现象→原因→解决”的结构。你大概率会遇到其中至少三条。4.1 配额耗尽一天的量一次跑光现象脚本刚开始跑得挺顺利几分钟后接口开始返回类似配额超限的提示info字段不再是OK而是提示当天配额已用完后续所有请求全部失败。原因交通态势接口按道路里程扣配额矩形越大、覆盖的道路越多单次扣得越狠。个人开发者默认配额很低一次大范围的请求就烧掉大半再跑几轮彻底归零。解决第一把矩形控制在 0.1 度到 0.2 度见方别贪大第二原始 JSON 一定要缓存分析数据时不要去重新请求前一天已经抓过的内容第三如果配额确实不够用把请求时间错开每天零点重置后再跑不要在同一天内反复重试。4.2 rectangle 参数写错一个符号毁掉一次全城拉取现象请求返回status1、infoOK但trafficinfo.roads是空的或者返回的道路数量少得离谱明显和矩形范围不匹配。原因rectangle参数要求的顺序是“左下经度、左下纬度、右上经度、右上纬度”很多人习惯性写成左上和右下或者把经度纬度顺序搞反。还有一种情况是用了中文逗号高德解析失败后静默返回空结果不报错。解决写一个自检函数每次请求后检查roads的长度如果请求成功但道路数为 0先打印出当前的rectangle并人工核对范围。另外先用一个小矩形测试比如经纬度跨度只有 0.02 度、确定有城市道路的区域能返回几条 road 再铺开全城网格。4.3 坐标系偏移GCJ-02 和 WGS84 的几百米差距现象把 CSV 导入 ArcGIS 后路况线和底图道路明显错位严重的时候偏离几百米甚至一公里看起来像数据抓错了。原因高德返回的polyline坐标用的是 GCJ-02火星坐标系而 ArcGIS 默认在线底图通常是 WGS84 坐标系两者之间大约有几百米的系统性偏移纬度越高偏移越明显。解决最简单的方法是不做坐标转换直接在 ArcGIS 或 QGIS 里叠加高德瓦片底图让数据和底图保持同一个坐标体系。如果你必须用 WGS84 底图就得先对polyline做 GCJ-02 到 WGS84 的近似纠偏。网上有很多开源实现但别指望它有厘米级精度肉眼对齐底图是没问题的。4.4 speed 为 0 与 status 对不上缺失值不能乱删现象同一段路status1畅通但speed0或者status3拥堵但speed80看起来数据自相矛盾。原因speed字段在部分路况响应里本身就是缺失值高德用 0 表示“没有速度回报”并不代表车辆真的静止status和speed的更新频率也可能不同一个是路况计算值一个是实时速度采样值时间上略有错位。解决判读时以status为主、speed为辅。speed为 0 时不要直接删行也不要填成 0 参与计算最好原样保留空值在 ArcGIS 做分级渲染时用status字段不要用speed直接做颜色梯度否则会出现大量灰点。4.5 空 roads 和偶发超时怎么判断是没路还是被卡了现象某个矩形请求返回status1但roads为空或者请求偶发超时、返回异常状态码重试几次又好了。原因两种情况本质不同。空roads可能是矩形范围确实不在路网覆盖区比如画在了水域、郊区空旷地带偶发超时则多半是对端限流或网络抖动重试能解决。解决按住 4.2 的自检思路空roads时打印矩形范围并人工确认是不是郊区偶发超时用第 3 章的重试函数处理3 次指数退避足够。跑完一轮后把失败的矩形记录到一个retry_list.txt单独重跑不要重新拉全量。5. 导入 ArcGIS 的前处理polyline 转线、GCJ-02 纠偏与瓦片底图叠加zip 包的备注写着“导入 ArcGIS 前处理使用”这步就是把上一步的 CSV 变成 ArcGIS 能识别的线要素。这里给出我常用的处理流程。5.1 把 polyline 解析成线要素在 ArcGIS 里用 arcpy 把 CSV 转成线要素。如果环境里没有 arcpy用 QGIS 的“从分隔文本添加图层”也能做但处理大量 polyline 时 arcpy 更可控import arcpy import csv arcpy.env.workspace rC:\traffic fc arcpy.CreateFeatureclass_management( C:/traffic/traffic.gdb, traffic_lines, POLYLINE ) with open(traffic_rows.csv, r, encodingutf-8-sig) as f: reader csv.DictReader(f) with arcpy.da.InsertCursor(fc, [SHAPE, name, status, speed]) as cursor: for row in reader: polyline_str row[polyline] if not polyline_str: continue point_list [] for pair in polyline_str.split(;): lng, lat pair.split(,) point_list.append(arcpy.Point(float(lng), float(lat))) line arcpy.Polyline(arcpy.Array(point_list)) cursor.insertRow([line, row[name], row[status], row[speed]])逻辑说明polyline的格式是“分号分隔坐标对、逗号分隔经纬度”先按分号拆出每个点的坐标再按逗号拆成经度和纬度拼成arcpy.Point列表最后用arcpy.Polyline生成线要素。SHAPE是 arcpy 插入游标里代表几何对象的关键字必须写成这个带 的形式。参数说明目标工作空间建议放在 File Geodatabase 里比 shapefile 快而且能直接存线要素的坐标系属性。插入前先确认polyline里的坐标确实是 GCJ-02否则后面叠加底图会错位。5.2 叠加高德瓦片底图并做分级渲染线要素建好之后叠加瓦片底图做可视化。这里用的就是“高德地图瓦片”在 QGIS 里新增 XYZ Tile 图层URL 模板填https://webrd0{1-4}.is.autonavi.com/appmaptile?style7x{x}y{y}z{z}参数说明{1-4}是瓦片服务器编号QGIS 会自动做负载均衡style7是默认路网样式。这套底图和你的polyline同为 GCJ-02叠加后不会有偏移。渲染时按status做分级0 灰色、1 绿色、2 黄色、3 橙色、4 红色一眼就能看出全城拥堵分布。我最早跑这个流程时用一个大矩形把全市一次性拉完第一天就把配额烧光了后面三天只能对着缓存干等。从那以后凡是涉及高德交通态势的活儿我都强制自己走一遍“先拆矩形、再落缓存、最后才做 ArcGIS 前处理”的顺序顺序不乱数据就一直在。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?