go爬虫和python爬虫哪个好_python 爬虫实战项目--爬取京东商品信息(价格、优惠、排名、好评率等)-Go语言中文社区...
利用splash爬取京東商品信息
一、環境
window7
python3.5
pycharm
scrapy
scrapy-splash
MySQL
二、簡介
為了體驗scrapy-splash 的動態網頁渲染效果,特地編寫了利用splash爬取京東商品信息的爬蟲,當然站在爬取效率和穩定性方面來說,動態網頁爬取首先應該考慮的還是動態頁面逆向分析。
三、環境搭建
這里只介紹splash在window7上的搭建方法:
Splash是一個利用webkit或者基于webkit庫 Javascript渲染服務。它是一個實現了HTTP API的輕量級瀏覽器,Splash是用Python實現的,同時使用Twisted和QT。官方文檔解釋是必須使用Docker容器!之所以用容器技術,好處是你可以一坨的安裝好splash,而不必一點一點的去為安裝splash填坑。
在網上的教程中,大多數是建議利用linux來安裝docker,原因如下圖:
docker使用go語言開發,并且運行在linux系統下,而如果想用window運行,只能在window基礎上先運行一個linux虛擬機,然后再在這個linux虛擬機下運行docker。
由于我使用的是window7系統,只能到官網(https://docs.docker.com/toolbox/toolbox_install_windows/)下載DockerToolbox,下載完成后,雙擊安裝(安裝過程自行百度);
安裝完成后會有三個快捷鍵:
??? 點擊啟動Docker Quickstart Terminal
輸入安裝splash的命令:$docker pull scrapinghub/splash
運行命令:$docker run -p 8050:8050 -p 5023:5023 scrapinghub/splash? ,開啟8050連接端口和5023監控端口或者只開啟8050端口。
最后在scrapy項目中安裝scrapy-splash組件,在settings.py中添加#用來支持cache_args(可選),splash設置
SPIDER_MIDDLEWARES = {
#'e_commerce.middlewares.ECommerceSpiderMiddleware': 543,
'scrapy_splash.SplashDeduplicateArgsMiddleware' : 100 ,
}
DOWNLOADER_MIDDLEWARES = {
#'e_commerce.middlewares.ECommerceDownloaderMiddleware': 543,
'scrapy_splash.SplashCookiesMiddleware' : 723 ,
'scrapy_splash.SplashMiddleware' : 725 ,
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware' : 810 ,
}
#設置去重過濾器
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
SPLASH_URL = 'http://192.168.99.100:8050'
環境配置完成。
四、京東網頁分析與爬蟲編程實現
此次主要爬取京東商品的以下參數:
product:商品名
product_url : 商品鏈接
initial_price : 原價
price : 實際價格
shop : 店家
tags : 優惠活動
comment_nums : 累計評論數
summary_order : 京東排名
praise : 好評度
爬取京東商品信息首先得有商品信息入口,以商品書籍python(關鍵字)為例,url:https://search.jd.com/Search?keyword=python&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=python&page=159&s=4732&click=0
簡化為:https://search.jd.com/Search?keyword=python&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=python&page=1
查看多頁發現url里的幾個重要關鍵字:
keyword:搜索關鍵字
wq:搜索關鍵字
page:頁數(呈奇數遞增)
故可以構建請求url:https://search.jd.com/Search?keyword={1}&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq={1}&page={0}
分析網頁源碼發現各商品信息:
通過css或XPath很容易就可以提取出商品信息,不過發現這里并沒有我們想要的所有信息,故還得找出每個商品的url。
這里存在的一個問題是京東一頁的商品是分批顯示的,通過F12分析網絡里的XHR就會發現,新加載的商品是通過向服務器發送請求url:https://search.jd.com/s_new.php?keyword=python&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=python&page=160&s=4762&scrolling=y&log_id=1530076904.20294&tpl=2_M&show_items=28950919364,12082834672,28883808237,29290652302,29291203091,27895583715,29089172884,28884416666,28938172051,28938903145,26066239470,29090468719,29094523735,28949599627,29291004039,28041915738,26232273814,26400554950,28494562293,29361448498,26291836439,19942582293,15348519021,19580125836,29251686387,27859110321,27880583607,29185119165,28738281855,29184203799
重要關鍵字page是在原來的基礎上加1,直接對該url進行模擬瀏覽器請求應該是會簡便很多,但現在我們不討論這種逆向分析方法,我們這里采用的是splash中的execute 端點對動態網頁進行渲染,就是執行一條javascript語句模擬瀏覽器跳轉到頁面下方位置,從而達到完全加載商品的目的。
請求方法:
商品的url可以在這里提取到:
構造每個商品url請求:https:// + url,當對該url進行請求時發現商品的價格、優惠信息、圖書排名等需要的信息都沒有提取出,分析發現需要進行動態渲染才能得到,所以我們這里采用splash的render.html端點對該url網頁進行渲染,請求方法:
此時再去提取相應的信息,提取成功。
但最后還是有一項參數沒能成功提取,那就是好評率,躲在這里:
在瀏覽器中需要點擊【商品評價】才能看到,分析網頁源碼發現該信息也是在點擊【商品評價】后向服務器發送請求
請求url:https://sclub.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98vv1516&productId=12186192&score=0&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1
可簡化為:https://sclub.jd.com/comment/productPageComments.action?&productId=12186192&score=0&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1
構造請求url:https://sclub.jd.com/comment/productPageComments.action?&productId={0}&score=0&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1
只要傳入product_id便可以通過該url請求獲得需要的好評度
當然也可以繼續提取商品的評論或者是評論情況,這里我覺得好評度已經能說明該商品的好壞了,當然還得結合評論數來做出判斷。
關鍵代碼:def crawl_commentInfo(self , response):
total_product_info = response.css('.gl-item')
for product_info in total_product_info:
product_url = 'https:' + product_info.css('.gl-i-wrap .p-img a::attr(href)').extract_first()
#comment_info crawl firstly
headers = self.headers.copy()
headers.update({
'Referer' : 'https://item.jd.com/12330816.html' ,
'Host': 'sclub.jd.com',
})
match_obj = re.match('.*/(d+).html', product_url)
if match_obj:
product_id = match_obj.group(1)
yield scrapy.Request(self.start_urls[1].format(product_id) , headers = headers ,
meta= {'product_url' : product_url} , callback= self.parse_product)
print('Now crawl commentInfo url is' , self.start_urls[1].format(product_id))
# break
match_obj = re.match('.*page=(d+)$', response.url)
if match_obj:
page_num = int(match_obj.group(1)) + 2
else:
page_num = 3
if '下一頁' in response.text:
yield SplashRequest(self.start_urls[0].format(page_num, 'python'), endpoint='execute',
callback=self.crawl_commentInfo , splash_headers= self.headers ,
args={'lua_source': self.lua_script, 'image' : 0 , 'wait': 1}, cache_args=['lua_source'])
print('Now page_url is :', self.start_urls[0].format(page_num, 'python'))def parse_product(self, response):
product_url = response.meta.get('product_url')
praise = 0
praise_match = re.match('.*"goodRateShow":(d+),.*' , response.text)
if praise_match:
praise = praise_match.group(1)
headers = self.headers.copy()
headers.update({
'Upgrade-Insecure-Requests': 1,
'Host' : 'item.jd.com' ,
})
yield SplashRequest(product_url, endpoint='render.html', splash_headers = headers,
args={'image' : 0, 'timeout' : 15 , 'wait' : 1 } , meta={'praise' : praise}
)
print('Now request url is:', product_url)
爬取結果:
爬取了京東關鍵字“python”的全部商品信息,一共五千多條,也可以切換其他關鍵字爬取任何商品,我們可以通過評論數comment_nums分析每個商品的銷量情況(因為銷量數量和評論數量是相對應的),也可以通過排名summary_order分析出商品的銷量情況,通過praise好評度分析出商品的好壞。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的go爬虫和python爬虫哪个好_python 爬虫实战项目--爬取京东商品信息(价格、优惠、排名、好评率等)-Go语言中文社区...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql mgr 配置_MySQL5.
- 下一篇: python实战项目前后端分离flask