雲服務器下docker部署scrapyd之一:Scrapyd的容器化

一.部署前的準備

在開始部署之前,先梳理一下幾個關鍵詞:

1.Scrapy

Scrapy是一個基於Twisted的異步處理框架,是純Python實現的爬蟲框架。Scrapy由Spider、Middleware、Downloader、Pipeline等組成,各個模塊之間耦合度低,擴展性強。Scrapy的整體結構如下:

圖1:Scrapy架構

 

2.Scrapyd

Scrapyd是一個用於部署和運行scrapy項目的工具,通過Scrapyd可以將已經寫好的Scrapy項目上傳到雲主機並通過scrapyd提供的Restful API來控制它們的運行。

3.Scrapyd-Client

在將Scrapy代碼部署到遠程Scrapyd的時候,第一步就是要將代碼打包爲EGG文件(EGG是二進制文件),其次需要將EGG文件上傳到雲主機。這個過程可以使用程序實現,也可以使用Scrapyd-Client來實現。

圖2:Scrapyd-Client和Scrapyd的通信

 以圖2爲例子,客戶端做的有兩個操作:

  1. 通過Scrapyd-Client打包Scrapy項目併發送到對應的已經在運行Scrapyd進程的服務器上;
  2. 客戶端通過發送HTTP請求來獲取或者控制爬蟲的運行。

二.Scrapyd的Docker化

在把Scrapyd放入容器之前,首先要考慮需要什麼。

1.scrapyd的運行依賴庫

需要一個requirements.txt文件來安裝scrapyd的依賴文件,解決辦法是在本地開發scrapy的時候使用到python的虛擬環境,比如virtualenv,以便於版本控制和導出requirements.txt。

對於開發來說,環境配置一直就是個問題,最大的問題就是版本不一致。在Python中,可以使用virtualenv來解決上面的問題,但是virtualenv對於項目部署來說並不方便,而此時使用Docker則是更好的選擇。

項目鏈接:https://github.com/sky94520/ScrapyTutorial

上面的項目爲scrapy的一個簡例,它的任務就是爬取http://quotes.toscrape.com/網站的名言,並把這些數據存儲到mongodb中去。如果對mongodb不熟悉的可以改爲存在csv文件或者json文件中,只需要添加一個對應的pipeline即可。 

上面的這個例子包含了兩個標籤(tag):mongodbjson。mongodb標籤將會把數據保存到mongodb中;而json標籤將會把數據保存到quotes.json文件中。

使用git clone https://github.com/sky94520/ScrapyTutorial.git 把項目從github中克隆下來;然後在控制檯中切換到對應的標籤,比如這裏要切換到json標籤,需要鍵入:

git checkout json
圖3:ScrapyTutorial項目結構

這裏使用的是windows環境下的cmd。在項目根目錄下,使用下面的命令進入到虛擬環境下:

venv\Scripts\activate

如果執行成功的話會出現下面這樣:

圖4:虛擬環境

 此時無論是執行python文件、還是安裝/卸載庫都是隻會影響這個虛擬環境。

接着就可以導出該環境下的依賴庫文件:

pip freeze > requirements.txt

 requirements.txt文件顯示如下:

asn1crypto==0.24.0
attrs==19.1.0
Automat==0.7.0
cffi==1.12.3
constantly==15.1.0
cryptography==2.6.1
cssselect==1.0.3
hyperlink==19.0.0
idna==2.8
incremental==17.5.0
lxml==4.3.3
parsel==1.5.1
pyasn1==0.4.5
pyasn1-modules==0.2.5
pycparser==2.19
PyDispatcher==2.0.5
PyHamcrest==1.9.0
pymongo==3.8.0
pyOpenSSL==19.0.0
pywin32==224
queuelib==1.5.0
Scrapy==1.6.0
service-identity==18.1.0
six==1.12.0
Twisted==18.9.0
w3lib==1.20.0
zope.interface==4.6.0

注:Twisted的版本爲18.9.0,scrapy的版本爲scrapy==1.6.0,否則scrapyd的網頁訪問將會出錯。 另外,在虛擬環境下輸入deactivate表示退出虛擬環境


 2.外網可以訪問Scrapyd

可以參考官方網站https://scrapyd.readthedocs.io/en/latest/config.html,要了解的主要包括配置文件和配置文件的路徑;由於這裏使用的是ubuntu,所以配置文件放在/etc/scrapyd/目錄下,配置文件scrapyd.conf內容如下:

[scrapyd]
eggs_dir    = eggs
logs_dir    = logs
items_dir   =
jobs_to_keep = 5
dbs_dir     = dbs
max_proc    = 0
max_proc_per_cpu = 4
finished_to_keep = 100
poll_interval = 5.0
bind_address = 0.0.0.0
http_port   = 6800
debug       = off
runner      = scrapyd.runner
application = scrapyd.app.application
launcher    = scrapyd.launcher.Launcher
webroot     = scrapyd.website.Root

[services]
schedule.json     = scrapyd.webservice.Schedule
cancel.json       = scrapyd.webservice.Cancel
addversion.json   = scrapyd.webservice.AddVersion
listprojects.json = scrapyd.webservice.ListProjects
listversions.json = scrapyd.webservice.ListVersions
listspiders.json  = scrapyd.webservice.ListSpiders
delproject.json   = scrapyd.webservice.DeleteProject
delversion.json   = scrapyd.webservice.DeleteVersion
listjobs.json     = scrapyd.webservice.ListJobs
daemonstatus.json = scrapyd.webservice.DaemonStatus

 上面的是官方提供的一個配置文件,這裏的修改僅僅是把bind_address由127.0.0.1修改爲了0.0.0.0,以使得外網可以訪問scrapyd。

3.Docker鏡像

接下來則是Dockerfile的編寫了。

首先可以在雲服務器上/home/下創建一個scrapy_test來保存配置文件和Dockerfile。項目結構如下:

圖5:目錄結構

在圖5中,Dockerfile爲構建docker鏡像的配置文件;requirements.txt爲 scrapyd所依賴的環境;而scrapyd.conf則是scrapyd運行所需的配置文件。

Dockerfile文件內容如下:

FROM python:3.7
ENV REFRESHED_AT 2019-05-30
ENV PATH /usr/local/bin:$PATH

#add the scrapyd configure file
ADD ./scrapyd.conf /etc/scrapyd/scrapyd.conf

#add requirements.txt
ADD requirements.txt /opt/requirements.txt
WORKDIR /opt

#use other fast image
RUN pip3 install  -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt

CMD ["scrapyd"]

EXPOSE 6800

 首先,這個鏡像是基於python3.7的,所以需要先拉取鏡像:

docker pull python:3.7

 其次,在環境中設置了一個REFRESHED_AT變量,由於docker build運行Dockerfile是每一個指令創建一個鏡像的,而指令內容的變化會使得從它開始的鏡像全都重新生成,所以可以通過修改REFRESHED_AT來控制鏡像的更新。

之後,把scrapyd.conf放到了/etc/scrapyd/目錄下,而requirements.txt 放到了/opt/目錄下(放在其他目錄也可以),然後設置/opt爲工作路徑,之後使用pip來安裝依賴環境。爲了使得pip下載庫更快一些而使用了清華的鏡像;

最後的CMD則是可以在docker run不添加命令的時候直接啓動scrapyd,最後則是暴露的6800端口。

然後就可以在本文件夾中使用docker build來構建鏡像了:

docker build -t xiaoniu/scrapyd .

 構建成功後可以查看鏡像:

docker images

 

圖6:查看鏡像

最後則是運行:

docker run -d -p 6800:6800 --name=scrapyd xiaoniu/scrapyd

 -p 6800:6800表示的是開放容器的6800端口(這裏要確保主機的6800端口沒有被佔用),並把它和外部服務器的6800端口對應起來。

 之後輸入:

docker ps -l

 顯示:

圖7:查看容器運行狀態

可以看到我們創建的鏡像已經在運行了,並且開放了6800端口。 

三.測試環境

如果服務器的6800端口已經開放(阿里雲需要手動開放端口,參考鏈接),則可以直接在瀏覽器訪問到scrapyd:

