大家好我是小白鸽,最近有朋友在问怎么获取AOI数据,所谓AOI也叫感兴趣面,其实就是目标地名的边界数据,小白鸽以前也研究过,确实有一定的难度,今天就给大家分享一下从地图软件获取AOI的思路。
声明:本文章仅作技术探讨,本人并未对文章所涉及的地图软件数据做过大规模爬取,各位切勿模仿,切勿用于商业用途。
获取思路
根据获取的方法可以总结为一步获取和分步获取。一步获取是指通过一个工具即可实现,多步获取需要多个工具组合实现。大致思路都一致,都是先查找地名(或请求接口)再抓包最后解析数据,不过实施起来有些差异。
-
携带AOI信息的接口地址:
以高德地图为例,目前携带AOI信息的接口有两个,分别是poiInfo和detail,poiInfo对应于搜索框,detail对应于具体地点,如果在搜索框内搜索地名,只会请求poiInfo接口,如果进一步在搜索列表中选取具体的结果或者在地图上点击具体地点,则会请求detail接口。
-
请求:
请求可以通过代码实现也可以通过自动化工具实现,在Python中可以使用requests库或者selenium库进行请求,requests可以直接请求上述两个接口地址,不过由于反爬和风控存在不一定会成功,所以我一般使用selenium去模拟浏览器访问,通过控制浏览器在搜索框中搜索地名;如果使用自动化工具,可以选择Automa,Automa是一个网页自动化工具,通过可视化的配置可以实现自动在页面搜索地名,入门教程可以参考往期视频。
网页自动化神器|可视化爬虫|automa使用教程
-
抓包:
抓包可以通过代码实现也可以通过软件实现,在Python中通常使用Browsermobproxy或Scapy库进行抓包(使用其他库也行,此处不做详细介绍),通过软件抓包可以使用Fillder(使用其他软件也行),Fillder的使用方法可以查看一下别人的教程,主要用途是获取和过滤URL请求,在Fillder中通过配置filter对目标URL进行过滤,只显示包含poiInfo或detail的URL请求。
-
解析数据:
上述URL请求返回的是json对象,往期文章对json对象的解析做过详细说明,并且对于坐标序列转shape也有介绍。此处仅展示从detail请求结果提取坐标序列的代码。
【数据处理】高德地图路径规划数据转存shp以及json转geojson介绍
# 解析JSON数据
data = json.loads(json_data)
# 提取shape内的坐标序列
shape = data['spec']['mining_shape']['shape']
# 将坐标序列分割成单独的坐标对
coordinates = shape.split(';')
-
一步获取思路:
利用Python对全过程进行操作,包括读取文件、模拟访问、搜索地名、抓包和解析数据。
-
多步获取思路:
1、使用selenium模拟访问,使用Fillder进行抓包,统一保存数据包最后通过Python进行数据解析。
2、使用Automa模拟访问,使用Fillder进行抓包,统一保存数据包最后通过Python进行数据解析。
2和1相比,避开了模拟访问部分的代码,更简单。
难点及解决方案
-
难点:
高德地图具有十分严格的反爬和风控策略,经过测试总结如下:
1、访问频率检测:后台会检测ip和账号的访问情况,如果访问频率过高会被风控,被风控的账号可能带有某种标签,后续的访问也会被严格检测。
2、人机验证:如果账号已经被风控,在请求的过程中会偶尔被要求进行人机验证(滑块)。
3、错误提示:错误提示的方式有两种,一种是在请求的过程种可能会通过弹窗的方式弹出错误提示,这种是在账号被风控后偶发的,另一种是点击提示错误,在搜索列表中通过点击选择具体结果时会提示错误,当出现这种情况时,后续的每一次点击都会提示出错。
4、强制登陆:这种风控出现的机制还没弄懂,但是你的每一次搜索都会提示登陆,关闭后会再弹出提示,反复关闭后出提示错误,此种情况无法进行任何操作。
5、返回错误信息:当账号被风控还继续搜索时,系统可能会返回错误的结果,主要是错误的定位以及不展示AOI
-
解决方案:
1、降低访问频率:在请求时可以主动降低访问频率,延迟一定时间进行访问。
2、账号池和ip池:在爬取时做一个账号池和ip池,切换使用,不过ip池有个问题就是ip切换后Fillder会掉线,所以除非不抓包,如果抓包就别使用ip池。
3、登陆/不登陆:经过测试,在登陆或者不登陆时都有概率稳定访问,所以可以先尝试不登陆,降低访问频率看是否可以稳定访问,如果提示登陆可以直接关闭弹窗,个人测试用selenium在不登陆的状态下可以稳定访问(测试量50)。如果出现强制登陆的情况,可以尝试清除缓存再登陆,个人测试也是可以稳定访问(测试量50)。
4、清除缓存:被风控可以尝试清除缓存,尤其是已登陆状态下被风控。
5、重复请求:即便是已风控状态下,只要不是强制登陆,都能返回部分数据的AOI,对于没返回的部分可以继续请求。
实测结果
本实测案例采用的Automa+Fillder的方式,因为不用写代码真的很爽哈哈。
Automa从读取文件到循环搜索的脚本可以参考如下配置
Fillder过滤请求可以参考如下配置
本实测案例准备了50个地名用于搜索,实测发现在上述各种解决方案的组合使用下,可以稳定访问并获取数据。
多说两句
-
手机抓包:
实际上还有一个没有经过测试的技术思路,那就是对手机的数据流抓包,通过一定的设置Fillder也可以对手机数据流抓包,这时只需在前端做一个自动化脚本就行,当然脚本需要尽量模拟真人操作。
-
百度地图:
实际上百度地图也可以通过上述方式甚至是更简单的方式获取AOI,因为百度的风控没有那么严格,不过测试发现获取的结果不是标准的经纬度,估计是百度用了投影坐标或者是对坐标加了密,感兴趣可以试试。
希望有一天各大地图厂商可以开放官方接口,通过开发者平台去申请调用,让用户像获取POI一样光明正大获取其他数据。最后欢迎大家去微信公众号“小白鸽gis”点点关注,谢谢