引言
做LBS应用,POI数据是第一块砖。选址分析要看竞品密度,商圈研究要看业态分布,热力图要看点位聚合------这些分析的质量,直接取决于POI数据的覆盖度和准确度。
高德地图的POI接口看起来很简单:申请一个Key,传一个关键词和城市名,就能拿到商户和景点数据。但只要你试过"拉全量",问题会立刻暴露。直接传一个大范围再给关键词,返回结果按相关度截断,翻页翻到后面要么循环重复,要么数据缺得离谱。官方文档也写得很清楚:同请求参数翻页查询最多支持获取200条数据,搜索不支持返回全量数据。对于一个POI密集的城市,200条连一个商圈都覆盖不全。
更麻烦的是配额。2025年5月20日起,高德基础搜索服务的调用限制从"日配额"调整为"月配额",个人认证开发者月配额5000次,企业认证开发者50000次。按每次请求最多拿200条计算,5000次月配额的理论上限是100万条,但这是在"每次请求都满载"的理想情况下,实际采集中的探测请求、翻页请求、去重后的有效数据量都会让这个数字打折扣。
这意味着,全量POI采集不是"多翻几页"就能解决的问题,而是一套空间切分、溢出检测、接口选型、代理配合 的系统工程。本文将围绕这套工程链路展开,并说明站大爷隧道代理IP在多Key、高频请求场景中如何帮助分散IP层面的累积风险。
免责声明:本文仅限技术学习与交流。POI数据采集应遵守高德开放平台的服务条款及相关法律法规,仅将技术用于学习和研究目的,不得将数据用于商业转售或侵犯平台权益。
一、两条数据路径:官方API与前端接口
采集高德POI,有两条本质不同的路径。
1.1 官方API:合规、稳定,但有硬上限
高德Web服务API提供关键字搜索(/v3/place/text)、周边搜索(/v3/place/around)、多边形搜索(/v3/place/polygon)和ID查询四种机制。请求需要携带Key,返回JSON格式的结构化数据,字段包括POI名称、类型、经纬度、地址、电话等。
官方API的优势是合规、稳定、字段完整 ,适合大多数学习和研究场景。限制也很明确:单次搜索翻页最多200条,配额按月计算,超限后返回DAILY_QUERY_OVER_LIMIT等错误。
1.2 前端接口:数据更全,但需要逆向
高德网页端和App端使用的内部接口,在返回数据量上通常比公开API宽松。但这类接口携带动态生成的请求头,例如x-dc和bx-ua,其中bx-ua的生成逻辑被混淆,需要逆向JS还原;x-dc在少量请求时可能不是必须的,但服务端会校验其合法性。
此外,高频访问前端接口会触发JS Challenge(返回含混淆JavaScript的页面)或滑块验证。这类方案的逆向成本和维护成本都很高,只适合有逆向能力的团队做技术研究,不适合作为常规采集方案。
对于大多数开发者,官方API + 空间切分是更务实、更可持续的选择。本文后续的实现以官方API为主。
二、突破200条上限:网格切分与四叉树递归
官方API的200条上限不是"翻页"能绕过的------它是服务端的总量截断。唯一的解法是从物理层面缩小每次请求的空间范围,让每个子区域内的POI数量低于上限。
2.1 矩形网格切分
核心思路很朴素:把目标城市切成一个个小矩形,逐格调用多边形搜索接口,每个格子内的POI数量通常只有百级别,翻一两页就能拿全。
高德的/v3/place/polygon接口接收一组坐标点串,矩形是它的特例。整体流程四步:切 (按经纬度步长切分)、拉 (逐格请求,按页翻完)、并 (按POI ID去重合并)、存(写入SQLite或CSV)。
网格粒度直接决定采集效果。步长太大,密集区会溢出;步长太小,请求量爆炸。一组可参考的经验值:
| 场景 | 步长建议 | 原因 |
|---|---|---|
| 市中心密集区/重点商圈 | 0.005°~0.01° | 单格密度大,小格子避免截断 |
| 一般城市建成区 | 0.01°~0.02° | 覆盖与请求量均衡 |
| 郊区、县域 | 0.02°~0.05° | 数据稀疏,格子可以大 |
| 城市级宏观粗筛 | 0.05°~0.1° | 先定位高密度区块,再二次细分 |
1度纬度约111公里,1度经度的实际距离需要乘以cos(lat)修正。以北京(纬度约40°)为例,0.01度经度约0.85公里,0.01度纬度约1.1公里。
实际项目中推荐两阶段策略:先用粗网格(如0.05°)跑一遍,标记"装满"的格子;第二阶段只对高密度格子细分到0.005°重跑。这样既不会一上来就发起海量请求,又能保证密集区不丢数据。
2.2 四叉树递归:让网格"自动变焦"
固定步长的网格切分有一个问题:步长是预先设定的,无法根据实际密度自适应。四叉树递归解决了这个问题。
算法逻辑是检测---分裂---递归:请求当前矩形区域,如果翻到最大页数时数据仍然是满的(例如每页25条,第7页仍然满25条),说明该区域数据量可能超过了可返回上限,存在截断风险;此时将矩形等分为四个子矩形,递归执行同样的检测,直到每个子区域的数据量低于阈值或达到最小面积限制。
一个工程细节是空间裁剪 :通过shapely判断当前网格是否与城市轮廓相交,如果不相交(例如海面、荒山),直接跳过,节省大量无效请求和配额。另一个细节是初始粗切:先把城市切成100km级别的大块,再进入递归,降低递归栈深度,也方便断点续跑。
四叉树的效果可以这样理解:郊区用大网格快速扫过,市中心自动细分到50米级别的小格子,直到能把每个格子的数据完整拉下来。
三、API选型与请求封装
3.1 多边形搜索 vs 关键字搜索
全量采集应优先使用多边形搜索,而不是关键字搜索。原因有两个:关键字搜索按相关度排序后截断,覆盖不全;多边形搜索只按空间范围过滤,更适合"把区域内的POI全部拉出来"的场景。
如果要按类别采集,不要只依赖keywords,而应该使用types分类编码分段拉取。例如餐饮类传050000,购物类传060000,每个大类分别请求,才能拼出完整的业态数据。
3.2 请求封装
一个带重试和配额监控的请求封装:
import requests, time, random
BASE = "https://restapi.amap.com/v3/place/polygon"
def fetch_polygon(polygon, key, types=None, page=1, offset=25,
proxies=None, retry=3):
params = {
"key": key,
"polygon": polygon, # "lon1,lat1|lon2,lat2|lon3,lat3|lon4,lat4"
"offset": offset,
"page": page,
"extensions": "base",
}
if types:
params["types"] = types
for attempt in range(retry):
try:
resp = requests.get(
BASE, params=params, proxies=proxies, timeout=15
)
data = resp.json()
if data.get("status") == "1":
return data
# 配额/频率类错误,等待后重试
infocode = data.get("infocode", "")
if infocode in ("10003", "10004", "10021", "10029"):
time.sleep(3 * (attempt + 1))
continue
return data
except Exception:
time.sleep(2 * (attempt + 1))
return None
3.3 断点续跑与去重
每个网格的完成状态需要持久化,避免中断后从头再来。用SQLite记录"已完成的网格ID"和"已采集的POI ID":
CREATE TABLE grids (
grid_id TEXT PRIMARY KEY,
status TEXT, -- done / partial
finished_at TEXT
);
CREATE TABLE pois (
poi_id TEXT PRIMARY KEY,
name TEXT, type TEXT,
lon REAL, lat REAL,
address TEXT, grid_id TEXT
);
插入POI时用INSERT OR IGNORE,天然去重。网格完成后更新grids表。重启时跳过status='done'的网格,只补跑未完成的格子。
四、反爬的真实重点:不是IP,是JS挑战和Key管理
4.1 IP层面的封锁并非主要矛盾
有实践者指出,高德对IP地址本身的反爬机制并不算严格。真正的障碍是JS Challenge和滑块验证------当请求模式异常时,服务端返回的不再是JSON,而是含混淆JS的HTML页面或滑块验证页。
这意味着,单纯"换IP"并不能解决所有问题。如果请求的参数、频率、会话特征本身有问题,换多少个IP都会触发挑战。
4.2 Key管理是核心风控维度
高德的配额和风控是以Key为维度的。免费Key有日调用量上限和QPS限制。更关键的是,如果代理IP池与Key没有绑定关系,可能因账号关联风控被降级。
实践中需要做到:每个Key绑定固定的出口IP或IP段,多Key轮询时确保同一个Key的请求来源相对稳定,避免"一个Key今天用北京IP、明天用广州IP"造成异常。如果使用代理,应该为每个Key配置独立的代理出口,而不是所有Key共享一个轮换池。
4.3 站大爷隧道代理的配合方式
在这个风控框架下,站大爷隧道代理IP 的作用是在Key绑定的前提下,为每个Key提供稳定的出口通道,并在需要多Key轮询时隔离不同Key的请求来源:
-
Key与隧道入口绑定 :不同Key使用不同的隧道入口(或不同的
period轮换周期),让每个Key的请求来源保持一致性,降低账号关联风控的风险。 -
分散单IP的累积请求量:即使高德对IP本身不敏感,单IP在长时间运行中累积的请求量仍然可能触发行为层面的挑战。隧道代理的自动轮换可以把请求分散到不同出口,减少单IP的"曝光度"。
-
覆盖广、可用性高:站大爷覆盖全国99%地域,连接成功率在长时间压力测试中稳定在99%以上,适合需要持续运行的网格采集任务。
-
地域定向:如果采集的POI需要与特定城市对应,可以选择对应地域的出口IP,让请求来源与数据地域保持一致。
集成方式很简单:
PROXIES = {
"http": "http://用户名:密码@tps.zdaye.com:8080",
"https": "http://用户名:密码@tps.zdaye.com:8080",
}
需要强调的是:代理解决的是"请求来源的分散和稳定",它不替代Key管理和频率控制。如果Key本身的配额耗尽或触发风控,代理换再多IP也无济于事。
五、从POI数据到LBS应用
采集只是起点,清洗和可视化才是POI数据产生价值的地方。
5.1 数据清洗
原始POI数据需要几项基础清洗:按POI ID去重 (不同网格可能返回同一个POI);过滤类型 (只保留目标业态,如餐饮的050000下各子类);坐标系确认 (高德返回的是GCJ-02坐标,与其他坐标系混用时需要转换);地址标准化(同一商场内的不同商户可能有多条地址表述)。
5.2 选址分析:竞品密度与配套评估
POI数据最直接的应用是商圈选址分析。以某个候选点位为中心,统计周围一定半径内的竞品数量、交通设施数量、住宅小区数量,计算"竞品密度"和"配套完整度"。有开源项目已经实现了完整的单地址选址分析:竞品搜索、配套评估、交通态势、热力图可视化,多地址对比还支持雷达图和柱状图排名。
5.3 热力图与空间聚合
将POI按经纬度聚合到网格中,用颜色深浅表示密度,生成交互式热力图。高德POI数据本身就可以驱动这种可视化------把清洗后的点位数据叠加到地图底图上,用folium或pyecharts生成HTML即可。
5.4 业态结构分析
按types字段统计各一级分类的POI数量和占比,可以快速判断一个区域的业态结构:餐饮主导、零售主导还是服务业主导。进一步计算"餐饮/零售比""服务/人口比"等衍生指标,可以为商业定位提供参考。
六、常见问题与避坑指南
翻页翻到一半开始重复或数据变少。 这是相关度截断的典型表现。不要试图在"大范围+翻页"的模式下硬拉,切换到网格切分或四叉树递归,从空间上缩小请求范围。
某个网格返回的数据明显偏少。 检查是否只用了keywords而遗漏了types分类编码。名称不包含关键词的POI(如"张亮麻辣烫"可能不命中"餐厅"关键词)会被过滤掉,按types分段拉取才能覆盖全。
配额消耗过快。 两阶段策略是有效的控制手段:粗网格定位高密度区,只对"装满"的格子做细分。同时用shapely裁剪掉城市轮廓外的无效网格,避免把配额浪费在海面和荒山上。
触发JS Challenge或滑块。 降低请求频率,增加随机延迟,检查Key与IP的绑定关系是否稳定。如果挑战仍然频繁出现,说明请求模式本身需要调整,而不是单纯增加代理。
多Key轮询时部分Key被降级。 检查每个Key是否绑定了一致的出口IP。代理池与Key混用、所有Key共享同一个轮换池,是账号关联风控的常见诱因。
七、总结
高德POI爬虫的核心矛盾,不是"能不能发请求",而是"如何在配额和返回上限的约束下拿到可用的全量数据":
| 环节 | 关键做法 |
|---|---|
| 接口选型 | 优先官方API多边形搜索,避免前端接口逆向的高维护成本 |
| 突破200条上限 | 矩形网格切分 / 四叉树递归,从空间上缩小请求范围 |
| 网格粒度 | 两阶段策略:粗网格定位,高密度区细分 |
| 反爬重点 | 不是IP封锁,而是JS Challenge、滑块和Key级风控 |
| 代理配合 | 站大爷隧道代理按Key绑定出口,分散累积请求,保持来源稳定 |
| 数据清洗 | POI ID去重、类型过滤、坐标系确认 |
| LBS应用 | 竞品密度、配套评估、热力图、业态结构分析 |
POI数据的价值不在"采了多少条",而在"覆盖得对不对"。一个经过网格切分、四叉树补全、按类型分段拉取的数据集,比一个"大范围翻页翻到截断"的数据集,在选址分析和热力图上得出的结论可能完全不同。站大爷隧道代理在这个链路中承担的是"让请求来源稳定且分散"的角色------它不解决接口上限问题,但可以帮助多Key、高频采集在IP层面保持平稳,减少因来源异常触发的挑战和风控。
最后需要提醒的是:高德POI数据采集应遵守平台的服务条款和配额规则,控制请求频率,不将数据用于商业转售。技术让数据触手可及,合规边界让项目可持续。