1. 程式人生 > >Python爬蟲時翻頁等操作URL不會改變的解決辦法----以攜程評論爬取為例

Python爬蟲時翻頁等操作URL不會改變的解決辦法----以攜程評論爬取為例

一、需求:

      需要爬取攜程的五四廣場景點主頁的使用者點評資訊。

二、爬蟲時可能遇到的問題:

評論資訊雖然可以在該頁的原始碼中獲取到:

但是存在許多問題,例如:

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()

四、爬取結果: