Python爬蟲時翻頁等操作URL不會改變的解決辦法----以攜程評論爬取為例
阿新 • • 發佈:2018-12-18
一、需求:
需要爬取攜程的五四廣場景點主頁的使用者點評資訊。
二、爬蟲時可能遇到的問題:
評論資訊雖然可以在該頁的原始碼中獲取到:
但是存在許多問題,例如:
1、評論翻頁、修改評論排序方式(智慧排序、有用數排序、按時間排序)並不會改變當前頁的URL。
2、使用Fiddler等的抓包工具,雖然能夠找到該網頁用來進行評論資料傳輸的檔案AsynCommentView的URL,但是發現翻頁以及修改評論排序方式同樣不會改變URL。
三、問題分析:
1、觀察景點頁面的原始碼,注意到關鍵程式碼:
這行程式碼直接說明了,該網頁的評論資訊是通過POST服務的形式,向評論資料傳輸檔案AsynCommentView的URL傳送POST請求,然後獲取返回的評論資料。
2、通過Chrome核心瀏覽器的F12工具,切換到network檢視一下傳輸的內容,首先清空內容避免干擾,然後點選翻頁或者切換排序方式,切換到Headers我們可以看到:
傳送的請求資訊無處遁形~
4、那麼問題來了,請求的內容引數該如何設定呢?
(1)order以及pagenow:顧名思義,是排序方式(按時間:1 ,有用數:2,智慧:3)以及當前頁碼。
(2)star、tourist:測試發現使用0.0即可。
(3)poiID、districtId、districtEName、resourceId、resourcetype:無法輕易判斷,但是通過觀察網頁原始碼:
發現原始碼幫了大忙,他會把預設的引數儲存,可以通過爬取這些引數來進行填充。
3、因此可以初步思考爬蟲的解決思路:即使用自動模擬HTTP請求來解決,具體可參考我的另一篇部落格:
三、編寫程式碼:
import re import urllib.request import urllib.parse #模擬瀏覽器 headers=("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6726.400 QQBrowser/10.2.2265.400") opener=urllib.request.build_opener() opener.addheaders=[headers] urllib.request.install_opener(opener) #設定URL為當前景點頁面並獲取內容 baseUrl="http://you.ctrip.com/sight/Qingdao5/5326.html#ctm_ref=www_hp_bs_lst" pagedata=urllib.request.urlopen(baseUrl).read().decode("utf-8","ignore") #爬取頁面中的POST引數資訊並進行處理 poiIDPat='var poiid = "(.*?)"' districtIdPat='var districtid = "(.*?)"' districtENamePat='var districtename = "(.*?)"' resourceIdPat='var resourceid = "(.*?)"' resourcetypePat='var resourcetype = "(.*?)"' poiID=int(re.compile(poiIDPat,re.S).findall(pagedata)[0]) districtId=int(re.compile(districtIdPat,re.S).findall(pagedata)[0]) districtEName=re.compile(districtENamePat,re.S).findall(pagedata)[0] resourceId=int(re.compile(resourceIdPat,re.S).findall(pagedata)[0]) resourcetype=int(re.compile(resourcetypePat,re.S).findall(pagedata)[0]) order=1 #排序方式,此處設定為按時間排序 star=0.0 tourist=0.0 #設定資料傳輸檔案的URL,當Post網址無法輕易找到時,可以使用抓包分析 url="http://you.ctrip.com/destinationsite/TTDSecond/SharedView/AsynCommentView" comments=[]#儲存所有評論的列表 #以爬取評論前30頁為例 for i in range(1,31): #設定Post的值 mydata=urllib.parse.urlencode({ "poiID":poiID, "districtId":districtId, "districtEName":districtEName, "pagenow":i, "order":order, "star":star, "tourist":tourist, "resourceId":resourceId, "resourcetype":resourcetype }).encode("utf-8") #傳送POST請求進行爬取 req=urllib.request.Request(url,mydata) commentdata=urllib.request.urlopen(req).read().decode("utf-8","ignore") commentPat='<span class="heightbox">(.*?)</span>' #獲得當前頁評論並存儲 comment=re.compile(commentPat,re.S).findall(pagedata) comments.extend(comment) #寫入txt檔案 file_handle=open('E:/comment.txt',mode='w') for j in range(0,len(comments)): text = "評論內容:"+comments[j] + '\n\n' file_handle.write(text) file_handle.close()
四、爬取結果: