Python爬蟲-利用百度地圖API介面爬取資料並儲存至MySQL資料庫,pythonmysql

來源:互聯網
上載者:User

Python爬蟲-利用百度地圖API介面爬取資料並儲存至MySQL資料庫,pythonmysql

首先,我這裡有一份相關城市以及該城市的公園數量的txt檔案:

其次,利用百度地圖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介面可以獲得城市公園 的詳細資料參數說明:q:檢索的關鍵字region:檢索的地區(市級以上)page_size:每一頁的記錄數量page_num:分頁頁碼output:輸出格式json/xmlak:使用者的存取金鑰,可以在百度地圖API平台上進行申請
一、嘗試第一個API擷取資料並儲存至MySQL資料庫

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

因為我們的最終結果都是要儲存在MySQL資料庫中,為了操作上的方便,我直接使用了圖形管理工具MySQL-Front建立了資料庫:baidumap,並在裡面建立兩張表,表1city用來儲存第一個API的結果,表2park用來儲存第二個API的結果。表1結構如下:

接下來就是寫代碼請求資料,並將結果儲存在表city中:

import requestsimport jsonimport MySQLdbfrom 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=Falsecur.close()conn.close()

從MySQL匯出資料的結果:

二、嘗試第二個API擷取資料

第二個API介面:http://api.map.baidu.com/place/v2/detail?uid=xxxxx&output=json&scope=2&ak=使用者的訪問密匙
裡面有一個參數uid,這個參數我們就從之前所儲存的city表中進行擷取,然後我們嘗試對這個API進行訪問,返回的結果是:

在表park建立表結構如下:

先從表city拿到uid,然後利用第二個API介面進行請求,拿到資料,儲存至表park中,代碼如下:

from datetime import datetimeimport requestsimport jsonimport MySQLdb#city表中拿到uidconn=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匯出資料的結果:

   
0
0
查看評論

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.