任务前提
做该项目之前,首先得有基础知识:
编程语言:python
编译工具:PyCharm
网络爬虫相关知识,xpath库,numpy,pandas等库。

任务准备:
去百度地图开放平台申请密匙:http://lbsyun.baidu.com/
步骤:
登录----->控制台----->注册登录成为开发者(已成为则跳过该步骤)----->创建应用------>填写应用名称----->应用类型选择浏览器端---->refer白名单输入“*”—>创建应用成功----->得到密匙(AK)

我的密匙:************************************

任务目的:
爬取西安市各种兴趣点的POI数据(以西安市所有中学为例)

选取方法:由于我们需要爬取西安市所有兴趣点,区域较大,数据较多,我们采用矩形区域检索来进行,具体可参考:http://lbs.baidu.com/index.php?title=webapi/guide/webservice-placeapi 来进行选择。

爬取关键字:城市:西安(以西安经纬度来表示)兴趣点:中学(其他兴趣点同理)
西安市经纬度范围:

西安市 经度 纬度
左下角 107.671067 33.699374
右上角 109.82715 34.746103

URL模板:
http://api.map.baidu.com/place/v2/search?query=中学& bounds=33.699374,107.671067,34.746103,109.82715&page_size=20&page_num=0&output=json&ak=9toMp2Wls5la******************88fiX (此处填写自己申请的AK)

功能详解:
其实调用百度地图API来爬取没什么难度,基本都是静态页面,和爬取普通的静态页面没什么区别,都是以下几个步骤:
第一步:构建需要访问的URL
第二步:构建请求头(防止反爬手段有很多:伪造UA,代理IP,多进程延迟爬取等)
第三步:访问URL,获取数据
第四步:解析网页数据(xpath,bs4,lxml等)
第五步:存储数据(存入excel,数据库等)

通过调用百度地图API,爬取西安市所有数据,也是通过以上步骤完成的,唯一需要注意的就是我们构造目的URL时根据区域来构建URL的,但是每个URL所爬取到的数据有限,所以我们需要对区域进行合理的划分,来构造跟多的目的URL,这样才能爬取到更多的API数据。有几种不同的方法,圆形区域分割,矩形区域分割等,具体参考官方文档:http://lbs.baidu.com/index.php?title=webapi/guide/webservice-placeapi

因为由于百度的限制每一个区域只有20个url,即page_num从0–19,每一个url最多只有20条数据,所以哪怕该区域有成千上万条数据,最多只能获得400条数据,因此我们要用bound对应区域的经纬度进行网格划分,将西安市通过经纬度进行划分,为了计算简便,我们就切成正方形。(类似于数学中的微分思想)
坐标范围:
西安市经纬度:
左下角:107.671067,33.699374 右上角:109.82715,34.746103
lat_1 = 33.699374 ; lat_2 = 34.746103 ;lon_1 = 107.671067 ; lon_2 = 109.82715
纬度差:lat_2 - lat_1 = 1.046729
经度差:lon_2 - lon_1 = 2.156083
设切割的小正方形的边长为:las;则lat_count = int((lat_2 - lat_1) / las)+1计算的是在纬度上能够分割出多少个小正方形;lon_count = int((lon_2 - lon_1) / las )+1计算的是在经度上能够分割出多少个小正方形;二者乘积就是总共能够分割出多少个小正方形。为了简便计算,取las值为1
编写代码获取每一个小正方形的坐标范围:
代码如下:

lat_1=33.699374
lon_1=107.671067
lat_2=34.746103
lon_2=109.82715   #坐标范围
las=1  #给las一个值1
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_cprint(str(lat_b1)+','+str(lon_b1)+','+str(lat_b1+las)+','+str(lon_b1+las))#这段代码生成的是小正方形的范围坐标运行结果:
33.699374,107.671067,34.699374,108.671067
33.699374,108.671067,34.699374,109.671067
33.699374,109.671067,34.699374,110.671067
34.699374,107.671067,35.699374,108.671067
34.699374,108.671067,35.699374,109.671067
34.699374,109.671067,35.699374,110.671067

由以上结果看出,可以分为六个小正方形,当然要想更加精细,可以缩小las的值,使划分的区域更小。
待访问的URL由参数bounds和page_num决定,page_num取值为range(0,20)。

具体参考代码如下:

import requests
import time
from urllib.parse import urlencode
import csv"""
要想爬取所有兴趣点的信息,对下面代码稍加修改,将所有兴趣点列为一个列表,然后keyeord从列表中遍历获取来构造URL即可,即增加一层循环
若要将该区域分割的更加细致,则修改las的值,值越小,分的越细
改进方案:由于每个密匙访问次数有限,可以使用代理池加上多进程来进行爬取大量数据
"""'''计算纬度上能分割几次'''
def get_lat_count(lat_2,lat_1,las):lat_count = int((lat_2 - lat_1) / las + 1)return lat_count'''计算经度上能分割几次'''
def get_lon_count(lon_2,lon_1,las):lon_count = int((lon_2 - lon_1) / las + 1)return lon_count'''计算每个分区的经纬度'''
def get_latLonList(lat_2,lat_1,lon_2,lon_1,las):'''得到所有小正方形的经纬度范围:param lat_2:右上纬度:param lat_1:左下纬度:param lon_2:右上经度:param lon_1:左下经度:param las:一个分割正方形的边长:return:latLonList:含有所有小正方形的经纬度列表。'''lat_count = get_lat_count(lat_2,lat_1,las)lon_count = get_lon_count(lon_2,lon_1,las)latLonList = []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_clat_lon = str(lat_b1) + ',' + str(lon_b1) + ',' + str(lat_b1 + las) + ',' + str(lon_b1 + las)latLonList.append(lat_lon)return latLonList'''拼接url'''
def get_urlList(oldurl,keyword,lat_2,lat_1,lon_2,lon_1,las):''':param oldurl: 不完整的url:param keyword: 兴趣点:param lat_2:右上纬度:param lat_1:左下纬度:param lon_2:右上经度:param lon_1:左下经度:param las:一个分割正方形的边长:return: list'''latLonList = get_latLonList(lat_2,lat_1,lon_2,lon_1,las)urlList = []for bounds in latLonList:for num in range(0,1):     #此处修改为(0,20)就是每个url爬取20页parameter = {"query":keyword,"bounds": bounds,"page_size": 20,"page_num": num,"output":'json',"ak": ak}data = urlencode(parameter)url = oldurl + dataurlList.append(url)return urlList'''爬取数据'''
def getDataFromHtml():'''# 示例数据:{'name': '周至中学', 'location': {'lat': 34.168176, 'lng': 108.248956}, 'address': '陕西省西安市周至县五合村一零八国道北', 'province': '陕西省', 'city': '西安市', 'area': '周至县', 'telephone': '(029)87161124', 'detail': 1, 'uid': '593850fb6bcfc45dde1e52b0'}:return: list'''urlList = get_urlList(oldurl=oldurl, keyword=keyword, lat_2=lat_2, lat_1=lat_1, lon_2=lon_2, lon_1=lon_1, las=las)# for i in urlList:#     print(i)# print(len(urlList))json_data_list = []for url in urlList:response = requests.get(url=url)json_data = response.json()# 去重if json_data not in json_data_list:json_data_list.append(json_data)time.sleep(10)# print(json_data_list)result_dict = []for data in json_data_list:if data['results']:for result in data['results']:result_dict.append(result)return result_dict'''将数据写入excel'''
def export_excel(result_dict):with open('西安所有中学.csv','a',encoding='utf8') as f:for mydict in result_dict:w = csv.DictWriter(f, mydict.keys())w.writerow(mydict)def main():result_dict = getDataFromHtml()# 将分析完成的列表导出为csvexport_excel(result_dict)if __name__ == "__main__":lat_1=33.699374lon_1=107.671067lat_2=34.746103lon_2=109.82715   #坐标范围las=1  #给las一个值1oldurl = "http://api.map.baidu.com/place/v2/search?"ak = '9toMp2Wls5la**************fiX' #自己申请的AKkeyword = '中学'main()

最后具体爬取到的数据如下,数据量过大,此处展示部分截图:

