<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
上次亞馬遜的商品資訊都獲取到了,自然要看一下評論的部分。使用者的評論能直觀的反映當前商品值不值得購買,亞馬遜的評分資訊也能獲取到做一個評分的權重。
亞馬遜的評論區由使用者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)
穩定的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('獲取失敗')
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亞馬遜的評論內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45