目前高德的边界没法批量爬取,不过可以采用百度地图的接口来替代,目前用着还可以,参见这里:

为了方便大家,不用再为安装环境,以及运行报错等问题困扰,目前已经将POI数据爬取做成一个在线公开的数工具,地址奉上:

免费使用哦,只需要申请个高德key,然后选择需要爬取的城市,关键字名,以及数据的坐标系,即可将数据导出到本地,无需运行任何代码。

欢迎加入地图数据爬取交流群:626697156

背景

由于之前项目需要从高德地图上爬取一个地方的不同分类数据,所以初学了一下爬虫,也了解了一些高德地图提供的web API用来获取免费的地图数据。因此写了一篇博客用来记录一下大致步骤。

项目的需求是爬取一个地方的七个分类数据, 包括大学、景点、酒店等等,其中一条数据叫作一个POI。需要的poi点的字段包括:poi点id、名称name、位置(经纬度)location、所属省名称pname、所属省编号pcode、所属城市名称cityname、所属城市编号citycode、所属区名称adname、所属区编号adcode、所在地址address、所属类别type、边界经纬度。这里先展示一下最后爬取到的保存在excel表格中的数据吧。

步骤说明

1. 申请账号

到高德开放平台 | 高德地图API注册账号,并且申请web服务的AK密钥,每次发送请求需要带着这个key去认证。注册账号登陆后点击右上角的控制台 ->应用管理 -> 创建应用 -> 添加新key,注意选择web api,就得到了一个可以使用web服务的key密钥。

2. 确定api查询的地址:

查找高德地图提供的web api下的搜索模块,http://lbs.amap.com/api/webservice/guide/api/search 使用关键字搜索服务,关键字搜索API的服务地址:

http://restapi.amap.com/v3/place/text?parameters

我们需要根据API提供的参数说明拼接GET请求所需要的参数URL。常用的使用参数说明:

key

用户在高德地图官网申请Web服务API类型KEY

keywords

查询关键字

types

查询POI类型

city

城市

offset,page

分页参数

output

返回数据格式类型,可选值:JSON,XML

比如,查询珠海的所有大学数据,拼接起来完整的url:

http://restapi.amap.com/v3/place/text?&keywords=%E5%A4%A7%E5%AD%A6&city=%E7%8F%A0%E6%B5%B7&output=json&offset=20&page=1&key=9f99fc570ccaf6abc209780433d9f4c1&extensions=all

使用浏览器打开上面的链接,返回的数据使用hijson格式化后截图如下:

其中的pois展开后就是返回的当前页的POI数据。

3. 根据获取到的POI数据的id获取其边界经纬度

高德地图上搜索一个景点时,如果有边界的景点会圈出其范围,如下图所示:

打开F12切换到network查看,点击一下该范围,会看到发送了一个detail请求,返回了这个圈的详细信息。请求的地址如下:

https://ditu.amap.com/detail/get/detail?id=B0014014AD

该接口传入POI点的id,返回详细信息,我们在第二部拿到了POI点的ID,因此可以遍历每一个POI数据,然后根据id获取边界数据,获取到的detail数据格式化后如下:

标红的shape数据即为边界坐标数据(一个多边形的边界其实是由多个点围成的)。

解析数据

具体代码

getpois方法传入需要的城市名和分类关键字,最后将数据导出到d盘目录下excel文件中:

运行代码前须知:

需要将代码前面的amap_web_key的值替换为第一步中申请到的web api的密钥。

需要启动爬取程序时,需要修改getpois()方法的两个参数值(代码的后部分),cityname为城市名,classfield为分类名,分类可以查看官方文档。

由于高德地图每个key每天的请求量有限额,并且请求评率太快的话会返回错误信息,因此建议最好每天不要爬太多,而且不要集中在一个时间点。

from urllib.parse import quote

from urllib import request

import json

import xlwt

amap_web_key = '你申请的密钥'

poi_search_url = "http://restapi.amap.com/v3/place/text"

poi_boundary_url = "https://ditu.amap.com/detail/get/detail"

#根据城市名称和分类关键字获取poi数据

def getpois(cityname, keywords):

i = 1

poilist = []

while True : #使用while循环不断分页获取数据

result = getpoi_page(cityname, keywords, i)

result = json.loads(result) # 将字符串转换为json

if result['count'] == '0':

break

poilist.extend(result['pois'])

i = i + 1

return poilist

#数据写入excel

def write_to_excel(poilist, cityname, classfield):

# 一个Workbook对象,这就相当于创建了一个Excel文件

book = xlwt.Workbook(encoding='utf-8', style_compression=0)

sheet = book.add_sheet(classfield, cell_overwrite_ok=True)

