1. 程式人生 > >python爬蟲爬取美團西安美食資料

python爬蟲爬取美團西安美食資料

經歷了一週的種種波折,參考了CSDN上N多博主的部落格,終於搞定了美團西安美食資料,在此做簡單記錄:

愚蠢如我,不知如何讓爬蟲程式翻下一頁,只好看了前後兩頁請求的網址有什麼不同,後來發現第一頁字尾是‘pn1’,第二頁是‘pn2’,以此類推……所以手動查看了一共有15頁之後,萌生了一個愚蠢的想法並實現了它,以下是部分程式碼:

    target = 'http://xa.meituan.com/meishi/'
    head={}
    head['authorization']='your ClientId'(cookie倒數第幾個引數)
    head['User-Agent'] = ''
    for i in range(16):
        if i==0:
            continue
        target_real=target+'pn'+str(i)+'/'
        req = requests.get(url=target_real,headers=head)
        html=req.text
        bf=BeautifulSoup(html,'lxml')
        texts=bf.find_all('script')
        text=texts[14].get_text().strip()(這部分也是很愚蠢的做法,實在是找不到別的方法了)
        text=text[19:-1]
        result=json.loads(text)
        result=result['poiLists']
        result=result['poiInfos']

以此挑出自己想要的部分資料,再經過簡單處理之後便以為大功告成,在日報裡向老闆彙報了捷報“美團西安美食部分爬取完成”,今天早上十點多老闆問我爬了多少家,我看了下一共四百多家,老闆說有兩三萬餐飲,讓我看看怎麼回事

回到工位上,開啟美團網頁發現不管登不登入,只要不選任何條件,都是顯示15頁,然後我按照行政劃分一個個開啟,根本不是15頁好嗎,再譬如開啟“長安區”,選擇‘長安區全部’,顯示有19頁,我再分別將長安區的商圈一個個開啟,加起來發現有大概39頁,就算剃掉不滿一頁的情況,也遠遠不止19頁,而且還有了一個發現,每一個商圈都有一個特定的ID,其url就是美團西安美食的url+b+ID+pn+頁碼,所以我決定按照行政區劃分來獲取資料,這時候問題就出現了,不可能把每一個商圈一共有多少頁都手動檢視一遍,於是想了以下辦法:

        for i in range(1,5,1):(每個商圈商家總數最多不超過50頁)
            target='http://xa.meituan.com/meishi/'+'b'+str(item)+'/'+'pn'+str(i)+'/'
            head={}
            head['authorization']='your ClientID'
            head['User-Agent'] = ''
            req = requests.get(url=target,headers=head)
            html=req.text
            bf=BeautifulSoup(html,'lxml')
            texts=bf.find_all('script')
            text=texts[14].get_text().strip()
            text=text[19:-1]
            result=json.loads(text)
            result=result['poiLists']
            result=result['poiInfos']
            if result:(判斷獲取內容是否為空)
                print(target)
                for it in result:
                    Info_list=[]
                    Info_list.append('美團')
                    Info_list.append('美食')
                    Info_list.append(it['title'])
                    Info_list.append(it['address'])
                    writer.writerow(Info_list)
                time.sleep(3)
            else:
                break(若為空,直接跳出本層迴圈)

下面是獲取各個商圈ID的部分程式碼:

    target = 'http://xa.meituan.com/meishi/'
    head={}
    head['authorization']='your ClientID'
    head['User-Agent'] = ''
    req = requests.get(url=target,headers=head)
    html=req.text
    bf=BeautifulSoup(html,'lxml')
    texts=bf.find_all('script')
    text=texts[14].get_text().strip()
    text=text[19:-1]
    result=json.loads(text)
    result=result['filters']
    result=result['areas']
    list=[]
    for item in result:
        for i in item['subAreas']:
            if i['name']=='全部':(不需要獲取每個行政區第一個全部的ID,所以直接略過)
                continue
            list.append(i['id'])
    print(list)

獲取了每個商圈的ID之後,再根據url組成規則即可得到每個商圈的url(好像走了一點彎路了,獲取的html裡面直接有每個商圈的url)

以下是完整程式碼,根據自己需要可做修改:

#美團美食
# -*- coding:UTF-8 -*-
import requests
import time
from bs4 import BeautifulSoup
import json
import csv
with open(r'美團西安美食.csv',"w", newline='',encoding='UTF-8') as csvfile: 
    writer = csv.writer(csvfile)
    writer.writerow(['網站名','品類','商家名稱','地址']) 
    target = 'http://xa.meituan.com/meishi/'
    head={}
    head['authorization']='your ClientID'
    head['User-Agent'] = ''
    req = requests.get(url=target,headers=head)
    html=req.text
    bf=BeautifulSoup(html,'lxml')
    texts=bf.find_all('script')
    text=texts[14].get_text().strip()
    text=text[19:-1]
    result=json.loads(text)
    result=result['filters']
    result=result['areas']
    list=[]
    for item in result:
        for i in item['subAreas']:
            if i['name']=='全部':
                continue
            list.append(i['id'])
    print(list)
    for item in list:
        for i in range(50):
            if i==0:
                continue
            target='http://xa.meituan.com/meishi/'+'b'+str(item)+'/'+'pn'+str(i)+'/'
            head={}
            head['authorization']='your ClientID'
            head['User-Agent'] = ''
            req = requests.get(url=target,headers=head)
            html=req.text
            bf=BeautifulSoup(html,'lxml')
            texts=bf.find_all('script')
            text=texts[14].get_text().strip()
            text=text[19:-1]
            result=json.loads(text)
            result=result['poiLists']
            result=result['poiInfos']
            if result:
                print(target)
                for it in result:
                    Info_list=[]
                    Info_list.append('美團')
                    Info_list.append('美食')
                    Info_list.append(it['title'])
                    Info_list.append(it['address'])
                    writer.writerow(Info_list)
                time.sleep(3)
            else:
                break
print('Done')
        

整理完畢