Python爬蟲(chóng)實(shí)例_利用百度地圖API批量獲取城市所有的POI點(diǎn)
上篇關(guān)于爬蟲(chóng)的文章,我們講解了如何運(yùn)用Python的requests及BeautifuiSoup模塊來(lái)完成靜態(tài)網(wǎng)頁(yè)的爬取,總結(jié)過(guò)程,網(wǎng)頁(yè)爬蟲(chóng)本質(zhì)就兩步:
1、設(shè)置請(qǐng)求參數(shù)(url,headers,cookies,post或get驗(yàn)證等)訪問(wèn)目標(biāo)站點(diǎn)的服務(wù)器;
2、解析服務(wù)器返回的文檔,提取需要的信息。
而API的工作機(jī)制與爬蟲(chóng)的兩步類似,但也有些許不同:
1、API一般只需要設(shè)置url即可,且請(qǐng)求方式一般為“get”方式
2、API服務(wù)器返回的通常是json或xml格式的數(shù)據(jù),解析更簡(jiǎn)單
也許到這你就明白了,API簡(jiǎn)直就是開(kāi)放的“爬蟲(chóng)”呀,可以告訴你,基本就是這個(gè)意思。好的,言歸正傳,本篇我們就演示如何運(yùn)用Python結(jié)合百度地圖API來(lái)批量獲取POI(興趣點(diǎn))。
所謂POI(興趣點(diǎn)),指的是人們感興趣,比較常去的地方,比如銀行、醫(yī)院、學(xué)校等,利用城市的POI的空間屬性可以做非常多的事情,至于什么事情呢,此處省略10000字。。。
說(shuō)干就干,Let's go!
(1)創(chuàng)建百度地圖應(yīng)用
訪問(wèn)百度地圖API需要一個(gè)信令(AK),打開(kāi)百度地圖開(kāi)放平臺(tái),點(diǎn)擊右上角“API控制臺(tái)”,即進(jìn)入了百度地圖的開(kāi)發(fā)界面。
選擇“創(chuàng)建應(yīng)用”-應(yīng)用類型勾選“瀏覽器端”–勾選所用到的服務(wù)(一般全選即可),此時(shí)就創(chuàng)建好了應(yīng)用賬號(hào),得到“AK”
(2)Place API 及Web服務(wù)API
打開(kāi)百度地圖API的POI模塊,網(wǎng)址:http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-placeapi,這個(gè)頁(yè)面詳細(xì)介紹了Place API的請(qǐng)求參數(shù)及返回?cái)?shù)據(jù)的情況。
可以看到,Place API 提供區(qū)域檢索POI服務(wù)與POI詳情服務(wù)。
1. 區(qū)域檢索POI服務(wù)提供三種區(qū)域檢索方法:
a.城市內(nèi)檢索(對(duì)應(yīng)JavaScriptAPI的Search方法)
b.矩形檢索(對(duì)應(yīng)JavaScript API的SearchInBound方法)
c.圓形區(qū)域檢索(對(duì)應(yīng)JavaScript的SearchNearBy方法)。
2. POI詳情服務(wù)提供查詢單個(gè)POI的詳情信息,如好評(píng)。
并給出了請(qǐng)求的一個(gè)示例,設(shè)置檢索城市為北京,檢索關(guān)鍵字為“飯店”,檢索后返回10條數(shù)據(jù):
http://api.map.baidu.com/place/v2/search?q=飯店®ion=北京&output=json&ak=您的AK
將上述url粘貼到瀏覽器里,返回的數(shù)據(jù)如下:
上圖是將返回的json數(shù)據(jù)解析之后的結(jié)果,可以看到,服務(wù)器返回了10條北京市的飯店的信息,包括飯店名稱、經(jīng)緯度、地址、聯(lián)系電話等。
具體的參數(shù)設(shè)置,自行去該網(wǎng)頁(yè)去看吧,這里就不再贅述,這里我們主要利用“矩形檢索”的方式來(lái)獲取整個(gè)城市的特定POI信息,其url格式如下:
http://api.map.baidu.com/place/v2/search?query=美食&page_size=10&page_num=0&scope=1&bounds=39.915,116.404,39.975,116.414&output=json&ak={您的密鑰}
通過(guò)實(shí)驗(yàn)可以發(fā)現(xiàn),一個(gè)矩陣區(qū)域最多返回400(20*20)個(gè)POI點(diǎn),即page_size = 20 & page_total = 20,雖然官方文檔里說(shuō)一個(gè)區(qū)域返回760+都不成問(wèn)題的,但是測(cè)試了一下,發(fā)現(xiàn)并沒(méi)有這么多,最多400個(gè)。
顯然,整個(gè)城市不可能僅400個(gè)特定描述的POI點(diǎn),所以我們需要對(duì)整個(gè)城市進(jìn)行分片操作,然后每片進(jìn)行訪問(wèn),通過(guò)Python的循環(huán)實(shí)現(xiàn)。
(3)獲取城市特定POI點(diǎn)集合
比如:我們想獲取北京市四環(huán)以內(nèi)所有飯店的信息,即可通過(guò)上述步驟借助Python快速實(shí)現(xiàn),廢話不多說(shuō),直接上代碼:
# -*- coding: utf-8 -*- # Python 2.7 # 提取城市的POI點(diǎn)信息并將其保存至MongoDB數(shù)據(jù)庫(kù) import urllib2 import json from pymongo import MongoClient left_bottom = [116.282387,39.835862]; # 設(shè)置區(qū)域左下角坐標(biāo)(百度坐標(biāo)系) right_top = [116.497405,39.996569]; # 設(shè)置區(qū)域右上角坐標(biāo)(百度坐標(biāo)系) part_n = 2; # 設(shè)置區(qū)域網(wǎng)格(2*2) client = MongoClient('localhost',27001) db = client.transdata db.authenticate("user", "password") col = db.taxi; # 連接集合 url0 = 'http://api.map.baidu.com/place/v2/search?'; x_item = (right_top[0]-left_bottom[0])/part_n; y_item = (right_top[1]-left_bottom[1])/part_n; query = '飯店'; #搜索關(guān)鍵詞設(shè)置 ak = 'xxxxxxxxxxxxxxxxxxxxxx'; #百度地圖api信令 n = 0; # 切片計(jì)數(shù)器 for i in range(part_n): for j in range(part_n): left_bottom_part = [left_bottom[0]+i*x_item,left_bottom[1]+j*y_item]; # 切片的左下角坐標(biāo) right_top_part = [right_top[0]+i*x_item,right_top[1]+j*y_item]; # 切片的右上角坐標(biāo) for k in range(20): url = url0 + 'query=' + query + '&page_size=20&page_num=' + str(k) + '&scope=1&bounds=' + str(left_bottom_part[1]) + ',' + str(left_bottom_part[0]) + ','+str(right_top_part[1]) + ',' + str(right_top_part[0]) + '&output=json&ak=' + ak; data = urllib2.urlopen(url); hjson = json.loads(data.read()); if hjson['message'] == 'ok': results = hjson['results']; for m in range(len(results)): # 提取返回的結(jié)果 col.insert_one(results[m]); n += 1; print '第',str(n),'個(gè)切片入庫(kù)成功'
執(zhí)行為上述代碼,運(yùn)行結(jié)果如下:
可以看到,我們將北京市四環(huán)以內(nèi)區(qū)域分成4個(gè)切片來(lái)進(jìn)行處理,之所以分切片處理,主要是單個(gè)區(qū)域訪問(wèn)最多返回400個(gè)結(jié)果,當(dāng)區(qū)域較大的時(shí)候,區(qū)域內(nèi)往往不止400個(gè),所以講大區(qū)域進(jìn)行切片處理,最后,我們通過(guò)數(shù)據(jù)聚合操作,發(fā)現(xiàn)返回的結(jié)果總共1014個(gè)。(理論上應(yīng)該返回1600,實(shí)際返回1014,說(shuō)明切片的數(shù)量是合適的)
好的,我們本篇的分享到這里就要結(jié)束了,最后只想說(shuō),API真的是個(gè)好東西,科學(xué)地使用它我們可以做出很多炫酷的應(yīng)用,像現(xiàn)在比較活躍的數(shù)據(jù)型應(yīng)用,其數(shù)據(jù)接口基本都是基于API形式的,后面的分享我們還會(huì)用到更多API的,大家一起期待吧,哈哈,今天就到這里了,各位回見(jiàn)。
相關(guān)文章
Collatz 序列、逗號(hào)代碼、字符圖網(wǎng)格實(shí)例
下面小編就為大家?guī)?lái)一篇Collatz 序列、逗號(hào)代碼、字符圖網(wǎng)格實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06Python中交換兩個(gè)元素的實(shí)現(xiàn)方法
今天小編就為大家分享一篇Python中交換兩個(gè)元素的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-06-06Python如何實(shí)現(xiàn)MySQL實(shí)例初始化詳解
這篇文章主要給大家介紹了關(guān)于Python如何實(shí)現(xiàn)MySQL實(shí)例初始化的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11解決python subprocess參數(shù)shell=True踩到的坑
這篇文章主要介紹了解決python subprocess參數(shù)shell=True踩到的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04Python數(shù)據(jù)分析之?Pandas?Dataframe合并和去重操作
這篇文章主要介紹了Python數(shù)據(jù)分析之?Pandas?Dataframe合并和去重操作,文章基于python的相關(guān)資料展開(kāi)詳細(xì)的內(nèi)容介紹,需要的小伙伴可以參考一下2022-05-05Python使用OpenCV和K-Means聚類對(duì)畢業(yè)照進(jìn)行圖像分割
圖像分割是將圖像分割成多個(gè)不同區(qū)域(或片段)的過(guò)程。目標(biāo)是將圖像的表示變成更容易和更有意義的圖像。在這篇博客中,我們?cè)敿?xì)的介紹了使用方法,感興趣的可以了解一下2021-06-06Python處理RSS、ATOM模塊FEEDPARSER介紹
這篇文章主要介紹了Python處理RSS、ATOM模塊FEEDPARSER介紹,本文只是做個(gè)入門(mén)級(jí)的簡(jiǎn)潔介紹,需要的朋友可以參考下2015-02-02Pytorch中如何調(diào)用forward()函數(shù)
這篇文章主要介紹了Pytorch中如何調(diào)用forward()函數(shù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02