我们研究生的课程内容,做下笔记记录一下。

使用的python环境是python3.7

用的图大部分都是老师ppt里的图,懒得自己截了……

申请百度开发者密匙

(1)注册百度用户,注册过的话,直接登录就可以。登录地址为百度地图开放平台

(2)登录后,在控制台点击【创建应用】。

(3)填写表单,创建应用

(4)这样就得到了API Key了

百度地图搜索API语法

poi查询的基本url为http://api.map.baidu.com/place/v2/search?

按矩形框坐标范围检索

有如下参数

参数名 参数含义 类型 是否必须
query 检索关键字,周边检索和矩形区域检索
支持多关键字(以$隔开)并集检索,最多支持10个。
string(45) Y
bounds 设置查询的坐标范围
矩形框的左下角经纬度和右上角经纬度。
string(50) Y
output 输出格式为json或xml string(50) Y
scope 检索结果的详细程度
取值为1或空,返回基本信息;取值2,返回详细信息
string(50) N
page_size 页面显示POI数量,默认值为10条,最大值为20 int N
page_num 分页页码,从0开始 int N
coord_type 坐标类型
1:WGS84即GPS经纬度坐标
2:国家测绘局GCJ-02坐标
3:bd09,即百度经纬度坐标
4:bd09mc即百度米坐标
int N
ret_coordtype 返回国测局经纬度坐标 string(50) N
ak 开发者访问密钥(刚刚申请的API KEY) string(50) Y

关于上面这个bounds的值,可以使用百度地图自己提供的坐标拾取器获得。也可以通过别人写的一个网页获得具体的行政区矩形框。

别人写的网页的html如下

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";}
#panel{
position:absolute;
left:5px;
top:5px;
}
#result{
background: #fff;
padding:5px;
}
</style>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=1XjLLEhZhQNUzd93EjU5nOGQ"></script>
<title>添加行政区划</title>
</head>
<body>
<div id="allmap"></div>
<div id="panel">
<div>
<input type="text" id="keyword" value="昆明市"/>
<input type="button" value="查看范围" id="commitBtn"/>
边界经纬度坐标
<textarea id="pathStr"></textarea>
边界墨卡托坐标
<textarea id="pathMc"></textarea>
</div>
<div id="result">
</div>
</div>
</body>
</html>
<script type="text/javascript">
// 百度地图API功能
var map = new BMap.Map("allmap");
map.centerAndZoom(new BMap.Point(116.403765, 39.914850), 5);
map.enableScrollWheelZoom();
var mercatorProjection = map.getMapType().getProjection();
$("#commitBtn").bind('click', function(){
getBoundary($("#keyword").val());
});
function getBoundary(city){
var bdary = new BMap.Boundary();
bdary.get(city, function(rs){ //获取行政区域
map.clearOverlays(); //清除地图覆盖物
var count = rs.boundaries.length; //行政区域的点有多少个
if (count === 0) {
alert('未能获取当前输入行政区域');
return ;
}
var pointArray = [];
for (var i = 0; i < count; i++) {
var ply = new BMap.Polygon(rs.boundaries[i], {strokeWeight: 2, strokeColor: "#ff0000"}); //建立多边形覆盖物
map.addOverlay(ply); //添加覆盖物
pointArray = pointArray.concat(ply.getPath());
}
var pathStr = "";
var pathMc = "";
for (var i = 0; i < pointArray.length; i++) { var mc = mercatorProjection.lngLatToPoint(pointArray[i]);
pathStr += pointArray[i].lng + "," + pointArray[i].lat + ";";
pathMc += mc.x + "," + mc.y + ";";
}
$('#pathStr').html(pathStr);
$('#pathMc').html(pathMc);
var ply = new BMap.Polygon(pointArray , {strokeWeight: 2, strokeColor: "#ff0000"}); //建立多边形覆盖物
var bounds = ply.getBounds();
var ne = bounds.getNorthEast();
var sw = bounds.getSouthWest();
var neMc = mercatorProjection.lngLatToPoint(ne);
var swMc = mercatorProjection.lngLatToPoint(sw);
var str = "经纬度:左下角,右上角:" + sw.lng + "," + sw.lat + ";" + ne.lng + "," + ne.lat
+ "<br/>墨卡托坐标:左下角,右上角:" + swMc.x + "," + swMc.y + ";" + neMc.x + "," + neMc.y;
$('#result').html(str);
console.log(bounds);
map.setViewport(pointArray); //调整视野
});
}
//getBoundary('北京');
</script>

