在网上找了很多关于爬取百度POI的文章,但是对“全量”的做法并没有得到最终的解决方案,自己写了一个,但还是不能实现全量POI抓取,能够达到至少50%的信息抓取。
注意:这里所指“全量”是能够达到100%的POI信息获取。
以下是自己写的代码可直接复制粘贴使用,只针对重庆主城区的。

# -*- coding: utf-8 -*-
#-----------------采集全重庆范围内的POI兴趣点-------------------
import requests
import json
import xlrd
import pandas as pd
import pymysql
import time

def sleeptime(day=1): # 默认参数智能放最后
return day * 24 * 3600

def get_Region():
#'重庆市渝中区',
region = ['重庆市渝中区','重庆市江北区','重庆市渝北区','重庆市沙坪坝区','重庆市九龙坡区',
'重庆市南岸区','重庆市巴南区','重庆市北碚区','重庆市大渡口区']

lng_lat = {'重庆市渝中区':'29.525375,106.494032,29.582745,106.602727', #重庆市渝中区的矩形区域左下角和右上角的经纬度(可参看百度文档对矩形区域的解释)
'重庆市江北区':'29.571878,106.440282,29.689841,106.896587', #左下:106.440282,29.571878
'重庆市渝北区':'29.575192,106.434211,30.051651,106.993128', #右上106.993128,30.051651
'重庆市沙坪坝区':'29.497572,106.261671,29.755899,106.51607', #106.275683,29.497572
'重庆市九龙坡区': '29.248442,106.275683,29.574961,106.553261',
'重庆市南岸区':'29.476615,106.542511,29.614757,106.803882',
'重庆市巴南区':'29.118686,106.520931,29.735054,107.062741',
'重庆市北碚区':'29.66131,106.29192,30.109513,106.720972',
'重庆市大渡口区':'29.344094,106.403174,29.509104,106.532859'}

#'重庆市渝中区':'29.525375,106.494032,29.582745,106.602727', #右上 106.597337,29.578724
# '重庆市江北区':'29.571878,106.440282,29.689841,106.896587', #左下:106.440282,29.571878
# '重庆市渝北区':'29.575192,106.434211,30.051651,106.993128', #右上106.993128,30.051651
# '重庆市沙坪坝区':'29.497572,106.261671,29.755899,106.51607', #106.275683,29.497572
#'重庆市九龙坡区':'29.248442,106.275683,29.574961,106.553261'#, #106.275683,29.248442,106.553261,29.574961
# '重庆市南岸区':'29.476615,106.542511,29.614757,106.803882',
# '重庆市巴南区':'29.118686,106.520931,29.735054,107.062741',
# '重庆市北碚区':'29.66131,106.29192,30.109513,106.720972',
# '重庆市大渡口区':'29.344094,106.403174,29.509104,106.532859'}#各行政区左下右上经纬度
return region,lng_lat

#
# 左下角: [29.547183, 106.545379]
# 右上角: [29.5560735, 106.559716]

def get_Keyword():
#path =r'E:\Project\电子围栏\Data\兴趣点.xlsx'
#data = pd.read_excel(path,sheet_name='keyword2')
data = ['酒店','公司']
return data

def get_ak():#改成你自己的ak
ak = ['xYhFWBgDCF12nPU5v2pMue5uN14d****',
'nryXXcwxdwGws64qmB9jFE29yY6P****',
'tP4RTTuWu0Rds81Hvm0Mn9QXajBs****',
'GP12Wh7S1pM1oa4oNyib7xByol5X****']
return ak

def get_Url(data,region,lng_lat,aks,connect):

url_POI = 'http://api.map.baidu.com/place/v2/search?'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36'
}
ak_num = 0
ak = aks[ak_num]
payload = {'output': 'json'}
payload['ak'] = ak
payload['city_limit'] = 'true' #区域数据限制(只返回指定区域的信息)
payload['scope'] = '2' # 返回详细信息,1或空为基本信息
payload['page_size'] = '20' #每一页最多返回20个兴趣点
for i in range(len(region)):
payload['region'] = region[i] #指定行政区域名称
trapeze = lng_lat[region[i]].split(',') #指定行政区的左下右上经纬度 trapeze 经纬度格

#以下是将一个行政区(大矩形)划分为多个矩形网格,获取大于400个兴趣点的返回值
left_bottom = [trapeze[0],trapeze[1]] #左下角坐标
right_top = [trapeze[2],trapeze[3]] #右上角坐标
part_n = 20; #网格切割数量,20*20=400 可根据行政区域的大小调整网格数量

x_item = (float(right_top[0]) - float(left_bottom[0])) / part_n; #纬度平均分割大小
print(x_item)
y_item = (float(right_top[1]) - float(left_bottom[1])) / part_n; #经度平均分割大小
print(y_item)
for key in range(len(data['keyword'])):
payload['query'] = data['keyword'][key] #指定查询关键字
#print(data['keyword'][key])
for ii in range(part_n): # 遍历横向网格
for jj in range(part_n): # 遍历纵向网格
#以下left_bottom_part、right_top_part认真理解
left_bottom_part = [float(left_bottom[0]) + ii * x_item, float(left_bottom[1]) + jj * y_item]; #切片的左下角坐标
right_top_part = [float(right_top[0]) - (part_n-1-ii) * x_item, float(right_top[1]) - (part_n-1-jj) * y_item]; # 切片的右上角坐标
for page_num in range(20): #接口最多返回20页
payload['page_num'] = page_num
payload['bounds']=str(left_bottom_part[0]) + ',' + str(left_bottom_part[1]) + ',' + \
str(right_top_part[0])+','+str(right_top_part[1])
#print(payload)
try:
content = requests.get(url_POI,params=payload,headers=headers).json()
#print(content)
if content['status'] == 0: #能够正常返回值
if content['results']:
storeTomysql(content, data['keyword'][key], connect,region[i])#存放数据库
else:
break
else:
if content['status'] == 302: # 如果ak配额用完
print('第' + str(ak_num) + '个ak配额用完,自动调用下一个····')
ak_num = ak_num+1
if ak_num>(len(aks)-1):
print('今天ak已用完,明天再继续吧。。。')
time.sleep(sleeptime()) #程序休眠24小时
ak_num = 0
ak = aks[ak_num]
payload['ak']=ak
content = requests.get(url_POI, params=payload, headers=headers).json()
if content['status']==0:
if content['results']:
storeTomysql(content,data['keyword'][key],connect,region[i])
else:
break #为空则跳出本层循环
else:pass
else:
ak = aks[ak_num]
payload['ak'] = ak
content = requests.get(url_POI, params=payload, headers=headers).json()
if content['status']==0:
if content['results']:
storeTomysql(content,data['keyword'][key],connect,region[i])
else:
break
else:pass
else:
pass #其他错误
# print(content)

except Exception as e:
print(e)

def mysql_Detail():
# 使用的mysql数据库
connect = pymysql.Connect(host='localhost', port=3306, user='root', passwd='更改为你的密码',
db='addr_trans', charset='utf8')
return connect

def storeTomysql(content,Key_word,connect,region):
#在 content 中提取详细信息
# print('test01')
cursor = connect.cursor()
# if content['results']:
for h in range(len(content['results'])): # 遍历返回地点
name = content['results'][h]['name']
lng = content['results'][h]['location']['lng']
lat = content['results'][h]['location']['lat']

if 'area' in content['results'][h].keys():
area = content['results'][h]['area']
else:
area = None
if 'address' in content['results'][h].keys():
address = content['results'][h]['address']
else:
address = None
if 'province' in content['results'][h].keys():
province = content['results'][h]['province']
else:
province = None
if 'city' in content['results'][h].keys():
city = content['results'][h]['city']
else:
city = None
if 'telephone' in content['results'][h].keys():
telephone = content['results'][h]['telephone']
else:
telephone = None
if 'uid' in content['results'][h].keys():
uid = content['results'][h]['uid']
else:
uid = None
if 'street_id' in content['results'][h].keys():
street_id = content['results'][h]['street_id']
else:
street_id = None
if content['results'][h]['detail'] == 1:
if 'type' in content['results'][h]['detail_info'].keys():
type0 = content['results'][h]['detail_info']['type']
else:
type0 = None
if 'tag' in content['results'][h]['detail_info'].keys():
tag = content['results'][h]['detail_info']['tag']
else:
tag = None
else:
type0 = None
tag = None

if area == region[3:]:#区域相符才存数据
try:
sql = "insert into poi_full(keyword,name0,lng,lat,address,province,city,area,telephone,uid,street_id,type0,tag) " \
"VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')"
data0 = (Key_word,name,lng,lat,address,province,city,area,telephone,uid,street_id,type0,tag)
cursor.execute(sql % data0)
connect.commit()
except Exception as e:
print(e)
else:pass
cursor.close()

if __name__ == "__main__":
aks = get_ak()
keyword = get_Keyword()
region,lng_lat = get_Region()
connect = mysql_Detail()
get_Url(keyword, region, lng_lat,aks,connect)
connect.close()

---------------------
作者:Seven_047
来源:CSDN
原文:https://blog.csdn.net/Seven_047/article/details/81476924
版权声明:本文为博主原创文章,转载请附上博文链接!

