简介:基于Python的高德地图调用与数据采集源码,面向地理信息初学者、爬虫开发者以及需要快速搭建地图可视化页面的技术人员。示例以高德地图API为核心,实现坐标定位、地图展示与交互操作,同时结合58租房页面数据进行抓取和清洗,最终整合为可浏览的租房信息地图,打通从数据源到前端呈现的完整链路。压缩包共11个文件,包含2个Python程序(分别承担数据爬取和Web服务)、1个HTML地图页面、1个CSV租房数据、2份doc说明文档以及3个xml工程配置文件,整体大小仅4.41MB,结构精简、分类清楚,便于按需查阅与二次开发。配套的程序配置说明详细讲解环境搭建、运行参数和常见问题,配合readme可以快速复现项目;对希望学习地图API调用、爬虫脚本编写以及前后端数据联调的开发者,是一份可直接运行的参考实现。目前已有1309人学习下载,适合作为课程设计或小型项目的原型模板。 这几个月我在给公司做内部调度系统,有个硬需求:把所有外勤人员的轨迹和配送路线叠在高德底图上展示,还要支持按时间段回放。项目一开始就定了用 Python 做数据处理,地图自然想到高德地图。网上聊怎么申请 Key 的教程不少,但把 Python 环境和地图接口、可视化串成一条完整链路讲的很少,尤其是几个容易踩的坑,基本散落在各个评论区。这篇文章就是我跑完整套流程后的记录,从环境准备、Key 申请到地理编码、路径规划和轨迹可视化,再到瓦片、路况数据背后的授权边界,适合刚入门的 Python 开发者,也适合要在内部运维、数据大屏里快速接入地图能力的同学。你不需要多深的地图基础,按我给的代码和思路走,一下午能跑通。
1. 先想明白你的地图需求,再选技术路线
1.1 同样是“用Python实现高德地图”,需求其实分三类
我在动手之前,习惯先问一句:你要的到底是“地图长什么样”,还是“地图接口返回什么数据”?这两个方向的技术选型差别很大。
| 需求类型 | 典型场景 | 核心技术点 |
|---|---|---|
| 纯数据接口 | 批量地址转坐标、POI检索、路径规划数据 | 高德Web服务API,requests库 |
| 地图可视化 | 轨迹大屏、路线回放、门店分布 | folium、ECharts、高德JS API |
| 数据处理 | 轨迹纠偏、路况分析、坐标转换 | Python数据处理 + API组合 |
这个分类直接决定了你的代码结构。如果只是想把几千个公司名转成经纬度然后落库,就不需要折腾 folium;如果要做一张运营大屏展示车辆轨迹,那就必须理解瓦片加载和坐标系。
1.2 为什么优先用官方API,而不是直接爬网页
早期我图省事,试过直接 requests 去抓高德网页版的搜索接口,结果遇到的不是加密参数就是风控验证,十分钟能完成的事折腾了一晚上,而且最后拿到的数据还不能商用。后来老老实实切到官方API,不仅稳定,文档也完整。
在地图这件事上,数据版权和坐标系是两堵墙。网页页面里展示的数据属于高德资产,用来做个人学习没问题,但一旦放到系统里就有“未获得高德地图商用授权”的风险。正确的打开方式永远是:通过高德开放平台的各类API去拿数据,按官方规则使用。
2. Python环境与高德Key准备:比想象中更值钱的半小时
2.1 开发环境:Python版本和依赖库
个人建议直接上 Python 3.10 或更新版本,高德Web服务API是基于HTTP协议的,对版本不挑,但后续做轨迹可视化的时候,新版库对类型注解和异步支持都更好。如果你还没装好环境,安装时记得勾选“Add Python to PATH”这一项,很多新手后面在命令行里敲不出 python 命令,都是这一步漏了。
装完之后,用虚拟环境管理项目依赖:
python -m venv venv source venv/bin/activate # Windows下是 venv\Scripts\activate pip install requests folium pandas这里只列了最核心的库。requests 用来调高德接口,folium 用来把轨迹画到地图上,pandas 用来做批量的数据整理。如果你后续要做坐标转换,可能还需要安装 pyproj,但那是后话。
VSCode 里要配就配三个东西:Python 插件、Pylance、以及 Python 解释器路径。选中虚拟环境里的 python.exe,终端里用哪个解释器、运行哪个依赖库,就不会傻傻分不清。
2.2 注册高德开放平台,申请正确的Key
进入高德开放平台控制台,注册完成后,“应用管理”里创建一个应用,然后添加Key。这里有个重要区分:
- Web服务API 的Key,用来请求
restapi.amap.com下的各种接口; - JavaScript API 的Key,用来在前端页面里加载地图。
我在项目里两个都用到了:Python后台调Web服务API拿轨迹数据,前端页面用JS API做交互展示。你一定要确认自己的Key类型对得上,否则会碰见INVALID_USER_KEY这种让人摸不着头脑的报错。
申请好之后,把Key写进环境变量或者单独的配置文件里,不要硬编码到代码中,这是习惯问题。
2.3 项目目录建议
amap_demo/ ├── config.py ├── amap_helper.py ├── visualize.py └── data/ ├── geocoded.csv └── routes.jsonconfig.py 放Key和统一请求参数,amap_helper.py 封装所有接口调用,visualize.py 只负责画图。把数据获取和可视化分离,后面调试的时候能省下大量时间。
3. 核心接口封装:从地址到坐标再到路线的完整链路
3.1 地理编码:把地址变成坐标
地理编码是使用频率最高的接口。用户给你一堆中文地址,你要先转成经纬度,才能继续做地图展示和路径规划。
import requests from config import AMAP_KEY def geocode(address: str, city: str = "") -> tuple | None: url = "https://restapi.amap.com/v3/geocode/geo" params = { "key": AMAP_KEY, "address": address, "city": city, } resp = requests.get(url, params=params, timeout=3) data = resp.json() if data["status"] == "1" and data["geocodes"]: lng, lat = data["geocodes"][0]["location"].split(",") return float(lng), float(lat) return None if __name__ == "__main__": print(geocode("北京市朝阳区望京SOHO", "北京"))这里有一个所有地图新手都会忽略的细节:高德返回的坐标是GCJ-02 坐标系,不是 GPS 拿到的 WGS-84 坐标。如果你把设备GPS的点直接叠在高德底图上,会发现偏移几十米到几百米。如果是车载设备、手机上报的原始坐标,一定要先做坐标转换再丢给高德接口。
3.2 POI搜索:在指定城市找兴趣点
有了坐标之后,第二高频的需求是周边检索。比如给我一批加油站坐标,找附近500米内的餐饮店。
def search_poi(keywords: str, city: str = "北京", types: str = "", offset: int = 20, page: int = 1): url = "https://restapi.amap.com/v3/place/text" params = { "key": AMAP_KEY, "keywords": keywords, "city": city, "types": types, "offset": offset, "page": page, } resp = requests.get(url, params=params, timeout=5) data = resp.json() return data.get("pois", [])types按高德的POI分类编码填,比如050000表示餐饮、010000表示汽车服务。如果不确定,可以先不传 types,用keywords直接搜。注意搜索结果分页,count字段返回总数,page和offset配合翻页,但单页最大不要超过25,拉太多容易被截断。
3.3 路径规划:把一条路线变成一串经纬度
路径规划接口返回的不止是总里程和总时间,还有每一个步骤的路段形状点。这些形状点才是你画轨迹的依据。
def get_driving_path(origin: str, destination: str, strategy: int = 0): url = "https://restapi.amap.com/v3/direction/driving" params = { "key": AMAP_KEY, "origin": origin, "destination": destination, "strategy": strategy, } resp = requests.get(url, params=params, timeout=5) data = resp.json() route = data["route"]["paths"][0] points = [] for step in route["steps"]: polyline = step["polyline"] for point in polyline.split(";"): lng, lat = point.split(",") points.append((float(lng), float(lat))) return { "distance": route["distance"], "duration": route["duration"], "points": points, }strategy参数决定了路线偏好:0速度优先、1费用优先、6躲避拥堵,还有不走高速等。实测下来速度优先的路线最符合日常导航感知,但早晚高峰时段差异会比较大。如果要做多条路线对比,可以传入strategy=32等组合值,或者反复调用接口获取不同方案。
这里的解析逻辑很简单:路径规划返回的是steps数组,每个step里有一个polyline字段,把每一段的形状点用分号切分,再拼起来,就是一条完整的折线。
4. 可视化落地:把轨迹画在高德底图上
4.1 底图从哪来:瓦片加载的基本原理
任何在线地图的底图都不是一整张大图,而是切成无数个小方块(瓦片),按层级 z、横向 x、纵向 y 编号。地图组件在移动和缩放时,只加载当前视野范围内的瓦片。高德的瓦片URL基本是这个套路:
https://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}folium、Leaflet 这类库会自动用{x}{y}{z}去拼接瓦片地址,你只需要把模板给它就行。但是记住,瓦片属于高德的基础地图资源,在项目里做个人学习、内部验证都行,如果要商业化使用,应该走官方JS API或商业授权渠道,而不是自己拉一堆瓦片搭离线地图。
4.2 方案一:folium加载高德瓦片,五步画出轨迹
folium 基于 Leaflet,后端生成HTML文件,浏览器里就能看,不需要起服务,适合快速交付。
import folium # 注意:高德返回的是 lng, lat,folium需要的顺序是 lat, lng track_points = [(lat, lng) for lng, lat in route_points] m = folium.Map( location=track_points[0], zoom_start=14, tiles="https://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}", attr="高德地图" ) folium.PolyLine( track_points, color="#FF6A00", weight=4, opacity=0.8 ).add_to(m) m.save("route.html")这个方案里最容易翻车的是坐标顺序。高德API返回的location是“经度,纬度”,而 folium 的所有坐标放进去时要写成“纬度,经度”。我第一次画线发现轨迹跑到海里去,检查半天才发现就是这个顺序问题。
4.3 方案二:ECharts结合高德地图,做动态交互大屏
如果你要把轨迹放到运营大屏,folium 的交互感可能不够。ECharts 结合高德底图是另一条很流行的路线,正好对应很多人在搜的“地图echart结合高德地图绘制多条路线轨迹”。
思路是:Python 只负责从高德API拿到所有轨迹点,统一输出成JSON文件;前端页面上用高德JS API加载底图,再把 ECharts 的 geo 坐标系和高德底图绑定,然后在 geo 上叠加线条。核心逻辑大致是这样:
const map = new AMap.Map('container', { zoom: 12, center: [116.40, 39.90] }); const chart = echarts.init(document.getElementById('chart')); chart.setOption({ geo: { map: 'amap', roam: true, }, series: [{ type: 'lines', coordinateSystem: 'geo', data: routeData, // Python生成的JSON lineStyle: { color: '#FF6A00', width: 3 } }] });实际落地的时候,一般会借助amap-echarts这类适配方案,让 ECharts 的 geo 坐标和高德地图联动。相比 folium 的优点是动画效果好、支持多系列数据,缺点是要前后端配合,调试成本高一些。
4.4 多条轨迹同屏展示,数据组织要注意什么
多条轨迹的时候,别把每条轨迹的逻辑都混在一个函数里。我建议统一组织成列表:
routes = [ {"name": "车辆A", "points": [(lat, lng), ...], "color": "#FF6A00"}, {"name": "车辆B", "points": [(lat, lng), ...], "color": "#33CC66"}, ] for route in routes: folium.PolyLine( route["points"], color=route["color"], weight=3, popup=route["name"], ).add_to(m)轨迹点特别多的时候,记得做抽稀。用最简单的等距抽稀就行:两点的直线距离小于一定阈值就跳过,不然很长的历史轨迹会让HTML文件膨胀到几十MB,浏览器直接卡死。抽稀阈值我一般取10米到30米,不影响视觉观感,性能提升却很显著。
5. 瓦片、路况数据和商用授权:必须知道的合规边界
5.1 瓦片能加载,但别批量抓取
4.1节里我给了高德瓦片的URL模板,这是为了让个人开发者在学习时理解原理。很多人看到这个URL会想到一件事:我能不能写脚本把某个城市所有层级的瓦片全部下载下来,做成离线地图包?我的建议是不要,这不是技术问题,而是规则问题。
高德地图瓦片受版权保护,批量抓取和离线分发属于平台条款明确禁止的行为。做过这个操作的人应该也发现了,下载到一半就会遇到大量403或者错乱瓦片,因为服务端会对异常请求做风控。真要离线地图,去了解高德开放平台的专有云方案或者购买相应授权,这才是正途。
5.2 路况和道路矢量的正规获取方式
热搜词里有“怎么导出高德地图的路况道路矢量”,这个需求很实际,比如做物流调度要看当前路段拥堵情况。官方有交通态势API,按矩形范围查询路况:
https://restapi.amap.com/v3/traffic/status/rectangle?key=你的Key&rectangle=116.35,39.90;116.45,40.00返回的结果里有每段道路的拥堵等级、速度和方向。这个接口需要申请开通,配额也有上限,用之前先在控制台看清楚剩余配额。
至于“全城道路矢量数据”,高德官方目前没有提供一个接口让你把整个城市的路网一次性下载。能做的是:用轨迹纠偏API把GPS轨迹匹配到道路上,或者结合路况API和POI数据做局部道路分析。如果业务确实需要完整路网,正确姿势是联系高德商务,购买数据产品或授权。市面上那些所谓“爬好的路网数据包”,来源不明、坐标系混乱、更新滞后,用了反而容易惹出版权和数据质量的麻烦。
5.3 商用授权和配额管理,别心存侥幸
很多开发者是在内部系统里接入高德API,觉得“内部用没什么大事”。但严格来讲,内部系统如果服务于业务运营,同样属于商业行为,需要确认是否符合高德的使用条款。官方的免费额度对个人学习和原型验证完全够用,但大规模商用前一定要去开通商用授权或购买配额。
配额有限的时候,不要想着申请几十个Key轮询绕开限制。地图平台对Key的风控体系很成熟,一旦触发异常反而会封停。正确做法是两层:
- 批量任务加缓存,同一个地理编码结果不要重复请求;
- 需要大量调用的任务跑在异步队列里,设置合理的时间间隔,避开高峰。
我给公司做的调度系统,就是把地址转坐标的结果落到了本地SQLite里。第二次再跑同样的地址,直接查缓存,配额消耗直接降了一个数量级。
6. 最后分享几个零散但能救命的实操心得
第一次调路径规划接口,返回INVALID_USER_KEY,我检查了半小时代码,最后发现是控制台里Key类型选错了——申请的是JavaScript API的Key,却拿去请求Web服务接口。所以申请完之后,先在浏览器里敲一下restapi.amap.com的URL,确认能返回JSON再写代码,这个习惯能省下大量时间。
另外高德接口里判断失败不能只看HTTP状态码。哪怕resp.status_code == 200,返回体里的status字段也可能是"0",真正的错误信息在info字段里。代码里统一用data["status"] == "1"判断成功,遇到info是INVALID_PARAMS、DAILY_QUERY_OVER_LIMIT之类的,再针对性去控制台看配额或参数。
最后说一点和坐标系有关的体会。项目里如果同时有GPS设备数据和高德接口数据,一定要在入库前统一转成同一坐标系,否则后面所有距离计算、路况匹配都会偏差。地图项目看着简单,真正的复杂度往往藏在坐标系、授权、配额这些“看不见的地基”里。我这次跑通的流程不算复杂,但它把 Python 和高德地图的整条链路完整串起来了,整套代码稍作修改就能复用到门店选址、配送监控、通勤分析等场景,如果你也刚好卡在哪一步,不妨按文章里的思路重新理一遍。
本文还有配套的精品资源,点击获取