在使用scrapy抓取網頁時, 如果遇到使用js動態渲染的頁面, 將無法提取到在瀏覽器中看到的內容. 針對這個問題scrapy官方給出的方案是scrapy selenium, 這是一個把selenium集成到scrapy的開源項目, 它使用selenium抓取已經渲染好(js代碼已經執行完成)的動態 ...
在使用scrapy抓取網頁時, 如果遇到使用js動態渲染的頁面, 將無法提取到在瀏覽器中看到的內容. 針對這個問題scrapy官方給出的方案是scrapy-selenium, 這是一個把selenium集成到scrapy的開源項目, 它使用selenium抓取已經渲染好(js代碼已經執行完成)的動態網頁.
事實上selenium自己也沒有渲染動態網頁的能力,它還是得依賴瀏覽器, 用瀏覽器作為動態網頁的渲染引擎. 目前主流的瀏覽器都能以headless模式運行, 即沒有圖形界面只有命令行界面. 同時提供了驅動程式和headless模式運行的瀏覽器交互的驅動, 驅動程式提供了一些API, 用於控制瀏覽器的行為, 如: 拖動滾動條, 生成網頁縮略圖等. selenium整合了這些瀏覽器驅動, 讓用戶可以用統一的介面和不同的瀏覽器進行交互, 所以selenium本質上就是一個adapter.
本文以chrome瀏覽器為網頁渲染引擎, 完整地講解抓取動態網頁的方法.
第一步 安裝chrome
本人長期在linux伺服器平臺下工作, 所以使用的環境是ubuntu-18.04.3-live-server. 以前還沒在伺服器安裝過瀏覽器, 也挺陌生的. 首先進入chrome的官網https://www.google.cn/chrome/ 下載安裝包google-chrome-stable_current_amd64.deb. 在頁面底部,有個”其他平臺“鏈接, 點進去找到這個安裝包.
安裝chrome: sudo dpkg -i google-chrome-stable_current_amd64.deb
出現依賴問題, 修複: sudo apt --fix-broken install
再次安裝就可以了.
找個網站驗證一下chrome是否能夠正常工作:
google-chrome --headless --no-sandbox --disable-gpu --dump-dom https://www.gushiwen.org/ >> index.html
如果在當前目錄下能夠正常的生成index.html文件,表示chrome已經安裝成功.
第二步 安裝scrapy-selenium, chromedriver
安裝scrapy-selenium: pip install scrapy-selenium
查看你的chrome版本: google-chrome --version
Google Chrome 80.0.3987.149
在這裡http://chromedriver.storage.googleapis.com/index.html找到對應版本的chromedriver. 我用的dirver是http://chromedriver.storage.googleapis.com/80.0.3987.16/chromedriver_linux64.zip.
手動安裝dirver:
unzip chromedriver_linux64.zip
chmod a+x chromedriver
cp chromedriver /usr/bin/
這樣就把chromedriver安裝到/usr/bin目錄下了.
第三步 為你的scrapy項目配置好scrapy-selenium
在scrapy項目的settings.py文件中添加如下代碼配置scrapy-selenium
SELENIUM_DRIVER_NAME = 'chrome' #瀏覽器driver名字
SELENIUM_DRIVER_EXECUTABLE_PATH = '/usr/bin/chromedriver' #瀏覽器driver的位置
#chrome瀏覽器的參數
SELENIUM_DRIVER_ARGUMENTS=['--headless', '--no-sandbox', '--disable-gpu']
#下載器中間件配置
DOWNLOADER_MIDDLEWARES = {
'scrapy_selenium.SeleniumMiddleware': 800
}
創建一個spider驗證一下scrapy-selenium是否可用
import scrapy
from scrapy_selenium import SeleniumRequest
class Myspider(scrapy.Spider):
name = "myspider"
def start_requests(self):
#這裡使用SeleniumRequest抓取頁面, 在parse中抓取頁面也要用它
yield SeleniumRequest(url='https://www.gushiwen.org/', callback=self.parse)
def parse(self, response):
with open('index.html', 'wb') as f:
f.write(response.body)
運行這個spider
scrapy crawl myspider
在當前目錄就會有一個index.html文件. 如果正常的話會發現使用js動態生成的內容已經被渲染到dom文檔中了.
現在已經成功地抓取到一個動態頁面啦!