python调用百度地图API爬取西安市POI数据相关推荐

  1. 【Python】 调用百度地图API抓取西安市小区信息

    前面有同学参加市场调查大赛,需要西安市的小区信息数据,一个小爬虫程序完美解决. 百度地图开放平台 详情访问:百度PlaceAPI 这里用到了矩形区域检索,具体参数说明如下: 调取详情 所需库: imp ...

  2. Python调用百度地图api路径查询

    通过调用百度地图api获取两个地点的距离和时间.参数详见百度地图api官方文档. # -*- coding: utf-8 -*- """ Created on Thu M ...

  3. python 调用百度地图api 实现批量经纬度转换为实际省市地点(api调用,json解析,mysql读取与写入)

    1.获取秘钥 调用百度地图API实现得申请百度账号或者登陆百度账号,然后申请自己的ak秘钥.链接如下:添加链接描述 下面是百度创建的app设置: 2.调用API将经纬度信息解析成json信息 def ...

  4. [Python]调用百度地图API对地点进行搜索,利用 JSON 返回纬度/行政区域编号

    1.创建百度API应用 类似爬虫程序,在百度地图API进行注册 在此处点击控制台,在应用管理------我的应用处 创建自己的应用. 创建应用如图所示,在请求校验方式处选择sn校验方式 记住自己的AK ...

  5. python爬取地图上的经纬度_Python调用百度地图API爬取经纬度

    作者:国服帅座  经济学在读硕士 微信公众号:统计之家 你吃肯德基,我点麦当劳.本是替代品,却众口难调.每个人都有独特的偏好,都有一份要坚守的情怀.高德与百度,你心仪哪款呢? 认识百度地图API 百度 ...

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

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

  7. python调用百度地图API 实现单点沿线轨迹运动

    百度地图API 可以做很多好玩的事情,自己闲来无事,先是照着一些资料做了热力图,然后借助pyqt5做了一个简单的界面,实现gps单点沿线(行车)的轨迹. 先上程序界面和效果图: 过程:1. 申请百度地 ...

  8. 百度地图API爬取不同类型POI的详细数据

    一.相关概念 查询某个范围内的所有POI 参数介绍: page_size:单次查询返回的POI的数量,最大值为20 page_num:查找的POI数量超过20时,会分页显示:比如60个POI就会分3页 ...

  9. python调用百度地图API批量查询全国高速收费站点经纬度

    写在前面 大家好,我是饭都吃不起的南南 昨天帮朋友爬了全国的高速站点收费站这里下载 [http://www.bestunion.cn/gaosu/p_4/sfzlist.html] 由于该网站并没有西 ...

最新文章

  1. java数据输入的步骤_Java学习日志1.4 Scanner 数据输入的三种方法
  2. mysqldump 和 sql命令导入sql文件
  3. 记住:永远不要在MySQL中使用UTF-8
  4. socketio mysql_socket.io 在java与微信小程序上的应用
  5. code block下使用openMP
  6. 阿里云云计算 9 弹性裸金属服务器(神龙)
  7. 百度网盘之我的应用数据文件夹删除(保姆版)
  8. 如何破解“仅三天可见”的朋友圈?
  9. WTL的CBitmapButton在MFC下完美使用
  10. Test meeting 11.23
  11. 学计算机独显重要吗,“集显”、“独显”对于普通电脑用户来说还那么重要吗?...
  12. php微信支付扫码源码下载,微信支付:扫码支付+APP支付
  13. nexmo 验证码的使用
  14. 77.组合 | 40.组合总和II | 39.组合总和 | 784.字母大小写全排列
  15. 类型BYTE,WORD与DWORD
  16. js实现仿微信红包随机分配
  17. Android APK反编译及逆向工程
  18. 【解决方案】SkeyeVSS煤矿安全生产监管视频监控系统,夯实煤矿生产安全防线
  19. Multisim交通信号灯简易控制器
  20. Public Key Retrieval is not allowed解决

热门文章

  1. 断网后parsec无法检测发现台式机设备的解决办法
  2. adobe cs5 indesign 不显示文本框_Adobe CS5 InDesign自动添加页码
  3. 什么是PCB加工中树脂塞孔工艺?
  4. 奇异值分解及几何意义
  5. OpenGL Android 安卓 入门 GLES20 初学者 初级 官方
  6. React使用className多类名设置
  7. JS、阻止 a 标签的默认点击事件,阻止默认的所有事件
  8. 中秋前瞻,原来这个季节采收的白茶最好喝!
  9. 波兰式与逆波兰式的转换和表达式求值
  10. STM32 FreeRTOS (三) 软件定时器