#第一行(列标题)

sheet.write(0, 0, 'id')

sheet.write(0, 1, 'name')

sheet.write(0, 2, 'location')

sheet.write(0, 3, 'pname')

sheet.write(0, 4, 'pcode')

sheet.write(0, 5, 'cityname')

sheet.write(0, 6, 'citycode')

sheet.write(0, 7, 'adname')

sheet.write(0, 8, 'adcode')

sheet.write(0, 9, 'address')

sheet.write(0, 10, 'type')

sheet.write(0, 11, 'boundary')

for i in range(len(poilist)):

# 根据poi的id获取边界数据

bounstr =''

bounlist = getBounById(poilist[i]['id'])

if(len(bounlist) > 1):

bounstr = str(bounlist)

#每一行写入

sheet.write(i + 1, 0, poilist[i]['id'])

sheet.write(i + 1, 1, poilist[i]['name'])

sheet.write(i + 1, 2, poilist[i]['location'])

sheet.write(i + 1, 3, poilist[i]['pname'])

sheet.write(i + 1, 4, poilist[i]['pcode'])

sheet.write(i + 1, 5, poilist[i]['cityname'])

sheet.write(i + 1, 6, poilist[i]['citycode'])

sheet.write(i + 1, 7, poilist[i]['adname'])

sheet.write(i + 1, 8, poilist[i]['adcode'])

sheet.write(i + 1, 9, poilist[i]['address'])

sheet.write(i + 1, 10, poilist[i]['type'])

sheet.write(i + 1, 11, bounstr)

# 最后,将以上操作保存到指定的Excel文件中

book.save(r'd:\\' + cityname +'.xls')

#单页获取pois

def getpoi_page(cityname, keywords, page):

req_url = poi_search_url + "?key=" + amap_web_key + '&extensions=all&keywords=' + quote(keywords) + '&city=' + quote(cityname) + '&citylimit=true' + '&offset=25' + '&page=' + str(page) + '&output=json'

data = ''

with request.urlopen(req_url) as f:

data = f.read()

data = data.decode('utf-8')

return data

#根据id获取边界数据

def getBounById (id):

req_url = poi_boundary_url + "?id=" + id

with request.urlopen(req_url) as f:

data = f.read()

data = data.decode('utf-8')

dataList = []

datajson = json.loads(data) # 将字符串转换为json

datajson = datajson['data']

datajson = datajson['spec']

if len(datajson) == 1:

return dataList

if datajson.get('mining_shape') != None:

datajson = datajson['mining_shape']

shape = datajson['shape']

dataArr = shape.split(';')

for i in dataArr:

innerList = []

f1 = float(i.split(',')[0])

innerList.append(float(i.split(',')[0]))

innerList.append(float(i.split(',')[1]))

dataList.append(innerList)

return dataList

#获取城市分类数据

cityname = "珠海"

classfiled = "大学"

pois = getpois(cityname, classfiled)

#将数据写入excel

write_to_excel(pois, cityname, classfiled)

print('写入成功')

#根据获取到的poi数据的id获取边界数据

#dataList = getBounById('B02F4027LY')

#print(type(dataList))

#print(str(dataList))

'''

返回的边界数据格式--方便高德地图前端展示

[[113.559199, 22.239364], [113.559693, 22.238274], [113.55677, 22.237162],

[113.557008, 22.236653], [113.555582, 22.236117], [113.555747, 22.235742],

[113.555163, 22.235538], [113.555027, 22.235831], [113.554934, 22.235875],

[113.554088, 22.235522], [113.553919, 22.235885], [113.553905, 22.235961],

[113.556167, 22.236835], [113.55561, 22.238172], [113.55494, 22.237933],

[113.554607, 22.238652], [113.554593, 22.238697], [113.554597, 22.238765],

[113.554614, 22.238834], [113.554646, 22.238885], [113.558612, 22.240406],

[113.558799, 22.240258], [113.559199, 22.239364]]

'''

由于在很多情况下,只需要爬取POI点的中心坐标就行了,因此这里也提供了直接获取分类数据中心点坐标的代码,下面是爬去出来的成果截图:

运行代码之前,需要安装xlutils库,代码如下:

from urllib.parse import quote

from urllib import request

import json

import xlwt

amap_web_key = '你申请的web服务的密钥'

poi_search_url = "http://restapi.amap.com/v3/place/text"

poi_boundary_url = "https://ditu.amap.com/detail/get/detail"

#TODO 需要爬取的POI所属的城市名,以及分类名. (中文名或者代码都可以,代码详见高德地图的POI分类编码表)

cityname = "珠海"

classfiled = "大学"

# 根据城市名称和分类关键字获取poi数据

