如何获取全国省市区行政边界数据
今天我们以高德地图为例,讲解一下如何获取全国省市区行政边界数据。
高德开放平台Web服务API
https://lbs.amap.com/
依次点击开发支持–Web服务–Web服务API,即可进入到高德开放平台Web服务API页面。
可以发现,官方已开放了行政区域查询的接口。
点击查看该接口的详细介绍:
其实就是先申请Key,然后构造Http请求,发送请求解析返回数据即可。
同时接口文档提到,该接口只能返回国、省、市、区的polyline(边界点集合),不支持街道级别,但已经满足我们的需求了。
首先分析下接口请求参数:
有4点值得关注:
- keywords支持行政区名称、citycode、adcode这3种格式,行政区名称可能存在重复(尤其level是县/区时),而citycode只有level在市或市以下才有,只有adcode可以唯一指定某个行政区,所以检索的时候,我们使用adcode作为keywords传入;
- subdistrict可以指定子级行政区的嵌套层数;
- 当最外层的districts超过20个元素时,需要配合page参数来获取全部元素;
- 只有extensions配置为all时,接口才会返回我们需要的区域边界数据。
想要一次性采集全国省市区行政边界数据的话,第1步肯定是先设法拿到省、市、区的列表,然后逐个遍历。
我们可以设置keywords为"中华人民共和国",然后将subdistrict设置为3,下3层(省、市、区)的子行政区信息就会返回。
这样,我们发送1次请求就可以拿到省、市、区的列表了。
接着,我们将subdistrict调整为1(减少数据冗余),依次遍历各个行政区域即可。
实现代码如下:
# -*- coding:utf-8 -*-import requests
import time
import mongo_util #自行封装的操作mongodb的工具类def get_district_info(key, col, time_delay, headers={}):request_url = 'https://restapi.amap.com/v3/config/district'country_name = '中华人民共和国'params = {'subdistrict':'3','extensions':'all','key':key,'output':'json','keywords':country_name,}# 设置subdistrict为3,1次请求获取到国、省、市、区的信息country_res = requests.get(url=request_url, headers=headers, params=params).json()if country_res['status'] != "1":print("调用高德地图Web API失败!")returncountry = country_res['districts'][0]col.insert_one(country)print(f'{country_name}数据插入成功!')params['subdistrict'] = '1'# 遍历省provinces = country['districts']for province in provinces:province_name = province['name']params['keywords'] = province['adcode']prov_res = requests.get(url=request_url, headers=headers, params=params).json()if prov_res['status'] == "0":print(f'{country_name}-{province_name}数据获取失败!')continuecol.insert_one(prov_res['districts'][0])print(f'{country_name}-{province_name}数据插入成功!')time.sleep(time_delay)# 遍历市cities = province['districts']if len(cities) == 0:continuefor city in cities:city_name = city['name']params['keywords'] = city['adcode']city_res = requests.get(url=request_url, headers=headers, params=params).json()if city_res['status'] == "0":print(f'{country_name}-{province_name}-{city_name}数据获取失败!')continuecol.insert_one(city_res['districts'][0])print(f'{country_name}-{province_name}-{city_name}数据插入成功!')time.sleep(time_delay)# 遍历区districts = city['districts']if len(districts) == 0:continuefor district in districts:distinct_name = district['name']params['keywords'] = district['adcode']distinct_res = requests.get(url=request_url, headers=headers, params=params).json()if distinct_res['status'] == "0":print(f'{country_name}-{province_name}-{city_name}-{distinct_name}数据获取失败!')continuecol.insert_one(distinct_res['districts'][0])print(f'{country_name}-{province_name}-{city_name}-{distinct_name}数据插入成功!')time.sleep(time_delay)
# 主函数
if __name__ == '__main__':key = "******"# 接口请求之间的间隔time_delay = 0.01db_name = 'web_map'col_name = 'distinct'# MongoDB数据库所在的服务器host = '******'port = 27017# 获取mongodb的表句柄col = mongo_util.get_col(db_name, col_name, host, port)# 获取全国各级行政区的数据get_district_info(key, col, time_delay)
因为接口返回的是JSON类型的嵌套数据,所以这里选择MongoDB作为存储组件。
为了防止爬取过程中,进程宕掉导致已请求的数据丢失,可以拿到1条数据就入库1条数据。
避免数据全都在内存中,执行批量插入的过程中异常退出,又得重复请求,但每个账号的天请求次数是有限制的。
同时,各个接口均有QPS阈值,所以我们通过time_delay参数来控制数据采集的频率。
但是高德开方平台Web服务API有天调用次数的限制,如果想获取大量数据,可能需要多个账号或者分多天进行请求,有没有更好的方法呢?
带着这样的疑问,我又看了看高德地图其他的API版块。
JS API
浏览高德开放平台的JS API示例,里面也有个行政区边界查询的Demo。
https://lbs.amap.com/demo/jsapi-v2/example/district-search/draw-district-boundaries
打开浏览器的"开发者工具",我们抓包一下哪个请求是用来获取行政区域数据的。
哈哈哈,其实跟开放的Web API接口地址是一致的,而且通过分析接口请求,我们直接可以拿到key。
也就是说,不需要用自己高德账号里生成的key值了。
使用这个key构建接口请求,悲伤的发现,接口返回异常。
说明该接口其实还是跟开放的Web API接口还是有区别的,一般体现在请求参数和Headers上。
我们把浏览器抓取到的请求参数和Headers配置原封不动的拷贝过来,再次构建接口请求,此时接口正常返回。
但请求参数里的csid是个啥东西,而且不同行政区域请求里的csid还不同。
尝试着去掉该参数,然后构建接口请求,发现接口仍然可以正常返回,说明该参数是可选参数,而且不是检索字段。
按照这个思路,我们逐步尝试去掉其他请求参数和Headers里的配置。
发现该接口与开放的Web API接口相比,本质仅有2点不同:
- 请求参数
请求参数需要额外指定: s=rsv3
- Headers
需要添加如下Headers:
调整原来的代码:
- 在params里增加s配置
params = {'subdistrict':'3','extensions':'all','key':key,'output':'json','keywords':country_name,'s':'rsv3' # 该项配置是关键配置
}
- 在发送请求的时候传入headers
headers = {'Host': 'restapi.amap.com','Referer': 'https://lbs.amap.com/'
}
# 获取mongodb的表句柄
col = mongo_util.get_col(db_name, col_name, host, port)
# 获取全国各级行政区的数据
get_district_info(key, col, time_delay, headers)
该种方法的优点是绕开了第1种方法的日调用次数限制(高德是否有额外的反爬策略,待验证)。
AMAP Service
其实前面headrs的Referer配置就提醒我了,是不是高德地图在https://lbs.amap.com/这个地址下也有功能相同的接口。
所以就在高德平台上随意点了点,逛了逛,还真就发现了,哈哈哈。
与上面两个接口不同的是,这个接口是POST请求,而且竟然不需要指定key,这也太爽了吧,哈哈哈。
接着看一下请求参数:
参数和开放平台Web服务API的完全一致。
最后看一下表单数据:
显然表单数据是用来配置请求哪个接口的,这里的config/district代表的就是行政区域查询。
代码调整起来也不难:
# 调整请求的url
request_url = 'https://lbs.amap.com/service/api/restapi'
# 将所有的请求调整为POST,并传入表单数据,例如:
body = {"type": "config/district","version": "v3"}
country_res = requests.post(url=request_url, params=params, data=body).json()
该接口跟第2种接口相比,更近一步,连key值都省略了。
总结
本文介绍了3种基于高德地图获取全国省市区行政边界数据的方法。
获取到数据之后,可以进一步处理。
比如: 我使用pyshp包将采集到的数据转换成了shp文件,然后可以在GIS软件里进行可视化编辑。
也可以再爬取各个行政区的人口、GDP等数据,制作人口热力图等,这里不再赘述,读者可自行实践。
如何获取全国省市区行政边界数据相关推荐
- 免费下载:全国各级别行政边界数据下载
之前做项目,直至找不到合适的行政边界数据,最近找到一个小网站GaoHR | 中国国家基础地理信息(GIS)数据,给需要的小伙伴参考使用.也特别感谢作者@GIS大饼,给我们提供了这么宝贵的数据,提供的数 ...
- 实时最新中国省市区县geoJSON格式地图行政边界数据Echarts地图数据(可精确到街道级)
geojson 数据下载地址:https://hxkj.vip/demo/echartsMap/ 可下载的数据包含省级geojson行政边界数据.市级geojson行政边界数据.区/县级geojson ...
- Ajax怎么获取天气,Ajax获取全国天气预报的API数据
这次给大家带来Ajax获取全国天气预报的API数据,Ajax获取全国天气预报API数据的注意事项有哪些,下面就是实战案例,一起来看一下. 预览图(比较简单粗糙) 聚合数据全国天气预报接口:https: ...
- Python 一键获取全国市县级行政单元Shapefile文件
之前的博客中介绍到利用区县级shp转市级shp的方法Arcgis制作全国行政区(精确到县级),但实际操作起来还是比较麻烦的,并且部分省份没有BOUA文件.今天,分享另外一个方法,利用Python迅速获 ...
- 获取全国地铁线站口数据(Python+百度API)
使用场景 工作中需要及时更新全量线站口数据 ~~~ 研究城市地铁分布和数据 ~~~ 整体方案 地铁线站:高德地铁页面获取全国地铁线.站数据.百度也有地铁页面,但是百度的比较难抓取. 高德地图 | 地 ...
- 在线获取全国省市区信息
省 http://datavmap-public.oss-cn-hangzhou.aliyuncs.com/areas/csv/100000_province.json 市(130000 河北省) h ...
- echarts——实现地图——获取全国+各省市的数据js——基础积累
前几天写了一篇关于 echarts实现地图的博文,关于全国+各省市的数据js的获取,下面做一下记录. 1.阿里云获取地图数据的网址 阿里云获取全国+各省市数据js的链接:http://datav.al ...
- Echarts+高德地图,获取全国省市区,区域板块地图获取并高亮显示
当用户选择省市区之后,可以看到对应区域的高亮显示. 如图: 之前用户选择的是江苏省,因此当前高亮显示的是江苏省地图板块,如果之前用户选择的是成都市,那么地图则会变成四川省的版图,高亮显示成都市,如下图 ...
- 省市区管理sql数据表设计、以及全国省市区全部最新数据
使用Mysql数据库,主要字段有: 区域主键.区域名称.区域上级标识.地名简称.区域等级.区域编码.邮政编码.组合名称.经度.维度.拼音, 其页面展示效果图如下: 建表sql为: CREATE TAB ...
- 全球行政边界数据(shp格式)
数据地址 直接下载china的数据,其他区域的数据对应也是有的. shp转geojson网址链接 导入数据,按照你需要的截取数据,修改.删除数据. select features选择想要下载的区域 然 ...
最新文章
- 中国最懂自动驾驶量产公司秀肌肉:自动驾驶算力怪兽、百亿参数云端超大模型、百万公里路测里程...
- 面试必问的16个经典问题的回答思路
- 几个机器学习算法及应用领域相关的中国大牛
- Mac环境下Redis的安装与配置
- 四川师范学院C语言实验报告,C语言【四川师范大学文理学院吧】_百度贴吧
- 在tomcat上部署项目需要打成jar_Spring Boot Web 项目教程,SpringBoot与传统Web 优缺对比...
- Android 4.4 KitKat, the browser and the Chrome WebView
- ux和ui_UI和UX设计师的10种软技能
- c语言编程图形并颜色,C语言图形编程(三、绘图函数1)
- 大数据的价值体现在哪几个方面,大数据领域未来的技术方向是什么?
- C. Remove Adjacent
- “仅三天可见” 的朋友圈有方法破解啦!
- python绘制三维地形_三维数字场地模型(上篇):Civil3D 地形的生成
- matlab矩阵旋转
- 软件测试笔记(十六)- 缺陷轰炸和beta测试
- Eclipse优化速度
- 哈哈,又找到几个强大的html5+css3的动画效果
- 音乐是我们日常生活中不可缺少的
- 非接触式IC卡、条码卡、磁道卡、接触式IC卡、芯片卡
- osg中NDC坐标转换为世界坐标
热门文章
- Matlab 移动通信原理-扩频通信系统仿真实验(扩频通信系统的多用户数据传输、利用蒙特卡罗仿真方法对扩频增益进行性能仿真)
- 人工智能的变革趋势: 从弱人工智能到强人工智能,再到生物智能
- windows服务器虚拟机 全屏,虚拟机安装Windowsxp系统后无法全屏的解决方法
- 13. 用hexdump工具分析镜像的16进制代码
- QT on Android的rtsp播放器demo
- 简单游戏(easygame)
- koa2 mysql项目教程_blogs: Node.js + Koa2 + MySQL + Vue.js 实战开发一套完整个人博客项目网站...
- matlab确定物体影子,用MATLAB浅析太阳影子定位问题
- 数学建模论文分析--2015A高教社杯--太阳影子定位的多目标优化模型
- 深入浅出Mysql 读书笔记