百度地图获得POI及python实现

本文将记录有关利用百度地图API去搜索一个城市内的POI的相关内容

百度地图API

百度地图API服务说明见其主页:

http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding

地址解析:根据地址获取座标

http://api.map.baidu.com/geocoder?address=地址&output=json&key=用户密钥&city=城市名)

它返回的是个json类型数据,一个区域最大返回数为400,每页最大返回数为20

逆地址解析:根据座标获取地址

http://api.map.baidu.com/geocoder?location=纬度,经度&output=输出格式类型&key=用户密钥

根据地址获取POI

http://api.map.baidu.com/place/v2/search?query=%E8%B6%85%E5%B8%82&page_size=0&page_num=2&scope=1&region=%E6%98%8C%E9%BB%8E&output=json&ak=40bUQeFSGGs8c45LHMfe2Ram0hSCKZks

秘钥的申请在百度API的官方网站http://lbsyun.baidu.com/apiconsole/key


秘钥是免费申请的,每天有固定的流量,如果您要使用我的代码,还麻烦您自主申请下秘钥,以免流量用完影响您的使用


在这两个API中有关query类型的选择可以参考http://lbsyun.baidu.com/index.php?title=lbscloud/poitags这个网址内的类别。
接下来需要考虑的就是有关在地图内小方格的选择,参考了一些博文里面提到方格的大小选择是2KM*2KM的大小比较好,我是对一个县城进行搜索,所以将该县城分割为四份或者8份即够了。

整体流程

1 区域划分,2km*2km的区域基本可以满足需求,获取每个区域的对角座标(经纬度),逐行写入一个txt文本里
2 爬虫程序编写 读取1中的txt文本,逐行循环;调用百度API接口,爬取json;将爬取的数据存入数据库中; 每个类别跑一次程序

python实现

#该代码是学习其他博文,在此对其他博主表示感谢
import sys
import requests  #导入requests库,这是一个第三方库,把网页上的内容爬下来用的
ty=sys.getfilesystemencoding()  #这个可以获取文件系统的编码形式
import time

#百度API接口,通过输入经纬度范围查询范围内的POI数据,
#http://lbsyun.baidu.com/index.php?title=lbscloud/poitags 该网址为POI类型,即API链接中的query的类型
base_url='http://api.map.baidu.com/place/v2/search?query={}&bounds={}&page_size=20&page_num={}&output=json&ak=SAKipkD157dL2Mamat8D4FqgxzYz0x7X'

#1.获取每个格网起始URL
def get_begin_url(keyword,page=0):
    with open('E:/贾学斌/格网矩形范围.txt', 'r') as f:
        #网格矩形范围内每一行是一个小方格的经纬度范围,保存顺序为小方格的左下经度纬度、右上经度纬度
        f=f.readlines()
        for line in f:
            w1 = float(line.split(',')[1])
            j1 = float(line.split(',')[0])
            w2 = float(line.split(',')[3])
            j2 = float(line.split(',')[2])
            url2 = base_url.format(keyword, str(w1) + ',' + str(j1) + ',' + str(w2) + ',' + str(j2), str(page))
            yield url2
#2.解析起始URL,请求成功返回json数据
def parse_begin_url(url,keyword):
    print(url)
    html=requests.get(url)
    time.sleep(3)
    if html.status_code==200:
        data = html.json()
        # 每个经纬度的POI数据会只显示前400个,以后不再显示,如果当总数为400时,需要将范围缩小在进行一次搜索
        if 400>data['total']>0:
            print(data['total'])
            page_numbers = int(data['total'] / 20) + 1
            if page_numbers>=1:
                write_to_file(data,keyword)
                time.sleep(3)
                if page_numbers>1:
                    for page in range(1,page_numbers):
                        url2=url.replace('page_num=0','page_num='+str(page))
                        res=requests.get(url2).json()
                        write_to_file(res,keyword)
                        time.sleep(3)
        elif data['total']==400:
            print('区域过大,准备分割')
            urls=get_four_areas(url,keyword)
            for url in urls:
                parse_begin_url(url,keyword)
def get_four_areas(url,keyword):
    #分割的原则是将输入的经纬度范围平均分成四份
    areas=[]
    boundary = url.split('=')[2].split('&')[0].split(',')
    w1=float(boundary[0])
    j1=float(boundary[1])
    w2=float(boundary[2])
    j2=float(boundary[3])
    wei=(float(w2)-float(w1))/2
    jing=(float(j2)-float(j1))/2
    area1=[w1,j1,w1+wei,j1+jing]
    area1=','.join([str(x) for x in area1])
    area2=[w1,j1+jing,w1+wei,j2]
    area2 = ','.join([str(x) for x in area2])
    area3=[w1+wei,j1,w2,j1+jing]
    area3 = ','.join([str(x) for x in area3])
    area4=[w1+wei,j1+jing,w2,j2]
    area4 = ','.join([str(x) for x in area4])
    areas=[area1,area2,area3,area4]
    for index,area in enumerate(areas):
        url=base_url.format(keyword,area,str(0))
        print('第'+str(index+1)+'个分割图形url:'+url)
        yield url


def write_to_file(data,keyword):
    for result in data['results']:
        name = result['name']
        lat = result['location']['lat']
        lng = result['location']['lng']
        address = result['address']
        area=result['area']
        city=result['city']
        province=result["province"]
        detail = result['detail']
        uid = result['uid']

        a = '#'.join([uid, name, address, str(lat), str(lng), str(detail),area,city,province])
        with open('E:/贾学斌/{}.txt'.format(keyword), 'a') as f:
            f.write(a + '\n')
            print('写入成功')
        with open('E:/贾学斌/昌黎县全部POI数据.txt', 'a') as f:
            f.write(a + '\n')
            print('写入成功')


def main():
    keywords = ['百货商场', '超市', '便利店', '商铺', '集市', '通讯营业厅', '邮局', '物流公司', '公用事业', '公园', '风景区', '动物园', '植物园', '游乐园', '文物古迹', '度假村', '农家院', '休闲广场', '高等院校', '中学', '小学', '幼儿园', '特殊教育学校', '综合医院', '专科医院', '诊所', '药店', '飞机场', '火车站', '长途汽车站', '公交车站', '公交线路', '港口', '服务区', '收费站', '银行', '', '信用社', '投资理财', '中央机构', '各级政府', '行政单位', '政治教育机构', '福利机构', '高速公路出口', '高速公路入口', '机场出口', '机场入口', '车站出口', '车站入口', '岛屿', '山峰', '水系']
    for keyword in keywords:
        urls=get_begin_url(keyword)
        for url in urls:
            parse_begin_url(url,keyword)



if __name__=="__main__":
    main()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章