圖8:查看scrapyd提供的網頁

 注意:如果scrapy和Twisted的版本不正確的話,Job網頁會出現錯誤.

四.Scrapyd-Client的安裝與操作

在終端環境下輸入下面的指令來安裝scrapyd-client:

pip install scrapyd-client

 scrapyd-client的安裝最好是在非虛擬環境下,從圖2中可以看出,我們使用這個庫僅僅是爲了打包scrapy項目併發送給服務器,所以沒必要在虛擬環境下安裝。

安裝成功後會有一個可用的命令,叫做scrapyd-deploy,不過在windows下這個命令是無法直接用的。

首先,需要確定python的安裝位置,我這裏的安裝路徑爲:

C:\Users\lbb\AppData\Local\Programs\Python\Python37\Scripts

在這裏應該可以看到dcrapyd-deploy這個文件:

圖9:目錄

 通過ubuntu的file命令(win10的應用商店中可以安裝ubuntu),可以稍微瞭解到這個文件的類型:

圖10:查看scrapyd-deploy文件類型

 如果想執行的話,那麼還需要一個批處理文件scrapy-deploy.bat來執行這個python腳本:

@echo off

"C:\Users\lbb\AppData\Local\Programs\Python\Python37\python.exe" "C:\Users\lbb\AppData\Local\Programs\Python\Python37\Scripts\scrapyd-deploy" %1 %2 %3 %4 %5 %6 %7 %8 %9

注意:請根據自己的安裝路徑然後修改scrapy-deploy.bat腳本的路徑。 

 接着就可以打包併發送scrapy文件了。回到ScrapyTutorial的項目根目錄下,打開scrapy.cfg文件:

[settings]
default = tutorial.settings

[deploy:demo]
url = http://localhost:6800/
project = tutorial

把url的值改爲自己的服務器的IP地址。然後在項目根目錄下打開控制檯,輸入:

scrapyd-deploy demo -p tutorial

 如果結果如下,則表示上傳到服務器成功!

圖11:上傳到服務器

接着可以在IP:6800上查看:

圖12:顯示可用工程

五.發起操作

從圖12中可以看到,scrapyd通過HTTP來發送請求的,而curl也可以發送HTTP請求,所以示例中使用到了curl。這裏同樣以curl爲例,注意把以下命令的localhost改爲服務器的IP地址。

1.獲取服務器狀態

curl http://localhost:6800/daemonstatus.json

 

圖13:顯示服務器狀態

2.運行爬蟲

curl http://localhost:6800/schedule.json -d project=tutorial -d spider=quotes

 

圖14:運行爬蟲

 此時再看scrapyd的Jobs:

圖15:爬蟲工作情況

能夠發現開啓的爬蟲已經運行完畢,總共運行了8秒左右。 

更多的命令請參考:https://scrapyd.readthedocs.io/en/latest/api.html

六.反向代理+身份驗證

配置完成後,Scrapyd和它的接口都是可以公開訪問的。如果想配置訪問認證的話,可以藉助於Nginx做反向代理。

雲服務器下docker部署scrapyd之二:使用Nginx對Scrapyd添加驗證

七.總結

1.curl的作用可以簡單的認爲和瀏覽器的作用差不多。

2.可以專門創建一個容器來對爬蟲進行管理,比如定時定點開啓爬蟲,這對於scrapyd是可以做到的。比如週一的凌晨2點到3點開始爬取數據,那麼我可以把這些數據寫入到容器的一個配置文件裏,然後在這個容器裏開啓一個進程,讓它一直檢測這個配置文件,來判斷是否需要開啓或者關閉爬蟲。

3.創建的scrapyd容器的requirements.txt僅僅包含了必要的庫,它並不能滿足所有的情況,如果一個其他的scrapy項目需要用到第三方庫,那麼在上傳的時候沒有問題,但是在運行的時候則會因爲找不到這個庫而出錯。解決辦法就是需要進入到scrapyd容器中手動加入某些庫。

 

參考鏈接:

Scrapyd使用教程

scrapyd 問題 builtins.AttributeError: 'int' object has no attribute 'splitlines'

解決python各類庫安裝包下載太慢速度問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章