之前我們學習的內容都是抓取靜態頁面,每次請求,它的網頁全部信息將會一次呈現出來。 但是,像比如一些購物網站,他們的商品信息都是js加載出來的,並且會有ajax異步加載。像這樣的情況,直接使用scrapy的Request請求是拿不到我們想要的信息的,解決的方法就是使用scrapy-splash。
scrapy-splash加載js數據是基於Splash來實現的,Splash是一個Javascript渲染服務。它是一個實現了HTTP API的輕量級瀏覽器,Splash是用Python實現的,同時使用Twisted和QT,而我們使用scrapy-splash最終拿到的response相當於是在瀏覽器全部渲染完成以后,拿到的渲染之后的網頁源代碼。
准備環節
-
安裝docker
在windows環境下,安裝docker簡便的方法是使用docker toolbox,由於Docker引擎的守護進程使用的是Linux的內核,所以我們不能夠直接在windows中運行docker引擎。而是需要在你的機器上創建和獲得一個Linux虛擬機,用這個虛擬機才可以在你的windows系統上運行Docker引擎,docker toolbox這個工具包里面集成了windows環境下運行docker必要的工具,當然也包括虛擬機了。
首先下載docker toolbox
執行安裝程序,默認情況下,你的計算機會安裝以下幾個程序- Windows版的Docker客戶端
- Docker Toolbox管理工具和ISO鏡像
- Oracle VM 虛擬機
- Git 工具
當然,如果你之前已經安裝過了Oracle VM 虛擬機 或者 Git 工具 ,那么你在安裝的時候可以取消勾選這兩個內容,之后,你只需要狂點下一步即可。安裝完畢以后,找到Docker Quickstart Terminal圖標,雙擊運行,稍等它自己配置一小段時間,你會看到以下的界面
請注意上面畫紅框的地方,這是默認分配給你的ip,下面會用到。至此,docker工具就已經安裝好了。 -
安裝Splash
雙擊運行Docker Quickstart Terminal,輸入以下內容
docker pull scrapinghub/splash
這個命令是拉取Splash鏡像,等待一算時間,就可以了。下面就是啟動Splash
docker run -p 8050:8050 scrapinghub/splash
這個命令就是在計算機的8050端口啟動Splash渲染服務
你會看到以下的圖示內容。
這個時候,打開你的瀏覽器,輸入
192.168.99.100:8050
你會看到出現了這樣的界面。
你可以在上圖紅色框框的地方輸入任意的網址,點擊后面的Render me! 來查看渲染之后的樣子。 -
安裝scrapy-splash
pip install scrapy-splash
至此,我們的准備環節已經全部結束了。
測試
下面我們就創建一個項目來測試一下,是否真的實現了我們想要的功能。
不使用scrapy-splash
為了有一個直觀的對比,我們首先不使用scrapy- splash,來看一下是什么效果,我們以淘寶商品信息為例,新建一個名為taobao的項目,在spider.py文件里面輸入下面的內容。
import scrapy
class Spider(scrapy.Spider):
name = 'taobao'
allowed_domains = []
start_urls = ['https://s.taobao.com/search?q=%E7%BE%8E%E9%A3%9F']
def start_requests(self):
for url in self.start_urls:
yield scrapy.Request(url=url, callback=self.parse)
def parse(self,response):
titele = response.xpath('//div[@class="row row-2 title"]/a/text()').extract()
print('這是標題:', titele)
我們打印出淘寶美食的名稱,你會看到這樣的信息:
使用scrapy-splash
下面我們使用scrapy-splash來實現一下,看一下會出現什么樣的效果:
使用scrapy-splash需要一些額外的配置,下面一一列舉:
在settings.py文件中,你需要額外的填寫下面的一些內容
# 渲染服務的url
SPLASH_URL = 'http://192.168.99.100:8050'
#下載器中間件
DOWNLOADER_MIDDLEWARES = {
'scrapy_splash.SplashCookiesMiddleware': 723,
'scrapy_splash.SplashMiddleware': 725,
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}
# 去重過濾器
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
# 使用Splash的Http緩存
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
在spider.py文件中,填入下面的代碼:
import scrapy
from scrapy_splash import SplashRequest
class Spider(scrapy.Spider):
name = 'taobao'
allowed_domains = []
start_urls = ['https://s.taobao.com/search?q=%E7%BE%8E%E9%A3%9F']
def start_requests(self):
for url in self.start_urls:
yield SplashRequest(url=url, callback=self.parse,
args={'wait':1}, endpoint='render.html')
def parse(self, response):
titele = response.xpath('//div[@class="row row-2 title"]/a/text()').extract()
print('這是標題:', titele)
記住不要忘記導入SplashRequest
。
下面就是運行這個項目,記得在docker里面先把splash渲染服務運行起來。
結果如下圖所示。
看的出來,我們需要的內容已經打印出來了,內容有點亂,我們可以使用正則來進行匹配,但是這已經不是我們這一小節的主要內容了,你可以自己嘗試一下。