关于爬虫系列,前三篇文章分别讲了三个简单案例,分别爬取了《你好,李焕英》电影豆瓣热门短评58同城在售楼盘房源信息以及安居客网二手房小区详情页数据。通过前三个案例,相信大家都对爬虫有了简单了解和运用,对于大部分网站来说呢,爬虫的基本流程都相差不多,主要区别在于解析网站标签的xpath语句不同,俗话说得好,熟能生巧,多去尝试爬取不同网站,慢慢地就会熟练使用了。

这篇文章呢,主要来谈一谈如何利用Python调用百度地图API接口,将研究区域看成是一个矩形,以固定经纬度间隔划分网格,爬取百度地图上的兴趣点(Point of interest),获取的字段主要包括名称、纬度、经度、详细地址、省份、市以及区7个字段。 对于有些知识点,比如百度地图的APK密钥注册等,网上各大博客都有很好的讲解,这里我会放上参考链接,小伙伴们各取所需,本文重点主要放在POI数据爬取的代码上。好了,废话不多说,开始走起~

1. 在百度地图开放平台注册,获取AK密钥

在爬取POI数据之前,必须先在百度地图开放平台上完成注册拿到AK密钥,才能调用百度地图的API接口,关于这部分本文不作过多的详解,具体可以参考如下博客:

参考资料:零基础掌握百度地图兴趣点获取POI爬虫(python语言爬取)(基础篇)

2. 获取石家庄市大致范围的经纬度

由于我们将研究范围看作是一个矩形,必然需要矩形的四个夹角经纬度,也就是说只要得到左下角和右上角经纬度,就可以大致知道地图所在位置。那么如何获取到左下角和右上角经纬度呢?在这篇博客零基础掌握百度地图兴趣点获取POI爬虫(python语言爬取)(进阶篇)中提及到一种方法,代码已经编好,只需将下面代码复制粘贴到txt文件中,然后修改文件后缀名为.html即可。

<!DOCTYPE html>
<html>
<head>  <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />  <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>

用本地浏览器打开这个html网页,输入研究的省市即可显示左下角和右上角经纬度,具体操作看下图:

所以我们可以得出:

lat_1 = 37.444122 # 石家庄市左下纬度
lon_1 = 113.529103 # 新石家庄市左下经度
lat_2 = 38.768031 # 石家庄市右上纬度
lon_2 = 115.486183 # 石家庄市右上经度

3. 获取URL

URL = "http://api.map.baidu.com/place/v2/search?query=政府& bounds=37.973948,114.382523,38.17371,114.714494&page_size=20&page_num=0&output=json&ak=xxxxx"

URL的各参数含义:① query:表示检索的POI类型;② bounds:采用矩形分割,依次分别为小网格的左下角纬度、左下角经度、右上角纬度、右上角经度;③ page_size:每页所能获取的最大记录数;④ page_num:页数;⑤ output:返回的是json数据;⑥ ak:从百度地图注册平台上申请到的密钥;

具体的参数详解,可以看下这篇博客:零基础掌握百度地图兴趣点获取POI爬虫(python语言爬取)(代码篇)

4. 爬取百度地图POI数据——代码详解

百度地图给出了两种获取POI的方式,一种是按照行政区域搜索,另一种是按照矩形框搜索

第一种,按行政区划检索POI,受到百度地图api的限制,最多开源读取20页数据,共计400条,所以这种方法比较适用于数量较小的POI爬取,不推荐在大的工程项目中使用。

第二种,按矩形框搜索,通过给定矩形框的左下角和右上角经纬度坐标,结合API进行爬取,爬取所需时间受两方面限制,一种是对于比较密集的POI,比如学校、超市这种,如果想尽可能将数据爬取完整,则需要缩小划分网格的经纬度间隔(las),这样就会增加爬取时间;另一种是,爬取所需时间还与检索的区域大小成正相关,检索区域越大的话,花费的时间就会越长;

(1)基本参数设置

lat_1 = 37.973948 #裕华区左下纬度
lon_1 = 114.382523 #新华区左下经度
lat_2 = 38.17371 #新华右上纬度
lon_2 = 114.714494 #长安区右上经度las = 0.01  # 爬取时划分网格的经纬度间隔
ak='oieDykNvNYpiu7xe3tIuvFZmdfQQB4pt' # 根据自己在百度地图注册平台上申请的AK
place = r'政府' # 爬取的POI类型,可以是学校、政府、超市、商场、小区、餐饮店等等,这里以政府为例

(2)POI区域划分,按照经纬度间隔0.01度,将不同URL存入一个列表中

print ('*******************{}POI开始获取****************'.format(place))
urls=[] #声明一个数组列表
lat_count=int((lat_2-lat_1)/las+1)
lon_count=int((lon_2-lon_1)/las+1)
for lat_c in range(0,lat_count):lat_b1=lat_1+las*lat_cfor lon_c in range(0,lon_count):lon_b1=lon_1+las*lon_cfor i in range(0,20):page_num=str(i)url='http://api.map.baidu.com/place/v2/search?query='+place+'& bounds='+str(lat_b1)+','+str(lon_b1)+','+str(lat_b1+las)+','+str(lon_b1+las)+'&page_size=20&page_num='+str(page_num)+'&output=json&ak='+akurls.append(url)
print ('url列表读取完成')

(3)为了方便看结果,这里设置些参数

total_before = 0
total = 0 # 获取总条数
label = 0 # 查看是否获取到数据的标志
count_20 = 0 # 查看每页超过20条的页数
K = 0 # 运行出错的断点数,代表第多少次循环urls = urls[K:] # 防止出现意外,比如在百度地图获取的数据达到上限,就会终止服务,这里的K主要是为了从当前断点处继续爬取,所以需要根据自己程序终止断点设置;
count_xunhuan = len(urls) # 循环次数
count_xunhuan2 = count_xunhuan # 还剩循环次数,主要让自己知道大概有多少循环,每次都打印下,对程序运行时间有个大致了解;

(4)创建文件以及将爬取到的数据读入文件

f=open(r''+place+'.csv','a',encoding='utf-8') # 根据爬取的POI类型创建文件
print("+++++++++++爬取需循环{}次++++++++++++".format(count_xunhuan))
for url in urls:#time.sleep(10) # 为了防止并发量报警,设置了一个10秒的休眠。认证后就不需要了html = requests.get(url) # 获取网页信息data = html.json() # 获取网页信息的json格式数据total_before = totalfor item in data['results']:jname = item['name'] # 获取名称jlat = item['location']['lat'] # 获取纬度jlon = item['location']['lng'] # 获取经度jadd = item['address'] # 获取详细地址jpro = item['province'] # 获取所在省jcity = item['city'] # 获取所在城市jarea = item['area'] # 获取所在区或县j_str = jname + ',' + str(jlat) + ',' + str(jlon) + ',' + jadd + ',' + jpro + ',' + jcity + ',' + jarea + '\n' # 以逗号格式,将数据存入一个字符串f.write(j_str) # 将数据以行的形式写入CSV文件中total = total + 1 # 获取的数据记录数label = 1 # 表示每个小网格是否爬取到数据,如果为1,则表示获取到数据,执行下面的if语句,如果为0,则表示没有获取到数据;count_xunhuan2 = count_xunhuan2 - 1 # 循环次数减一,方便查看了解循环进度if label == 1:print("需循环{}次, 已循环{}次, 还剩{}次循环结束".format(count_xunhuan, count_xunhuan-count_xunhuan2, count_xunhuan2))print('新增{}条数据'.format(total-total_before))if total-total_before == 20:count_20 = count_20 + 1 # 查看获取到20条数据的页数,因为百度地图限制每页获取20条数据,如果该网格区域超过的话,也是爬取到20条,所以这里设置count_20查看下没有爬取完整的网格数,如果过多,则最好修改las经纬度间隔;print("---------已获取{}条数据----------".format(total))label = 0
print("每页新增超过20条的页数:{}".format(count_20))
f.close()
print ('*****************{}POI获取完成******************'.format(place))

5. 完整代码汇总

关于该案例的完整代码,见下,小伙伴们可以结合我写的注释共同食用;

