百度地圖獲得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()

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