本文的文字及圖片來源于網路,僅供學習、交流使用,不具有任何商業用途,著作權歸原作者所有,如有問題請及時聯系我們以作處理
以下文章來源于騰訊云 作者:Python進階者
( 想要學習Python?Python學習交流群:1039649593,滿足你的需求,資料都已經上傳群檔案流,可以自行下載!還有海量最新2020python學習資料, )
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型別的資料抓取,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/235226.html
標籤:Python
上一篇:Java基礎語法吐血整理
下一篇:谷歌手機解鎖,刷機以及root
