前言
我的京東價(jià)格監(jiān)控網(wǎng)站需要不間斷爬取京東商品頁(yè)面雕擂,爬蟲模塊我采用了Scrapy+selenium+Headless Chrome的方式進(jìn)行商品信息的采集偏序。
由于最近爬蟲用的服務(wù)器到期,需要換到新服務(wù)器重新部署了赵,所以干脆把整個(gè)模塊封裝入Docker问拘,以便后續(xù)能夠方便快速的進(jìn)行爬蟲的部署。同時(shí)冯勉,由于我的Scrapy整合了redis,能夠支持分布式爬取摹芙,Docker化后也更方便進(jìn)行分布式的拓展灼狰。
任務(wù)需求
- 將爬蟲代碼打包為Docker鏡像
- 在全新的服務(wù)器上安裝Docker
- 使用單獨(dú)的Redis容器作為爬取url隊(duì)列(也就是Scrapy-redis中redis的主要用處)
- 所有新開的爬蟲容器連接Redis容器
步驟
打包爬蟲代碼
Scrapy內(nèi)置的crawler不支持頁(yè)面渲染的方式進(jìn)行頁(yè)面渲染,需要使用scrapy-splash或者selenium作為中間件浮禾,才能夠支持頁(yè)面渲染爬取交胚。我在代碼中整合了selenium,并在系統(tǒng)中安裝了chrome盈电,這在docker中蝴簇,需要在打包時(shí)將chrome安裝至鏡像中。
Dockerfile文件中匆帚,將chrome下載并安裝至鏡像熬词,并且將chromedriver放入系統(tǒng),保證selenium代碼能夠調(diào)用到chrome吸重。
我參考了開源庫(kù):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避免吧沒用的文件打包進(jìn)鏡像嚎幸。
我打包的代碼結(jié)構(gòu)圖如下:
使用命令颜矿,生成鏡像:
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,大的嚇人嫉晶。
運(yùn)行redis容器
鏡像打包好之后骑疆,別急著運(yùn)行,因?yàn)樾路?wù)器上替废,Redis還沒有呢箍铭。
原則上來說,你可以使用docker-compose椎镣,把redis和爬蟲代碼兩個(gè)鏡像同時(shí)運(yùn)行起來诈火。
我這里,我將redis開啟單獨(dú)的鏡像衣陶,一是為了方便其它模塊使用redis柄瑰,二是方便以后開更多的scrapy進(jìn)行分布式爬取闸氮。
使用官方的redis鏡像開啟redis容器,并將redis端口映射到宿主機(jī)6379:
docker run -p 6379:6379 -d redis --requirepass "密碼"
官方的redis設(shè)置中默認(rèn)就是0.0.0.0教沾,不用擔(dān)心宿主機(jī)無法訪問蒲跨。
連接爬蟲容器和redis容器
接下來可以運(yùn)行爬蟲容器,需要注意的是授翻,連接兩個(gè)容器或悲,需要使用link。
首先找到redis容器的ID堪唐,或者你給他自定義的名字
接著運(yùn)行并連接容器:
sudo docker container run -itd --link 00c2655515fb:redis pm_scrapy
出現(xiàn)問題:Docker 使用--link出現(xiàn)Cannot link to /xxx, as it does not belong to xxxxx異常
這個(gè)異常的原因是redis在一個(gè)特殊的網(wǎng)絡(luò)里巡语,你需要用:
docker inspect [需要link的容器名稱或ID]
來查看redis容器所在的網(wǎng)段。
同時(shí)還可以看看
docker network ls
之后你就需要類似這樣的語句(多指定--net來定下容器所在網(wǎng)絡(luò)):
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
http://www.reibang.com/p/21d66ca6115e
跑代碼
一切就緒淮菠,發(fā)現(xiàn)爬蟲沒法運(yùn)行男公,使用docker logs 容器ID
查看log。發(fā)現(xiàn)問題
出現(xiàn)問題:headless chrome:DevToolsActivePort file doesn't exist while trying to initiate Chrome Browser
這個(gè)問題參考下面的網(wǎng)址合陵,這里直接給出解決方案枢赔,在你的代碼里加一行參數(shù):
chrome_options.add_argument('--disable-dev-shm-usage')
這是我的代碼截圖:
參考:
對(duì)該容器的日常維護(hù)
平日里可以使用docker exec -it 21323a52d19f /bin/bash
進(jìn)入正在運(yùn)行容器的bash,查看下爬蟲狀態(tài)