#-*-coding:UTF-8-*-
import sys
import requests  #导入requests库,这是一个第三方库,把网页上的内容爬下来用的
ty=sys.getfilesystemencoding()  #这个可以获取文件系统的编码形式## 1. 基本参数设置:lat_1 = 37.444122 # 石家庄市左下纬度
lon_1 = 113.529103 # 新石家庄市左下经度
lat_2 = 38.768031 # 石家庄市右上纬度
lon_2 = 115.486183 # 石家庄市右上经度las = 0.01  # 爬取时划分网格的经纬度间隔
ak='xxxxxxxx' # 根据自己在百度地图注册平台上申请的AK
place = r'政府' # 爬取的POI类型,可以是学校、政府、超市、商场、小区、餐饮店等等,这里以政府为例## 2. POI区域划分,按照经纬度间隔0.01度,将不同URL存入一个列表中print ('*******************{}POI开始获取****************'.format(place))
urls=[] #声明一个数组列表
lat_count=int((lat_2-lat_1)/las+1)
lon_count=int((lon_2-lon_1)/las+1)
for lat_c in range(0,lat_count):lat_b1=lat_1+las*lat_cfor lon_c in range(0,lon_count):lon_b1=lon_1+las*lon_cfor i in range(0,20):page_num=str(i)url='http://api.map.baidu.com/place/v2/search?query='+place+'& bounds='+str(lat_b1)+','+str(lon_b1)+','+str(lat_b1+las)+','+str(lon_b1+las)+'&page_size=20&page_num='+str(page_num)+'&output=json&ak='+akurls.append(url)
print ('url列表读取完成')## 3. 为了方便看结果,这里设置了些参数total_before = 0
total = 0 # 获取总条数
label = 0 # 查看是否获取到数据的标志
count_20 = 0 # 查看每页超过20条的页数
K = 0 # 运行出错的断点数,代表第多少次循环urls = urls[K:] # 防止出现意外,比如在百度地图获取的数据达到上限,就会终止服务,这里的K主要是为了从当前断点处继续爬取,所以需要根据自己程序终止断点设置;
count_xunhuan = len(urls) # 循环次数
count_xunhuan2 = count_xunhuan # 还剩循环次数,主要让自己知道大概有多少循环,每次都打印下,对程序运行时间有个大致了解;# 4. 创建文件以及将爬取到的数据读入文件f=open(r''+place+'.csv','a',encoding='utf-8') # 根据爬取的POI类型创建文件
print("+++++++++++爬取需循环{}次++++++++++++".format(count_xunhuan))
for url in urls:#time.sleep(10) # 为了防止并发量报警,设置了一个10秒的休眠。认证后就不需要了html = requests.get(url) # 获取网页信息data = html.json() # 获取网页信息的json格式数据total_before = totalfor item in data['results']: jname = item['name'] # 获取名称jlat = item['location']['lat'] # 获取纬度jlon = item['location']['lng'] # 获取经度jadd = item['address'] # 获取详细地址jpro = item['province'] # 获取所在省jcity = item['city'] # 获取所在城市jarea = item['area'] # 获取所在区或县j_str = jname + ',' + str(jlat) + ',' + str(jlon) + ',' + jadd + ',' + jpro + ',' + jcity + ',' + jarea + '\n' # 以逗号格式,将数据存入一个字符串f.write(j_str) # 将数据以行的形式写入CSV文件中total = total + 1 # 获取的数据记录数label = 1 # 表示每个小网格是否爬取到数据,如果为1,则表示获取到数据,执行下面的if语句,如果为0,则表示没有获取到数据;count_xunhuan2 = count_xunhuan2 - 1 # 循环次数减一,方便查看了解循环进度if label == 1:print("需循环{}次, 已循环{}次, 还剩{}次循环结束".format(count_xunhuan, count_xunhuan-count_xunhuan2, count_xunhuan2))print('新增{}条数据'.format(total-total_before))if total-total_before == 20:count_20 = count_20 + 1 # 查看获取到20条数据的页数,因为百度地图限制每页获取20条数据,如果该网格区域超过的话,也是爬取到20条,所以这里设置count_20查看下没有爬取完整的网格数,如果过多,则最好修改las经纬度间隔;print("---------已获取{}条数据----------".format(total))label = 0
print("每页新增超过20条的页数:{}".format(count_20))
f.close()
print ('*****************{}POI获取完成******************'.format(place))

6. 爬取的数据展示

从百度地图上获取到的POI数据,主要包括以下字段:POI名称、纬度、经度、详细地址、省份、市以及7个字段;数据展示如下:


好了,到这里为止,本文的所有内容就结束了。本文主要利用Python调用百度地图API接口,来爬取POI兴趣点数据,当初做练习的时候获取了政府、小区、餐饮店、KTV、医院、商场、超市、学校、写字楼等等POI数据;总体来说,本文的难度相对来说不大,主要在于理解上,因为这跟之前三篇爬虫案例有一些差别,体现在这次获取的是json格式的文件,不再是之前的html文件了,html网页文件需要通过xpath进行解析,而json文件中得数据都存储在字典中,通过遍历这些字典来获取对应的值;关于json文件中数据的获取,已经在代码里了,小伙伴们不懂得可以多看看代码理解下。

感谢小伙伴们看到这里,如果哪里写的不是很全面的地方,可以在评论区留言哦,我会不断完善的!如果小伙伴们对Python感兴趣的话,可以来波关注,后续还有很多干货呀!

本文的参考资料:

零基础掌握百度地图兴趣点获取POI爬虫(python语言爬取)(基础篇)

零基础掌握百度地图兴趣点获取POI爬虫(python语言爬取)(代码篇)

零基础掌握百度地图兴趣点获取POI爬虫(python语言爬取)(进阶篇)


                          来都来了,确定不留下点什么嘛,嘻嘻~

