1. 程式人生 > 程式設計 >Python爬蟲例項——爬取美團美食資料

Python爬蟲例項——爬取美團美食資料

1.分析美團美食網頁的url引數構成

1)搜尋要點

美團美食,地址:北京,搜尋關鍵詞:火鍋

2)爬取的url

https://bj.meituan.com/s/%E7%81%AB%E9%94%85/

3)說明

url會有自動編碼中文功能。所以火鍋二字指的就是這一串我們不認識的程式碼%E7%81%AB%E9%94%85。

通過關鍵詞城市的url構造,解析當前url中的bj=北京,/s/後面跟搜尋關鍵詞。

這樣我們就可以瞭解到當前url的構造。

2.分析頁面資料來源(F12開發者工具)

開啟F12開發者工具,並且重新整理當前頁面:可以看到切換到第二頁時候,我們的url沒有變化,網站也沒有自動進行重新整理跳轉操作。(web中ajax技術就是在保證頁面不重新整理,url不變化情況下進行資料載入的技術)

Python爬蟲例項——爬取美團美食資料

此時我們需要在開發者工具中,找到xhr裡面對應當前資料的響應檔案。

Python爬蟲例項——爬取美團美食資料

分析到這裡可以得知:我們的資料是以json格式互動。分析第二頁的json檔案請求地址與第三頁json檔案的請求地址。

第二頁:https://apimobile.meituan.com/group/v4/poi/pcsearch/1?uuid=xxx&userid=-1&limit=32&offset=32&cateId=-1&q=%E7%81%AB%E9%94%85

第三頁:https://apimobile.meituan.com/group/v4/poi/pcsearch/1?uuid=xxx&userid=-1&limit=32&offset=64&cateId=-1&q=%E7%81%AB%E9%94%85

對比發現:offse引數每次翻頁增加32,並且limit引數是一次請求的資料量,offse是資料請求的開始元素,q是搜尋關鍵詞poi/pcsearch/1?其中的1是北京城市的id編號。

3.構造請求抓取美團美食資料

接下來直接構造請求,迴圈訪問每一頁的資料,最終程式碼如下。

import requests
import re


def start():
  for w in range(0,1600,32):
  #頁碼根據實際情況x32即可,我這裡是設定50頁為上限,為了避免設定頁碼過高或者資料過少情況,定義最大上限為1600-也就是50頁,使用try-except來檢測時候異常,異常跳過該頁,一般作為無資料跳過該頁處理
    try:
    # 注意uuid後面引數空餘將uuid後xxx替換為自己的uuid引數
      url = 'https://apimobile.meituan.com/group/v4/poi/pcsearch/1?uuid=xxx&userid=-1&limit=32&offset='+str(w)+'&cateId=-1&q=%E7%81%AB%E9%94%85'
      #headers的資料可以在F12開發者工具下面的requests_headers中檢視,需要實現選擇如下headers資訊
      #必要情況 請求頻繁 建議增加cookie引數在headers內
      headers = {
        'Accept': '*/*','Accept-Encoding': 'gzip,deflate,br','Accept-Language': 'zh-CN,zh;q=0.9','Connection': 'keep-alive','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400','Host': 'apimobile.meituan.com','Origin': 'https://bj.meituan.com','Referer': 'https://bj.meituan.com/s/%E7%81%AB%E9%94%85/'
      }
      response = requests.get(url,headers=headers)
      #正則獲取當前響應內容中的資料,因json方法無法針對店鋪特有的title鍵值進行獲取沒所以採用正則
   titles = re.findall('","title":"(.*?)","address":"',response.text)
     addresses = re.findall(',"address":"(.*?)",',response.text)
     avgprices = re.findall(',"avgprice":(.*?),response.text)
     avgscores = re.findall(',"avgscore":(.*?),response.text)
     comments = re.findall(',"comments":(.*?),response.text)
     #輸出當前返回資料的長度 是否為32
     print(len(titles),len(addresses),len(avgprices),len(avgscores),len(comments))
     for o in range(len(titles)):
     #迴圈遍歷每一個值 寫入檔案中
       title = titles[o]
       address = addresses[o]
       avgprice = avgprices[o]
       avgscore = avgscores[o]
       comment = comments[o]
       #寫入本地檔案
       file_data(title,address,avgprice,avgscore,comment)

#檔案寫入方法
def file_data(title,comment):
  data = {
        '店鋪名稱': title,'店鋪地址': address,'平均消費價格': avgprice,'店鋪評分': avgscore,'評價人數': comment
      }
  with open('美團美食.txt','a',encoding='utf-8')as fb:
    fb.write(json.dumps(data,ensure_ascii=False) + '\n')
    #ensure_ascii=False必須加因為json.dumps方法不關閉轉碼會導致出現亂碼情況
if __name__ == '__main__':
  start()

執行結果如下:

Python爬蟲例項——爬取美團美食資料

本地檔案:

Python爬蟲例項——爬取美團美食資料

4.總結

根據搜尋詞變化,城市變化,可以改變url中指定的引數來實現。同時也要記得變更headers中的指定引數,方法簡單,多加練習即可熟悉ajax型別的資料抓取。

以上就是Python爬蟲例項——爬取美團美食資料的詳細內容,更多關於Python爬蟲爬取美食資料的資料請關注我們其它相關文章!