基於Python獲取亞馬遜的評論信息的處理
上次亞馬遜的商品信息都獲取到瞭,自然要看一下評論的部分。用戶的評論能直觀的反映當前商品值不值得購買,亞馬遜的評分信息也能獲取到做一個評分的權重。
亞馬遜的評論區由用戶ID,評分及評論標題,地區時間,評論正文這幾個部分組成,本次獲取的內容就是這些。
測試鏈接:https://www.amazon.it/product-reviews/B08GHGTGQ2/ref=cm_cr_arp_d_paging_btm_14?ie=UTF8&pageNumber=14&reviewerType=all_reviews&pageSize=10&sortBy=recent
一、分析亞馬遜的評論請求
首先打開開發者模式的Network,Clear清屏做一次請求:
你會發現在Doc中的get請求正好就有我們想要的評論信息。
可是真正的評論數據可不是全部都在這裡的,頁面往下翻,有個翻頁的button:
點擊翻頁請求下一頁,在Fetch/XHR選項卡中多瞭一個新的請求,剛才的Doc選項卡中並無新的get請求。這下發現瞭所有的評論信息是XHR類型的請求。
獲取到post請求的鏈接和payload數據,裡面含有控制翻頁的參數,真正的評論請求已經找到瞭。
這一堆就是未處理的信息,這些請求未處理的信息裡面,帶有data-hook=\"review\"的就是帶有評論的信息。分析完畢,下面開始一步一步去寫請求。
二、獲取亞馬遜評論的內容
首先拼湊請求所需的post參數,請求鏈接,以便之後的自動翻頁,然後帶參數post請求鏈接:
headers = { 'authority': 'www.amazon.it', "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36", } page = 1 post_data = { "sortBy": "recent", "reviewerType": "all_reviews", "formatType": "", "mediaType": "", "filterByStar": "", "filterByLanguage": "", "filterByKeyword": "", "shouldAppend": "undefined", "deviceType": "desktop", "canShowIntHeader": "undefined", "pageSize": "10", "asin": "B08GHGTGQ2", } # 翻頁關鍵payload參數賦值 post_data["pageNumber"] = page, post_data["reftag"] = f"cm_cr_getr_d_paging_btm_next_{page}", post_data["scope"] = f"reviewsAjax{page}", # 翻頁鏈接賦值 spiderurl=f'https://www.amazon.it/hz/reviewsrender/ajax/reviews/get/ref=cm_cr_getr_d_paging_btm_next_{page}' res = requests.post(spiderurl,headers=headers,data=post_data) if res and res.status_code == 200: res = res.content.decode('utf-8') print(res)
現在已經獲取到瞭這一堆未處理的信息,接下來開始對這些數據進行處理。
三、亞馬遜評論信息的處理
上圖的信息會發現,每一段的信息都由“&&&”進行分隔,而分隔之後的每一條信息都是由'","'分隔開的:
所以用python的split方法進行處理,把字符串分隔成list列表:
# 返回值字符串處理 contents = res.split('&&&') for content in contents: infos = content.split('","')
由'","'分隔的數據通過split處理生成新的list列表,評論內容是列表的最後一個元素,去掉裡面的"\","\n"和多餘的符號,就可以通過css/xpath選擇其進行處理瞭:
for content in contents: infos = content.split('","') info = infos[-1].replace('"]','').replace('\\n','').replace('\\','') # 評論內容判斷 if 'data-hook="review"' in info: sel = Selector(text=info) data = {} data['username'] = sel.xpath('//span[@class="a-profile-name"]/text()').extract_first() #用戶名 data['point'] = sel.xpath('//span[@class="a-icon-alt"]/text()').extract_first() #評分 data['date'] = sel.xpath('//span[@data-hook="review-date"]/text()').extract_first() #日期地址 data['review'] = sel.xpath('//span[@data-hook="review-title"]/span/text()').extract_first() #評價標題 data['detail'] = sel.xpath('//span[@data-hook="review-body"]').extract_first() #評價內容 image = sel.xpath('div[@class="review-image-tile-section"]').extract_first() data['image'] = image if image else "not image" #圖片 print(data)
四、代碼整合
4.1 代理設置
穩定的IP代理是你數據獲取最有力的工具。目前國內還是無法穩定的訪問亞馬遜,會出現連接失敗的情況。我這裡使用的ipidea代理請求的意大利地區的亞馬遜,可以通過賬密和api獲取代理,速度還是非常穩定的。
地址:http://www.ipidea.net/?utm-source=csdn&utm-keyword=?wb
下面的代理獲取的方法:
# api獲取ip def getApiIp(self): # 獲取且僅獲取一個ip------意大利 api_url = '獲取代理地址' res = requests.get(api_url, timeout=5) try: if res.status_code == 200: api_data = res.json()['data'][0] proxies = { 'http': 'http://{}:{}'.format(api_data['ip'], api_data['port']), 'https': 'http://{}:{}'.format(api_data['ip'], api_data['port']), } print(proxies) return proxies else: print('獲取失敗') except: print('獲取失敗')
4.2 while循環翻頁
while循環進行翻頁,評論最大頁數是99頁,99頁之後就break跳出while循環:
def getPLPage(self): while True: # 翻頁關鍵payload參數賦值 self.post_data["pageNumber"]= self.page, self.post_data["reftag"] = f"cm_cr_getr_d_paging_btm_next_{self.page}", self.post_data["scope"] = f"reviewsAjax{self.page}", # 翻頁鏈接賦值 spiderurl = f'https://www.amazon.it/hz/reviews-render/ajax/reviews/get/ref=cm_cr_getr_d_paging_btm_next_{self.page}' res = self.getRes(spiderurl,self.headers,'',self.post_data,'POST',check)#自己封裝的請求方法 if res: res = res.content.decode('utf-8') # 返回值字符串處理 contents = res.split('&&&') for content in contents: infos = content.split('","') info = infos[-1].replace('"]','').replace('\\n','').replace('\\','') # 評論內容判斷 if 'data-hook="review"' in info: sel = Selector(text=info) data = {} data['username'] = sel.xpath('//span[@class="a-profile-name"]/text()').extract_first() #用戶名 data['point'] = sel.xpath('//span[@class="a-icon-alt"]/text()').extract_first() #評分 data['date'] = sel.xpath('//span[@data-hook="review-date"]/text()').extract_first() #日期地址 data['review'] = sel.xpath('//span[@data-hook="review-title"]/span/text()').extract_first() #評價標題 data['detail'] = sel.xpath('//span[@data-hook="review-body"]').extract_first() #評價內容 image = sel.xpath('div[@class="review-image-tile-section"]').extract_first() data['image'] = image if image else "not image" #圖片 print(data) if self.page <= 99: print('Next Page') self.page += 1 else: break
最後的整合代碼:
# coding=utf-8 import requests from scrapy import Selector class getReview(): page = 1 headers = { 'authority': 'www.amazon.it', "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36", } post_data = { "sortBy": "recent", "reviewerType": "all_reviews", "formatType": "", "mediaType": "", "filterByStar": "", "filterByLanguage": "", "filterByKeyword": "", "shouldAppend": "undefined", "deviceType": "desktop", "canShowIntHeader": "undefined", "pageSize": "10", "asin": "B08GHGTGQ2", #post_data中asin參數目前寫死在 #"https://www.amazon.it/product-reviews/B08GHGTGQ2?ie=UTF8&pageNumber=1&reviewerType=all_reviews&pageSize=10&sortBy=recent" #這個鏈接裡,不排除asin值變化的可能,如要獲取get請求即可 def getPLPage(self): while True: # 翻頁關鍵payload參數賦值 self.post_data["pageNumber"]= self.page, self.post_data["reftag"] = f"cm_cr_getr_d_paging_btm_next_{self.page}", self.post_data["scope"] = f"reviewsAjax{self.page}", # 翻頁鏈接賦值 spiderurl = f'https://www.amazon.it/hz/reviews-render/ajax/reviews/get/ref=cm_cr_getr_d_paging_btm_next_{self.page}' res = self.getRes(spiderurl,self.headers,'',self.post_data,'POST',check)#自己封裝的請求方法 if res: res = res.content.decode('utf-8') # 返回值字符串處理 contents = res.split('&&&') for content in contents: infos = content.split('","') info = infos[-1].replace('"]','').replace('\\n','').replace('\\','') # 評論內容判斷 if 'data-hook="review"' in info: sel = Selector(text=info) data = {} data['username'] = sel.xpath('//span[@class="a-profile-name"]/text()').extract_first() #用戶名 data['point'] = sel.xpath('//span[@class="a-icon-alt"]/text()').extract_first() #評分 data['date'] = sel.xpath('//span[@data-hook="review-date"]/text()').extract_first() #日期地址 data['review'] = sel.xpath('//span[@data-hook="review-title"]/span/text()').extract_first() #評價標題 data['detail'] = sel.xpath('//span[@data-hook="review-body"]').extract_first() #評價內容 image = sel.xpath('div[@class="review-image-tile-section"]').extract_first() data['image'] = image if image else "not image" #圖片 print(data) if self.page <= 99: print('Next Page') self.page += 1 else: break # api獲取ip def getApiIp(self): # 獲取且僅獲取一個ip------意大利 api_url = '獲取代理地址' res = requests.get(api_url, timeout=5) try: if res.status_code == 200: api_data = res.json()['data'][0] proxies = { 'http': 'http://{}:{}'.format(api_data['ip'], api_data['port']), 'https': 'http://{}:{}'.format(api_data['ip'], api_data['port']), } print(proxies) return proxies print('獲取失敗') except: print('獲取失敗') #專門發送請求的方法,代理請求三次,三次失敗返回錯誤 def getRes(self,url,headers,proxies,post_data,method): if proxies: for i in range(3): try: # 傳代理的post請求 if method == 'POST': res = requests.post(url,headers=headers,data=post_data,proxies=proxies) # 傳代理的get請求 else: res = requests.get(url, headers=headers,proxies=proxies) if res: return res except: print(f'第{i+1}次請求出錯') else: return None else: proxies = self.getApiIp() # 請求代理的post請求 res = requests.post(url, headers=headers, data=post_data, proxies=proxies) # 請求代理的get請求 res = requests.get(url, headers=headers, proxies=proxies) print(f"第{i+1}次請求出錯") if __name__ == '__main__': getReview().getPLPage()
總結
本次的亞馬遜評論獲取就是兩個坑,一是評論信息通過的XHR請求方式,二是評論信息的處理。分析之後這次的數據獲取還是非常簡單的,找到正確的請求方式,穩定的IP代理讓你事半功倍,找到信息的共同點進行處理,問題就迎刃而解瞭。
到此這篇關於基於Python獲取亞馬遜的評論的文章就介紹到這瞭,更多相關Python亞馬遜的評論內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 用Python獲取亞馬遜商品信息
- Python爬蟲之自動爬取某車之傢各車銷售數據
- 單身狗福利?Python爬取某婚戀網征婚數據
- Python實現多線程爬表情包詳解
- Python爬蟲實現熱門電影信息采集