python 爬取全量百度POI的更多相关文章

  1. Python 爬取陈都灵百度图片

    Python 爬取陈都灵百度图片 标签(空格分隔): 随笔 今天意外发现了自己以前写的一篇爬虫脚本,爬取的是我的女神陈都灵,尝试运行了一下发现居然还能用.故把脚本贴出来分享一下. import req ...

  2. python 爬取全本免费小说网的小说

    这几天朋友说想看电子书,但是只能在网上看,不能下载到本地后看,问我有啥办法?我找了好几个小说网址看了下,你只能直接在网上看,要下载txt要冲钱买会员,而且还不能在浏览器上直接复制粘贴.之后我就想到py ...

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

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

  4. python爬取某个网页的图片-如百度贴吧

    python爬取某个网页的图片-如百度贴吧 作者:vpoet mail:vpoet_sir@163.com 注:随意copy,不用告诉我 #coding:utf-8 import urllib imp ...

  5. Python 爬取途虎养车 全系车型 轮胎 保养 数据

    Python 爬取途虎养车 全系车型 轮胎 保养 数据 2021.7.27 更新 增加标题.发布时间参数 demo文末自行下载,需要完整数据私聊我 2021.2.19 更新 增加大保养数据 2020. ...

  6. 没有内涵段子可以刷了,利用Python爬取段友之家贴吧图片和小视频(含源码)

    由于最新的视频整顿风波,内涵段子APP被迫关闭,广大段友无家可归,但是最近发现了一个"段友"的app,版本更新也挺快,正在号召广大段友回家,如下图,有兴趣的可以下载看看(ps:我不 ...

  7. python爬取网站数据保存使用的方法

    这篇文章主要介绍了使用Python从网上爬取特定属性数据保存的方法,其中解决了编码问题和如何使用正则匹配数据的方法,详情看下文     编码问题因为涉及到中文,所以必然地涉及到了编码的问题,这一次借这 ...

  8. Python 爬取 热词并进行分类数据分析-[解释修复+热词引用]

    日期:2020.02.02 博客期:141 星期日 [本博客的代码如若要使用,请在下方评论区留言,之后再用(就是跟我说一声)] 所有相关跳转: a.[简单准备] b.[云图制作+数据导入] c.[拓扑 ...

  9. Python爬取微信小程序(Charles)

    Python爬取微信小程序(Charles) 本文链接:https://blog.csdn.net/HeyShHeyou/article/details/90045204 一.前言 最近需要获取微信小 ...

随机推荐

  1. 深入出不来nodejs源码-timer模块(C++篇)

    终于可以填上坑了. 简单回顾一下之前JS篇内容,每一次setTimeout的调用,会在一个对象中添加一个键值对,键为延迟时间,值为一个链表,将所有该时间对应的事件串起来,图如下: 而每一个延迟键值对的 ...

  2. [转]SQL Server 2008 如何配置报表管理器

    本文转自:https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2008/cc281384%28v%3dsql.100%2 ...

  3. [android] fragment的生命周期和通讯

    重写一下生命周期方法 所有的fragment都是依附于activity的,只有当activity显示出来的时候,fragment才能够创建上去 onAttach,当附加到activity上的时候 on ...

  4. [android] 新闻客户端引入SlidingMenu

    下载SlidingMenu,https://github.com/jfeinstein10/SlidingMenu 导入library 我们项目右键==>Properties==>Andr ...

  5. 乐字节-Java8新特性之Stream流(上)

    上一篇文章,小乐给大家介绍了<Java8新特性之方法引用>,下面接下来小乐将会给大家介绍Java8新特性之Stream,称之为流,本篇文章为上半部分. 1.什么是流? Java Se中对于 ...

  6. 【Mysql】mysql和mariadb的区别

    MySQL之父Widenius先生离开了Sun之后,觉得依靠Sun/Oracle来发展MySQL,实在很不靠谱,于是决定另开分支,这个分支的名字叫做MariaDB.MariaDB跟MySQL在绝大多数 ...

  7. java多线程——线程池源码分析(一)

    本文首发于cdream的个人博客,点击获得更好的阅读体验! 欢迎转载,转载请注明出处. 通常应用多线程技术时,我们并不会直接创建一个线程,因为系统启动一个新线程的成本是比较高的,涉及与操作系统的交互, ...

  8. Linux常用基本命令( touch )

    touch命令: 作用:创建空文件,或者改变文件的时间戳属性 格式: touch [option] [file] 1,同时创建一个或者多个空文件 ghostwu@dev:~/linux/mkdir$ ...

  9. 2017萌新的ACM之旅参考代码

    地址:https://vjudge.net/contest/180794#overview A #include <iostream> using namespace std; int m ...

  10. Selenium win7+selenium2.0+python+JetBrains PyCharm环境搭建

    win7+selenium2.0+python+JetBrains PyCharm环境搭建 by:授客 QQ:1033553122 步骤1:下载python 担心最新版的支持不太好,这里我下载的是py ...