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

使用的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. document.compatMode,quirks mode and standards mode

    Document.compatMode Indicates whether the document is rendered in Quirks mode or Standards mode. Syn ...

  2. 分布式中 CAP BASE ACID 理解(转载)

    概念理解(CAP,BASE, ACID) CAP CAP:  Consistency, Availability, Partition-tolerance 强一致性(Consistency).系统在执 ...

  3. 打包压缩命令tar,zip,split

    1. tar tar的意思是Together ARchive(打包归档).我们可以用来打包,也可以用来解压包,而且还支持打包后用各种格式压缩(gz.bz2.xz等). 单个参数意义:f: 归档file ...

  4. 把自己的web项目发布到网页上

    一.首先,登录自己的bce百度云,bce.baidu.com,建立一个自己的网站 点击左边的应用引擎BAE 点击BAE基础版的部署列表,刚开始是没有的,要添加部署 其中的选项只需要写域名(应用名称会和 ...

  5. 初识容器和Docker

    什么是Docker? Docker 是一个用于开发,交付和运行应用程序的开放平台.能够就应用程序和基础架构分开,从而可以快速的交付软件. 借助Docker可以和管理应用程序的方式来管理基础架构. 使用 ...

  6. 同余&逆元简单总结

    # 同余&逆元 1. 同余 1. 同余的基本概念及性质 若\(x\)%\(m=a\)即m是 x-a 的一个因子, 则称x与a关于m同余,记作:\[x \equiv a(mod \;m)\] 同 ...

  7. Spring Boot 和 Spring Cloud Feign调用服务及传递参数踩坑记录(转)

    https://blog.csdn.net/uotail/article/details/84673347

  8. 22. ClustrixDB 杀掉恶意会话

    ClustrixDB提供了几种机制来识别消耗大量系统资源的查询.这样的查询通常是应用程序索引不良或错误的结果. ClustrixDB支持以下语法来杀死查询: KILL [QUERY | CONNECT ...

  9. 数据库范式以及ER图

    数据库范式包括第一.第二.第三以及BCNF范式,关于范式的探讨,博主在知乎上看见了一篇很不错的文章,分享文中,这边就不再做阐述.地址:https://www.zhihu.com/question/24 ...

  10. ASP net 上传整个文件夹

    HTML部分 <%@PageLanguage="C#"AutoEventWireup="true"CodeBehind="index.aspx. ...