打开后,类似这样

按城市检索

刚刚说的是按bound检索。也可以使用region参数按城市检索,比如说

http://api.map.baidu.com/place/v2/search?query=公园&region=武昌区&output=json&ak=xxxxxxxxx&page_size=20&page_num=0

周边检索

使用location参数(设置中心点坐标)和radius参数(设置半径)进行周边检索。比如说

http://api.map.baidu.com/place/v2/search?query=酒店&location=30.531642,114.366409&radius=300&output=json&ak=xxxxxxxxxx&page_size=20&page_num=0

返回内容

返回的内容,status为状态(0为成功返回,其他为异常),message为提示信息,total为返回的poi数量,results为当前页的poi信息。

{
"status":0,
"message":"ok",
"total":57,
"results":[]
}

一般scope为1的poi信息如下

 {
"name":"四美塘",
"location":{
"lat":30.603315,
"lng":114.344284
},
"address":"武汉市武昌区和平大道589号(长江二桥下)",
"province":"湖北省",
"city":"武汉市",
"area":"武昌区",
"street_id":"15a93810075519bd15c8f6b4",
"detail":1,
"uid":"f21f49135aad2a3ce856fad9"
}

一般scope为2的poi信息如下

{
"name":"四美塘",
"location":{
"lat":30.603315,
"lng":114.344284
},
"address":"武汉市武昌区和平大道589号(长江二桥下)",
"province":"湖北省",
"city":"武汉市",
"area":"武昌区",
"street_id":"15a93810075519bd15c8f6b4",
"detail":1,
"uid":"f21f49135aad2a3ce856fad9"
"detail_info":{
"tag":"旅游景点;公园",
"navi_location":{
"lng":114.34584347395,
"lat":30.604976470638
},
"type":"scope",
"detail_url":"http://api.map.baidu.com/place/detail?uid=f21f49135aad2a3ce856fad9&output=html&source=placeapi_v2",
"overall_rating":"4.3",
"comment_num":"14",
"children":[ ]
}
}

百度地图POI搜索爬虫设计

由于百度地图限制每次返回的poi最多只有400个,所以我们要把矩形区域进行分割以获得更多的数据。

具体实现的代码如下

def splitArea(bound):
# 分割矩形区域的函数
boundList=[]
row_num = 2 # 按照 2 X 2 进行分割
bound=list(map(float,bound.split(',')))
step_lat = (bound[2] - bound[0]) / row_num
step_lon = (bound[3] - bound[1]) / row_num
for i in range(0,row_num):
for j in range(0,row_num):
boundTemp = []
boundTemp.append(bound[0]+step_lat*i)
boundTemp.append(bound[1]+step_lon*j)
boundTemp.append(bound[0]+step_lat*(i+1))
boundTemp.append(bound[1]+step_lon*(j+1))
boundTemp=",".join(["%s" %x for x in boundTemp])
boundList.append(boundTemp)
return boundList

课后作业完成

题目如下:

寻找武汉市中学(或小学)周围500米(或其他)内的网吧

要求:提交代码py文件及运行结果文件(txt),txt文件格式如下:

1,XXX小学

1-1,XXX网吧

1-2, XXX网吧

2,XXX小学

2-1,XXX网吧

2-2, XXX网吧

………..

写的python3代码为

