Python爬蟲-利用百度地圖API接口爬取數(shù)據(jù)并保存至MySQL數(shù)據(jù)庫

首先,我這里有一份相關城市以及該城市的公園數(shù)量的txt文件:

分析-02.png

其次,利用百度地圖API提供的接口爬取城市公園的相關信息。
所利用的API接口有兩個:

1、http://api.map.baidu.com/place/v2/search?q=公園&region=北京&output=json&ak=用戶的訪問密匙
2、http://api.map.baidu.com/place/v2/detail?uid=xxxxx&output=json&scope=2&ak=用戶的訪問密匙

第一個API接口可以獲得城市公園的一般信息
第二個API接口可以獲得城市公園 的詳細信息

參數(shù)說明:
q:檢索的關鍵字
region:檢索的區(qū)域(市級以上)
page_size:每一頁的記錄數(shù)量
page_num:分頁頁碼
output:輸出格式json/xml
ak:用戶的訪問密鑰,可以在百度地圖API平臺上進行申請

一、嘗試第一個API獲取數(shù)據(jù)并存儲至MySQL數(shù)據(jù)庫

下面是對第一個API接口進行訪問時返回的結果:

分析-03.png

因為我們的最終結果都是要存儲在MySQL數(shù)據(jù)庫中,為了操作上的方便,我直接使用了圖形管理工具MySQL-Front新建了數(shù)據(jù)庫:baidumap,并在里面新建兩張表,表1city用來存儲第一個API的結果,表2park用來存儲第二個API的結果。表1結構如下:


分析-04.png

接下來就是寫代碼請求數(shù)據(jù),并將結果存儲在表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函數(shù)用來解析返回的數(shù)據(jù)
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

#連接數(shù)據(jù)庫、獲得游標,獲取數(shù)據(jù)并插入到數(shù)據(jù)庫中
在獲取數(shù)據(jù)時使用get()方法比較好,避免造成無相關數(shù)據(jù)時程序的中斷
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導出數(shù)據(jù)的結果:

分析-05.png

二、嘗試第二個API獲取數(shù)據(jù)

第二個API接口:http://api.map.baidu.com/place/v2/detail?uid=xxxxx&output=json&scope=2&ak=用戶的訪問密匙
里面有一個參數(shù)uid,這個參數(shù)我們就從之前所保存的city表中進行獲取,然后我們嘗試對這個API進行訪問,返回的結果是:

分析-06.png

在表park建立表結構如下:

分析-07.png

先從表city拿到uid,然后利用第二個API接口進行請求,拿到數(shù)據(jù),存儲至表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函數(shù)用來解析返回的數(shù)據(jù)
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

#獲取數(shù)據(jù),存儲數(shù)據(jù)
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導出數(shù)據(jù)的結果:

分析-08.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容