Python之爬取百度地图兴趣点(POI)数据相关推荐

  1. python爬取地图地址_Python爬取百度地图poi数据 !

    锵锵锵,我来啦.10天过的好快呀,4月份都已经过了三分之一,我的体重还居高不下,qwq.今天给大家分享python爬取百度地图小区的数据,希望大家看后,可以尝试自己编写爬取自己所在市的中学,公园,银行 ...

  2. Python爬取百度地图智慧交通-城市拥堵指数

    第一次写文章 分享一下我的大数据处理课程的一次作业,爬取百度地图智慧交通的城市拥堵指数内容,链接(以长春市为例):http://jiaotong.baidu.com/top/report/?cityc ...

  3. Python爬取百度地图的瓦片图

    Python爬取百度地图的瓦片图 需求 代码 爬虫结果 需求 采用Python + Selenium + phantomJs,自动爬取百度地图的栅格图(瓦片图),支持自定义区域.级别.无文字地图. 去 ...

  4. 爬取百度地图,获取城市楼盘信息

    有任何需要修正的地方请大家私信,评论. 大佬轻喷@-@ 以下是小项目的需求: *爬取百度地图,获取目标城市楼盘信息, *包括目标楼盘的经纬度,名称,并保存在excel文档中. 大家稍微等下,<这 ...

  5. python爬虫代码实例-Python爬虫爬取百度搜索内容代码实例

    这篇文章主要介绍了Python爬虫爬取百度搜索内容代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 搜索引擎用的很频繁,现在利用Python爬 ...

  6. python如何爬取百度云_python如何爬取百度云连接方法指导

    本篇文章主要介绍了python urllib爬取百度云连接的实例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 翻看自己以前写的程序,发现写过一个爬取盘多多百度云资源的东西,完全是当时想看变形 ...

  7. python爬虫爬取百度文档

    使用python爬虫爬取百度文档文字 话不多说,直接上代码! import requests import reheaders = {"User-Agent": "Moz ...

  8. 腾讯地图,百度地图兴趣点(POI)分类关键词表

    1.腾讯地图兴趣点(POI)分类关键词表 腾讯地图POI分类关键词表 序号 一级名称 二级分类 三级分类 完整名称 1 美食 美食 2 中餐厅 美食:中餐厅 3 北京菜 美食:中餐厅:北京菜 4 安徽 ...

  9. python爬虫爬取百度贴吧图片,requests方法

    每天一点点,记录学习 近期爬虫项目,看完请点赞哦---: 1:python 爬取菜鸟教程python100题,百度贴吧图片反爬虫下载,批量下载 2:python爬虫爬取百度贴吧图片,requests方 ...

最新文章

  1. C++ 对象的内存布局(上)
  2. 进程保护 (非Hook;非DKOM)
  3. Java中的内存泄露的几种可能
  4. stc8g1k08程序范例_通过WiFi对STC单片机程序下载和调试
  5. H.264视频编解码的代码移植和优化
  6. 百度,淘宝,腾讯三大巨头HTML页面规范分解
  7. 一摞烙饼最上面一个的另一面为焦的概率
  8. Java 8 Optional类深度解析(转)
  9. 关于linux开机自启
  10. java webserver demo_Java 实现 web服务器的简单实例
  11. 迷你世界甲龙变身机器人_迷你世界X变形金刚双形态皮肤特效,自带双血条,简直无敌...
  12. activity多实例任务加签
  13. Dubbo安装控制台和监控中心
  14. ios addressbook
  15. Linux copy命令 omitting directory
  16. 我被一只老鼠的吱吱声吵醒了
  17. Mac无法识别硬盘解决办法
  18. 花开的地方在希尔的故乡,听着远古的战歌仿佛生在花开的地方
  19. Redis6客户端工具——Jedis
  20. pytorch开发工具

热门文章

  1. 请设计一个既节省时间又节省空间的算法来找出该链表中的倒数第m个元素
  2. 2022年产品经理NPDP考试题型有哪些?须知
  3. 安卓设置菊花动画_这种 “小菊花”式加载动画,会让人觉得等了很久
  4. 《精神健康讲记:一个中医眼中的身心调适与精神发展》阅读笔记 P3-P52
  5. 挣脱PC枷锁,争当互联网主人
  6. python 编写实用小工具-toy: python平时积累的笔记以及编写的小工具
  7. Python+Vue计算机毕业设计旅游管理系统z1fuc(源码+程序+LW+部署)
  8. vue中播放m3u8格式实时监控画面(取流)--调用后端接口
  9. 状态提升(精读React官方文档—10)
  10. 阿里巴巴的阿里云操作系统希望做“中国的Android”