# coding:utf-8
# version:python3.7
# author:Ivy ############# 程序功能 ####################
# 本程序用来获取百度地图某城市某种poi周围一定范围内的另一种类型的poi数据
# 如示例是获取武汉市中学周围500米内的网吧
# 生成的info.txt格式如下
# 1, xxx中学
# 1-1, xxx网吧
# 1-2, xxx网吧
# 2, xxx中学
# 2-1, xxx网吧
############################################ import requests,json
import time,sys ############### 自主设置区 ###############
ak = 'xxxxxxxxx' #API key
keyword="中学"
keyword2="网吧"
radius=500
city="武汉市"
baseBound = '29.972898,113.707695,31.367052,115.085775' #武汉市矩形框的左下角经纬度和右上角经纬度
############################################ # 构造header
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36',
'Accept-Encoding':'gzip, deflate',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
'Host': 'api.map.baidu.com',
'Upgrade-Insecure-Requests': '1',
'Connection': 'keep-alive',
'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
'DNT': '1'
} baseUrl="http://api.map.baidu.com/place/v2/search?query={}&bounds={}&page_size=20&page_num={}&output=json&ak={}"
searchBaseUrl="http://api.map.baidu.com/place/v2/search?query={}&location={}&radius={}&output=json&ak={}&page_size=20&page_num={}" def req(url):
# 访问url获取返回的数据读取为json
errorNum=0
while True:
try:
res = requests.get(url,headers=headers)
res.encoding='utf-8'
jd = json.loads(res.text)
return jd
except Exception as e:
errorNum+=1
print("出错了!")
print(e)
if errorNum==5:
sys.exit(1)
time.sleep(1) def splitArea(bound):
# 分割矩形区域的函数
boundList=[]
row_num = 2 # 按照 2 X 2 进行分割
bound=list(map(float,bound.split(',')))
step_lat = (bound[2] - bound[0]) / row_num
step_lon = (bound[3] - bound[1]) / row_num
for i in range(0,row_num):
for j in range(0,row_num):
boundTemp = []
boundTemp.append(bound[0]+step_lat*i)
boundTemp.append(bound[1]+step_lon*j)
boundTemp.append(bound[0]+step_lat*(i+1))
boundTemp.append(bound[1]+step_lon*(j+1))
boundTemp=",".join(["%s" %x for x in boundTemp])
# 是否要继续分割
if check(boundTemp):
boundList.append(boundTemp)
else:
boundList+=splitArea(boundTemp)
return boundList def check(bound):
# 检查一下当前矩形框是否需要再次分割
checkUrl=baseUrl.format(keyword,bound,0,ak)
checkJd=req(checkUrl)
if checkJd["total"]<400:
return True
return False def getPois(bound):
# 获取一定范围内所有的想要的poi的信息
poiListTemp=[]
pageNum=0
while True:
getUrl=baseUrl.format(keyword,bound,pageNum,ak)
getJd=req(getUrl)
if getJd['results']==[]: # 如果这一页没数据了就是结束啦,退出循环
break
for result in getJd['results']:
if result["city"] != city: # 在矩形框中,但是不是想要的城市的,就不要记录啦
continue
poiListTemp.append(result)
pageNum+=1
print("当前区域{}的poi已爬完,共有{}个".format(bound,len(poiListTemp)))
return poiListTemp def searchPois(poiInfo):
# 获取某个poi周边的其他poi信息
poiListTemp=[]
pageNum=0
while True:
searchUrl=searchBaseUrl.format(keyword2,str(poiInfo['location']['lat'])+','+str(poiInfo['location']['lng']),radius,ak,pageNum)
searchJd=req(searchUrl)
if searchJd['results']==[]:
break
for result in searchJd['results']:
poiListTemp.append(result["name"])
print(result["name"]," 已添加")
pageNum+=1
print(poiInfo["name"],"周边poi已爬完")
return [poiInfo["name"],poiListTemp] if __name__ == '__main__':
# 分割想要的区域
boundList=splitArea(baseBound)
print(boundList) # 获取范围内所有的poi信息
poiList=[]
for bound in boundList:
poiList+=getPois(bound)
print('已获得所有poi信息') # 对于获取到的每个poi进行周边检索
infoList=[]
for poi in poiList:
infoList.append(searchPois(poi))
print('已获得所有周边poi信息') # 把获取到的信息都写入txt
with open('info.txt','w') as f:
for i in range(len(infoList)):
f.write(str(i+1)+', '+infoList[i][0]+'\n')
for j in range(len(infoList[i][1])):
f.write(str(i+1)+'-'+str(j+1)+', '+infoList[i][1][j]+'\n')
print("所获得的信息已全部写入txt啦!")

【参考】

[1]我们老师的PPT(不便公开)