def getpois(cityname, keywords):

i = 1

poilist = []

while True: # 使用while循环不断分页获取数据

result = getpoi_page(cityname, keywords, i)

print(result)

result = json.loads(result) # 将字符串转换为json

if result['count'] == '0':

break

hand(poilist, result)

i = i + 1

return poilist

# 数据写入excel

def write_to_excel(poilist, cityname, classfield):

# 一个Workbook对象,这就相当于创建了一个Excel文件

book = xlwt.Workbook(encoding='utf-8', style_compression=0)

sheet = book.add_sheet(classfield, cell_overwrite_ok=True)

# 第一行(列标题)

sheet.write(0, 0, 'id')

sheet.write(0, 1, 'name')

sheet.write(0, 2, 'location')

sheet.write(0, 3, 'pname')

sheet.write(0, 4, 'pcode')

sheet.write(0, 5, 'cityname')

sheet.write(0, 6, 'citycode')

sheet.write(0, 7, 'adname')

sheet.write(0, 8, 'adcode')

sheet.write(0, 9, 'address')

sheet.write(0, 10, 'type')

sheet.write(0, 11, 'typecode')

sheet.write(0, 12, 'gridcode')

sheet.write(0, 13, 'entr_location')

sheet.write(0, 14, 'timestamp')

sheet.write(0, 15, 'tel')

sheet.write(0, 16, 'postcode')

sheet.write(0, 17, 'tag')

sheet.write(1, 18, 'shopid')

sheet.write(1, 19, 'shopinfo')

for i in range(len(poilist)):

# 每一行写入

sheet.write(i + 1, 0, poilist[i]['id'])

sheet.write(i + 1, 1, poilist[i]['name'])

sheet.write(i + 1, 2, poilist[i]['location'])

sheet.write(i + 1, 3, poilist[i]['pname'])

sheet.write(i + 1, 4, poilist[i]['pcode'])

sheet.write(i + 1, 5, poilist[i]['cityname'])

sheet.write(i + 1, 6, poilist[i]['citycode'])

sheet.write(i + 1, 7, poilist[i]['adname'])

sheet.write(i + 1, 8, poilist[i]['adcode'])

sheet.write(i + 1, 9, poilist[i]['address'])

sheet.write(i + 1, 10, poilist[i]['type'])

sheet.write(i + 1, 11, poilist[i]['typecode'])

sheet.write(i + 1, 12, poilist[i]['gridcode'])

sheet.write(i + 1, 13, poilist[i]['entr_location'])

sheet.write(i + 1, 14, poilist[i]['timestamp'])

sheet.write(i + 1, 15, poilist[i]['tel'])

sheet.write(i + 1, 16, poilist[i]['postcode'])

sheet.write(i + 1, 17, poilist[i]['tag'])

sheet.write(i + 1, 18, poilist[i]['shopid'])

sheet.write(i + 1, 19, poilist[i]['shopinfo'])

# 最后,将以上操作保存到指定的Excel文件中

book.save(r'' + cityname + "_" + classfield + '.xls')

# 将返回的poi数据装入集合返回

def hand(poilist, result):

# result = json.loads(result) # 将字符串转换为json

pois = result['pois']

for i in range(len(pois)):

poilist.append(pois[i])

# 单页获取pois

def getpoi_page(cityname, keywords, page):

req_url = poi_search_url + "?key=" + amap_web_key + '&extensions=all&keywords=' + quote(

keywords) + '&city=' + quote(cityname) + '&citylimit=true' + '&offset=25' + '&page=' + str(

page) + '&output=json'

data = ''

with request.urlopen(req_url) as f:

data = f.read()

data = data.decode('utf-8')

return data

# 获取城市分类数据

pois = getpois(cityname, classfiled)

# 将数据写入excel

write_to_excel(pois, cityname, classfiled)

print('写入成功')

在后面代码中,会将爬取的POI数据写入EXCEL中,EXCEL存放文件为当前目录,文件名为 cityname_classfiled.xls,例如珠海_大学.xls。

附录:

