Python爬蟲-利用百度地圖API介面爬取資料並儲存至MySQL資料庫
阿新 • • 發佈:2019-01-06
首先,我這裡有一份相關城市以及該城市的公園數量的txt檔案:
其次,利用百度地圖API提供的介面爬取城市公園的相關資訊。
所利用的API介面有兩個:
1、http://api.map.baidu.com/place/v2/search?q=公園®ion=北京&output=json&ak=使用者的訪問密匙
2、http://api.map.baidu.com/place/v2/detail?uid=xxxxx&output=json&scope=2&ak=使用者的訪問密匙
第一個API介面可以獲得城市公園的一般資訊
第二個API介面可以獲得城市公園 的詳細資訊
引數說明:
q: 檢索的關鍵字
region:檢索的區域(市級以上)
page_size:每一頁的記錄數量
page_num:分頁頁碼
output:輸出格式json/xml
ak:使用者的訪問金鑰,可以在百度地圖API平臺上進行申請
一、嘗試第一個API獲取資料並存儲至MySQL資料庫
下面是對第一個API介面進行訪問時返回的結果:
因為我們的最終結果都是要儲存在MySQL資料庫中,為了操作上的方便,我直接使用了圖形管理工具MySQL-Front新建了資料庫:baidumap,並在裡面新建兩張表,表1city用來儲存第一個API的結果,表2park用來儲存第二個API的結果。表1結構如下:
接下來就是寫程式碼請求資料,並將結果儲存在表city中:
import requests
import json
import MySQLdb
from datetime import datetime
#從txt檔案中獲取相關城市並重新生成一個列表
city_list=[]
with open('cities.txt','r',encoding='utf-8') as f:
for eachline in f:
if eachline !='' and eachline !='\n':
city=eachline.split('\t')[0]
city_list.append(city)
f.close()
#定義一個getjson函式用來解析返回的資料
def getjson(palace,page_num=0):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
}
url='http://api.map.baidu.com/place/v2/search'
params={
'q':'公園',
'region':palace,
'scope':'2',
'page_size':'20',
'page_num':page_num,
'output':'json',
'ak':'XM53LMurtNQaAPFuKVy1WzSyZCNmNA9H',
}
response=requests.get(url=url,params=params,headers=headers)
html=response.text
decodejson=json.loads(html)
return decodejson
#連線資料庫、獲得遊標,獲取資料並插入到資料庫中
在獲取資料時使用get()方法比較好,避免造成無相關資料時程式的中斷
conn=MySQLdb.connect(host='localhost',user='root',password='root',db='baidumap',charset='utf8')
cur=conn.cursor()
for city in city_list:
not_last_page=True
page_num=0
while not_last_page:
decodejson=getjson(city,page_num)
print(city,page_num)
if decodejson.get('results'):
for result in decodejson.get('results'):
park=result.get('name')
lat=result.get('location').get('lat')
lng=result.get('location').get('lng')
address=result.get('address')
street_id=result.get('street_id')
uid=result.get('uid')
sql="""INSERT INTO baidumap.city
(city,park,location_lat,location_lng,address,street_id,uid,time)
VALUES (%s,%s,%s,%s,%s,%s,%s,%s);"""
cur.execute(sql,(city,park,lat,lng,address,street_id,uid,datetime.now()))
conn.commit()
page_num=page_num+1
else:
not_last_page=False
cur.close()
conn.close()
從MySQL匯出資料的結果:
二、嘗試第二個API獲取資料
在表park建立表結構如下:
先從表city拿到uid,然後利用第二個API介面進行請求,拿到資料,儲存至表park中,程式碼如下:
from datetime import datetime
import requests
import json
import MySQLdb
#city表中拿到uid
conn=MySQLdb.connect(host='localhost',user='root',password='root',db='baidumap',charset='utf8')
cur=conn.cursor()
sql="Select uid from baidumap.city WHERE id>0;"
cur.execute(sql)
conn.commit()
uids=cur.fetchall()
##定義一個getjson函式用來解析返回的資料
def getjson(uid):
try:
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
}
params={
'uid':uid,
'scope':'2',
'output':'json',
'ak':'XM53LMurtNQaAPFuKVy1WzSyZCNmNA9H',
}
url='http://api.map.baidu.com/place/v2/detail'
response=requests.get(url=url,headers=headers,params=params)
html=response.text
decodejson=json.loads(html)
return decodejson
except:
pass
#獲取資料,儲存資料
for uid in uids:
uid=uid[0]
print(uid)
decodejson=getjson(uid)
data=decodejson.get('result')
if data:
park=data.get('name')
location_lat = data.get('location').get('lat')
location_lng=data.get('location').get('lng')
address=data.get('address')
street_id=data.get('street_id')
telephone=data.get('telephone')
detail=data.get('detail')
uid=data.get('uid')
tag=data.get('detail_info').get('tag')
detail_url=data.get('detail_info').get('detail_url')
type=data.get('detail_info').get('type')
overall_rating=data.get('detail_info').get('overall_rating')
image_num=data.get('detail_info').get('image_num')
comment_num=data.get('detail_info').get('comment_num')
shop_hours=data.get('detail_info').get('shop_hours')
alias=data.get('detail_info').get('alias')
scope_type=data.get('detail_info').get('scope_type')
scope_grade=data.get('detail_info').get('scope_grade')
description=data.get('detail_info').get('description')
sql="""INSERT INTO baidumap.park(park,location_lat,location_lng,address,street_id,telephone,
detail,uid,tag,detail_url,type,overall_rating,image_num,comment_num,shop_hours,alias,scope_type,scope_grade,
description,time) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s);"""
cur.execute(sql,(park,location_lat,location_lng,address,street_id,telephone,
detail,uid,tag,detail_url,type,overall_rating,image_num,comment_num,shop_hours,alias,scope_type,scope_grade,
description,datetime.now()))
conn.commit()
cur.close()
conn.close()
從MySQL匯出資料的結果: