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不變化情況下進行數據加載的技術)
此時我們需要在開發者工具中,找到xhr里面對應當前數據的相應文件。
分析到這里可以得知:我們的數據是以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, address, avgprice, avgscore, 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()
運行結果如下:
本地文件:
4.總結
根據搜索詞變化,城市變化,可以改變url中指定的參數來實現。同時也要記得變更headers中的指定參數,方法簡單,多加練習即可熟悉ajax類型的數據抓取。
以上就是Python爬蟲實例——爬取美團美食數據的詳細內容
此文轉載文,著作權歸作者所有,如有侵權聯系小編刪除!
原文地址:https://www.zhangshengrong.com/p/8AaYmGYRa2/
