1. 程式人生 > 實用技巧 >Docker部署Scrapy-redis分散式爬蟲框架(整合Selenium+Headless Chrome網頁渲染)

Docker部署Scrapy-redis分散式爬蟲框架(整合Selenium+Headless Chrome網頁渲染)

前言

我的京東價格監控網站需要不間斷爬取京東商品頁面,爬蟲模組我採用了Scrapy+selenium+Headless Chrome的方式進行商品資訊的採集。

由於最近爬蟲用的伺服器到期,需要換到新伺服器重新部署,所以乾脆把整個模組封裝入Docker,以便後續能夠方便快速的進行爬蟲的部署。同時,由於我的Scrapy整合了redis,能夠支援分散式爬取,Docker化後也更方便進行分散式的拓展。

任務需求

  • 將爬蟲程式碼打包為Docker映象
  • 在全新的伺服器上安裝Docker
  • 使用單獨的Redis容器作為爬取url佇列(也就是Scrapy-redis中redis的主要用處)
  • 所有新開的爬蟲容器連線Redis容器

步驟

打包爬蟲程式碼

Scrapy內建的crawler不支援頁面渲染的方式進行頁面渲染,需要使用scrapy-splash或者selenium作為中介軟體,才能夠支援頁面渲染爬取。我在程式碼中整合了selenium,並在系統中安裝了chrome,這在docker中,需要在打包時將chrome安裝至映象中。

Dockerfile檔案中,將chrome下載並安裝至映象,並且將chromedriver放入系統,保證selenium程式碼能夠呼叫到chrome。

我參考了開源庫:https://github.com/joyzoursky/docker-python-chromedriver

最後完成的Dockerfile檔案:

FROM python:3.6

# install google chrome
RUN wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
RUN apt-get -y update
RUN apt-get install -y google-chrome-stable

# install chromedriver
RUN apt-get install -yqq unzip
RUN wget -O /tmp/chromedriver.zip http://chromedriver.storage.googleapis.com/`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip
RUN unzip /tmp/chromedriver.zip chromedriver -d /usr/local/bin/

# set display port to avoid crash
ENV DISPLAY=:99

# copy pm_scrapy
WORKDIR /usr/src/app
COPY . .

# install requirements
RUN pip install -r requirements.txt

CMD scrapy crawl JDcate

寫完Docker檔案,在打包前,最好還要加上.dockerignore避免吧沒用的檔案打包進映象。

我打包的程式碼結構圖如下:

使用命令,生成映象:

 sudo docker image build -t pm_scrapy .   
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
pm_scrapy           latest              082e7e350831        47 hours ago        1.41 GB
proxy_pool          latest              83a95913162b        6 days ago          1.01 GB
python              3.6                 749d36d00e00        10 days ago         921 MB
redis               latest              5d2989ac9711        10 days ago         95 MB

1.41G,大的嚇人。

執行redis容器

映象打包好之後,別急著執行,因為新伺服器上,Redis還沒有呢。

原則上來說,你可以使用docker-compose,把redis和爬蟲程式碼兩個映象同時執行起來。

我這裡,我將redis開啟單獨的映象,一是為了方便其它模組使用redis,二是方便以後開更多的scrapy進行分散式爬取。

使用官方的redis映象開啟redis容器,並將redis埠對映到宿主機6379:

docker run -p 6379:6379  -d redis --requirepass "密碼"

官方的redis設定中預設就是0.0.0.0,不用擔心宿主機無法訪問。

連線爬蟲容器和redis容器

接下來可以執行爬蟲容器,需要注意的是,連線兩個容器,需要使用link。

首先找到redis容器的ID,或者你給他自定義的名字

接著執行並連線容器:

sudo docker container run -itd --link 00c2655515fb:redis pm_scrapy

這個異常的原因是redis在一個特殊的網路裡,你需要用:

docker inspect [需要link的容器名稱或ID]

來檢視redis容器所在的網段。

同時還可以看看

docker network ls

之後你就需要類似這樣的語句(多指定--net來定下容器所在網路):

docker run -d --name movie_project -p 9090:80 --link 容器名:別名 --net link_continer_network -v /root/project/movie_project:/app:Z python2/nginx/flask

參考:

https://blog.csdn.net/hanchaobiao/article/details/81911587
https://www.jianshu.com/p/21d66ca6115e

跑程式碼

一切就緒,發現爬蟲沒法執行,使用docker logs 容器ID檢視log。發現問題

出現問題:headless chrome:DevToolsActivePort file doesn't exist while trying to initiate Chrome Browser

這個問題參考下面的網址,這裡直接給出解決方案,在你的程式碼里加一行引數:

chrome_options.add_argument('--disable-dev-shm-usage')

這是我的程式碼截圖:

參考:

https://stackoverflow.com/questions/50642308/org-openqa-selenium-webdriverexception-unknown-error-devtoolsactiveport-file-d/50642913#50642913

對該容器的日常維護

平日裡可以使用docker exec -it 21323a52d19f /bin/bash進入正在執行容器的bash,檢視下爬蟲狀態

關注我

本人目前為後臺開發工程師,主要關注Python爬蟲,後臺開發等相關技術。

原創部落格主要內容:

  • 筆試面試複習知識點手冊
  • Leetcode演算法題解析(前150題)
  • 劍指offer演算法題解析
  • Python爬蟲相關實戰
  • 後臺開發相關實戰

同步更新以下幾大部落格:

  • Csdn:

http://blog.csdn.net/qqxx6661

擁有專欄:Leetcode題解(Java/Python)、Python爬蟲開發

  • 知乎:

https://www.zhihu.com/people/yang-zhen-dong-1/

擁有專欄:碼農面試助攻手冊

  • 掘金:

https://juejin.im/user/2119514149109095

  • 簡書:

https://www.jianshu.com/u/b5f225ca2376

  • 個人公眾號:Rude3Knife