Python爬蟲執行個體_利用百度地圖API批量擷取城市所有的POI點,pythonpoi
上篇關於爬蟲的文章,我們講解了如何運用Python的requests及BeautifuiSoup模組來完成靜態網頁的爬取,總結過程,網頁爬蟲本質就兩步:
1、佈建要求參數(url,headers,cookies,post或get驗證等)訪問目標網站的伺服器;
2、解析伺服器返回的文檔,提取需要的資訊。
而API的工作機制與爬蟲的兩步類似,但也有些許不同:
1、API一般只需要設定url即可,且請求方式一般為“get”方式
2、API伺服器返回的通常是json或xml格式的資料,解析更簡單
也許到這你就明白了,API簡直就是開放的“爬蟲”呀,可以告訴你,基本就是這個意思。好的,言歸正傳,本篇我們就示範如何運用Python結合百度地圖API來批量擷取POI(興趣點)。
所謂POI(興趣點),指的是人們感興趣,比較常去的地方,比如銀行、醫院、學校等,利用城市的POI的空間屬性可以做非常多的事情,至於什麼事情呢,此處省略10000字。。。
說幹就幹,Let's go!
(1)建立百度地圖應用
訪問百度地圖API需要一個信令(AK),開啟百度地圖開放平台,點擊右上方“API控制台”,即進入了百度地圖的開發介面。
選擇“建立應用”-應用類型勾選“瀏覽器端”–勾選所用到的服務(一般全選即可),此時就建立好了應用帳號,得到“AK”
(2)Place API 及Web服務API
開啟百度地圖API的POI模組,網址:http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-placeapi,這個頁面詳細介紹了Place API的請求參數及返回資料的情況。
可以看到,Place API 提供地區檢索POI服務與POI詳情服務。
1. 地區檢索POI服務提供三種地區檢索方法:
a.城市內檢索(對應JavaScriptAPI的Search方法)
b.矩形檢索(對應JavaScript API的SearchInBound方法)
c.圓形地區檢索(對應JavaScript的SearchNearBy方法)。
2. POI詳情服務提供查詢單個POI的詳情資訊,如好評。
並給出了請求的一個樣本,設定檢索城市為北京,檢索關鍵字為“飯店”,檢索後返回10條資料:
http://api.map.baidu.com/place/v2/search?q=飯店®ion=北京&output=json&ak=您的AK
將上述url粘貼到瀏覽器裡,返回的資料如下:
是將返回的json資料解析之後的結果,可以看到,伺服器返回了10條北京市的飯店的資訊,包括飯店名稱、經緯度、地址、聯絡電話等。
具體的參數設定,自行去該網頁去看吧,這裡就不再贅述,這裡我們主要利用“矩形檢索”的方式來擷取整個城市的特定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={您的密鑰}
通過實驗可以發現,一個矩陣地區最多返回400(20*20)個POI點,即page_size = 20 & page_total = 20,雖然官方文檔裡說一個地區返回760+都不成問題的,但是測試了一下,發現並沒有這麼多,最多400個。
顯然,整個城市不可能僅400個特定描述的POI點,所以我們需要對整個城市進行分區操作,然後每片進行訪問,通過Python的迴圈實現。
(3)擷取城市特定POI點集合
比如:我們想擷取北京市四環以內所有飯店的資訊,即可通過上述步驟藉助Python快速實現,廢話不多說,直接上代碼:
# -*- coding: utf-8 -*-# Python 2.7# 提取城市的POI點資訊並將其儲存至MongoDB資料庫import urllib2 import json from pymongo import MongoClientleft_bottom = [116.282387,39.835862]; # 設定地區左下角座標(百度座標系)right_top = [116.497405,39.996569]; # 設定地區右上方座標(百度座標系)part_n = 2; # 設定地區網格(2*2)client = MongoClient('localhost',27001)db = client.transdatadb.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 = '飯店'; #搜尋關鍵詞設定ak = 'xxxxxxxxxxxxxxxxxxxxxx'; #百度地圖api信令n = 0; # 切片計數器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]; # 切片的左下角座標 right_top_part = [right_top[0]+i*x_item,right_top[1]+j*y_item]; # 切片的右上方座標 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)): # 提取返回的結果 col.insert_one(results[m]); n += 1; print '第',str(n),'個切片入庫成功'
執行為上述代碼,運行結果如下:
可以看到,我們將北京市四環以內地區分成4個切片來進行處理,之所以分切片處理,主要是單個地區訪問最多返回400個結果,當地區較大的時候,地區內往往不止400個,所以講大地區進行切片處理,最後,我們通過資料彙總操作,發現返回的結果總共1014個。(理論上應該返回1600,實際返回1014,說明切片的數量是合適的)
好的,我們本篇的分享到這裡就要結束了,最後只想說,API真的是個好東西,科學地使用它我們可以做出很多炫酷的應用,像現在比較活躍的資料型應用,其資料介面基本都是基於API形式的,後面的分享我們還會用到更多API的,大家一起期待吧,哈哈,今天就到這裡了,各位回見。