python爬取高德poi数据_高德地图之python爬取POI数据及其边界经纬度相关推荐

  1. python爬取地图数据_高德3地图之python爬取POI数据及其边界经纬度(根据关键字在城市范围内搜索)...

    目前高德的边界没法批量爬取,不过可以采用百度地图的接口来替代,目前用着还可以,参见这里: 为了方便大家,不用再为安装环境,以及运行报错等问题困扰,目前已经将POI数据爬取做成一个在线公开的数工具,地址 ...

  2. python爬取大众点评数据_利用Node.js制作爬取大众点评的爬虫

    前言 Node.js天生支持并发,但是对于习惯了顺序编程的人,一开始会对Node.js不适应,比如,变量作用域是函数块式的(与C.Java不一样):for循环体({})内引用i的值实际上是循环结束之后 ...

  3. python爬取拼多多爆款数据_利用风变Python快速爬取海量数据,写出10万+爆文

    我是从事自媒体内容创作者,每天都用心创作,保证文章质量,然后希望能出爆文,但似乎事情没有那么简单--自己认为可以的内容和标题但推送出去后,展示量和阅读量都低得可怜,心想,每次都这么用心,但结果却这样, ...

  4. 利用python爬取知乎评论_一个简单的python爬虫,爬取知乎

    一个简单的python爬虫,爬取知乎 主要实现 爬取一个收藏夹 里 所有问题答案下的 图片 文字信息暂未收录,可自行实现,比图片更简单 具体代码里有详细注释,请自行阅读 项目源码: 1 # -*- c ...

  5. 高德地图巡航异步加载数据_“高德地图”和“百度地图”的差别

    高德地图"和"百度地图"到底有什么差别?专家:细节定成败! 导读:高德和百度都是做电子地图的,很多人很好奇,高德地图和百度地图的区别是什么.除了开发者不同,两者在数据和功 ...

  6. python怎么帮助运营 进行数据管理_注意!这里手把手教你做数据运营管理

    对于企业的IT人员来说,最痛苦的事情莫过于面对业务的各种各样的需求,IT人员要在繁忙的开发任务中抽时间来做数据分析,而业务和领导则需要等很久才能拿到数据.重复的工作太多,一旦数据.需求都上涨,将承受更 ...

  7. mysql分组取出每组地一条数据_基于mysql实现group by取各分组最新一条数据

    基于mysql实现group by取各分组最新一条数据 前言: group by函数后取到的是分组中的第一条数据,但是我们有时候需要取出各分组的最新一条,该怎么实现呢? 本文提供两种实现方式. 一.准 ...

  8. python与数据分析的课程报告_【最新】python数据分析课程报告论文(附代码数据)...

    用python进行数据分析 一.样本集 本样本集来源于某高中某班78位同学的一次月考的语文成绩.因为每位同学的成绩都是独立的随机变量,遂可以保证得到的观测值也是独立且随机的 样本如下: grades= ...

  9. python向es写入大量数据_使用Python-elasticsearch-bulk批量快速向elasticsearch插入数据_李谦的博客-CSDN博客...

    from elasticsearch import Elasticsearch from elasticsearch import helpers import pymysql import time ...

  10. python获取同花顺数据_开启量化第一步!同花顺iFinD数据接口免费版简易操作教程...

    金融市场波动频繁,投资往往会夹杂非理性的情绪.而量化交易,旨在以先进的数学模型替代人为的主观判断,利用计算机技术从庞大的历史数据中海选能带来超额收益的多种"大概率"事件以制定策略, ...

最新文章

  1. Rocksdb 通过posix_advise 让内核减少在page_cache的预读
  2. .NET Core 使用Dapper 操作MySQL
  3. Pytorch和Numpy的默认类型
  4. java基础 第一章上(安装 配置java、简单dos命令)
  5. java只修改变的字段_修改Java中的最终字段
  6. idea输出目录详解
  7. Linux的系统程序包管理
  8. 新浪微博开发者平台应用申请及配置说明
  9. 时间序列分析的计量经济学方法 - Python中的序列性ARIMA
  10. 2021-2025年中国共享Web托管服务行业市场供需与战略研究报告
  11. 初创企业及中小型企业财务特点以及建议
  12. 黑苹果万能驱动神器 Hackintool 3.8.4中文版
  13. R:数据分析-----汽车数据可视化
  14. java播放音频文件mp3
  15. cdoj1087 基爷的中位数 二分
  16. 亲测有效:Steam 上的 Mountain 游戏设置为壁纸的方法
  17. NFC模块方案,轻松实现NFC通讯
  18. 《Cocos Creator游戏实战》游戏转场时如何保留节点信息
  19. java中子类会继承父类的构造方法吗
  20. Java实现伪查询(全匹配+模糊匹配)

热门文章

  1. sigar取得进程信息
  2. 最新国民经济行业分类sql文件
  3. 海思Hi3519AV100sensor移植之二-- imx586 sensor
  4. 数据分析侠A的成长故事
  5. linux下vmlinuz到vmlinux的转换
  6. STM32 FOC5.2电机库中中的电流采样改为反向放大
  7. SQL如何删除重复数据
  8. 写给自己的CDSN账号
  9. 随身助手271个可用api接口网站php源码(随身助手API)
  10. Windows装机必备软件大全,全部支持Vista系统