百度地图POI爬取的更多相关文章

  1. 百度地图POI数据爬取,突破百度地图API爬取数目“400条“的限制11。

    1.POI爬取方法说明 1.1AK申请 登录百度账号,在百度地图开发者平台的API控制台申请一个服务端的ak,主要用到的是Place API.检校方式可设置成IP白名单,IP直接设置成了0.0.0.0 ...

  2. 高德地图POI爬取_Python

    高德地图POI 官方文档:https://lbs.amap.com/api/webservice/guide/api/search#introduce 官网控制台:https://lbs.amap.c ...

  3. 教你如何拔取百度地图POI兴趣点

    教你如何拔取百度地图POI兴趣点   通过聚合数据提供的接口,获取百度地图的POI兴趣点,并存储至数据库中. 实现: 1.聚合数据百度POI接口说明 调用聚合数据,首先得注册聚合.聚合数据提供的百度地 ...

  4. 基于 Golang 完整获取百度地图POI数据的方案

    百度地图为web开发者提供了基于HTTP/HTTPS协议的丰富接口,其中包括地点检索服务,web开发者通过此接口可以检索区域内的POI数据.百度地图处于数据保护对接口做了限制,每次访问服务,最多只能检 ...

  5. 获取百度地图POI数据三(模拟关键词搜索)

    上一篇博文中讲到如何获取用于搜索的关键词,并且已经准备好了一百五十万的关键词   这其中有门牌号码,餐馆酒店名称,公司名称,道路名称等.有了这些数据,我们就可以通过代码,模拟我们在百度地图的搜索框中搜 ...

  6. 获取百度地图POI数据二(准备搜索关键词)

    上篇讲到  想要获取尽可能多的POI数据 需要准备尽可能多的搜索关键字   那么这些关键字如何得来呢?   本人使用的方法是通过一些网站来获取这些关键词   http://poi.mapbar.com ...

  7. 第三百三十四节,web爬虫讲解2—Scrapy框架爬虫—Scrapy爬取百度新闻,爬取Ajax动态生成的信息

    第三百三十四节,web爬虫讲解2—Scrapy框架爬虫—Scrapy爬取百度新闻,爬取Ajax动态生成的信息 crapy爬取百度新闻,爬取Ajax动态生成的信息,抓取百度新闻首页的新闻rul地址 有多 ...

  8. 十三 web爬虫讲解2—Scrapy框架爬虫—Scrapy爬取百度新闻,爬取Ajax动态生成的信息

    crapy爬取百度新闻,爬取Ajax动态生成的信息,抓取百度新闻首页的新闻rul地址 有多网站,当你浏览器访问时看到的信息,在html源文件里却找不到,由得信息还是滚动条滚动到对应的位置后才显示信息, ...

  9. iOS地图集成示例:百度地图POI检索

    一.集成百度地图(傻瓜教程,以网站说明文档为准,此处罗列几项主要步骤) 1.登录  http://lbsyun.baidu.com  百度地图开发者平台,获取SDK和集成文档. 2.百度地图可以提供的 ...

随机推荐

  1. vi 纵向模式编辑

    Vim 的纵向编辑模式 vim解读 vi解读 批量删除# 技巧: r 进入修改模式 I 进入行首插入模式 A 进入行尾插入模式 r替换 I前前添加 A后添加 1.多行注释: a. 按下Ctrl + v ...

  2. Django学习系列13:Django ORM和第一个模型

    ORM—对象关系映射器,是一个数据抽象层,描述存储在数据库中的表,行和列.处理数据库时,可以使用熟悉的面向对象方式,写出更好的代码. 在ORM的概念中,类对应数据库中的表,属性对应列,类的单个实例表示 ...

  3. 关于order_by

  4. Spring Boot整合拦截器

    过滤器和监听器都属于Servlet 的api,还可以使用 Spring 提供的拦截器(HandlerInterceptor)进行改更精细的控制.

  5. 安装nodejs与使用

    nodejs 官方下载地址:https://nodejs.org/en/ 下载完成后,双击打开安装程序 然后: 然后点击install,等待安装 安装完成后的目录如下: 检测是否真的安装成功.打开cm ...

  6. Web API接口规范与测试方法

    目录 1.Web API接口 1.1接口的四大特点 1.2接口文档的编写:YApi 1.3接口测试工具:Postman 2.接口规范(restful) 2.1URL设计 2.1.1 数据的安全保障(h ...

  7. CSS定位——浮动定位

    CSS定位机制Ⅱ——浮动定位 float属性:进行浮动定位   left,right clear属性:清除浮动   left,right,both  ㈠  float属性 1.概述 ⑴div实现横向多 ...

  8. PHP 下载+安装

    1.官网下载 官网地址:http://PHP.net/ 地址:http://download.csdn.NET/detail/anndy_/9494632 官网手册:https://secure.ph ...

  9. [转载]深入理解iostat

    深入理解iostat 前言 iostat算是比较重要的查看块设备运行状态的工具,相信大多数使用Linux的同学都用过这个工具,或者听说过这个工具.但是对于这个工具,引起的误解也是最多的,大多数人对这个 ...

  10. [VIJOS2053][SDOI2019]世界地图:最小生成树+虚树

    分析 可以发现第一列和最后一列永远不会被删除,于是我们可以想到维护前后缀最小生成树,但是直接维护的话显然时间空间两爆炸.(通过上网找题解)可以发现我们关心的只是最左边和最右边两列,而不关心内部的连边情 ...