環境配置問題可能一直會讓我們頭疼,包括如下幾種情況。
我們在本地寫好了一個Scrapy爬蟲專案,想要把它放到伺服器上執行,但是伺服器上沒有安裝Python環境。
其他人給了我們一個Scrapy爬蟲專案,專案使用包的版本和本地環境版本不一致,專案無法直接執行。
我們需要同時管理不同版本的Scrapy專案,如早期的專案依賴於Scrapy 0.25,現在的專案依賴於Scrapy 1.4.0。
在這些情況下,我們需要解決的就是環境的安裝配置、環境的版本衝突解決等問題。
對於Python來說,VirtualEnv的確可以解決版本衝突的問題。但是,VirtualEnv不太方便做專案部署,我們還是需要安裝Python環境,
如何解決上述問題呢?答案是用Docker。Docker可以提供作業系統級別的虛擬環境,一個Docker映象一般都包含一個完整的作業系統,而這些系統內也有已經配置好的開發環境,如Python 3.6環境等。
我們可以直接使用此Docker的Python 3映象執行一個容器,將專案直接放到容器裡執行,就不用再額外配置Python 3環境。這樣就解決了環境配置的問題。
我們也可以進一步將Scrapy專案製作成一個新的Docker映象,映象裡只包含適用於本專案的Python環境。如果要部署到其他平臺,只需要下載該映象並執行就好了,因為Docker執行時採用虛擬環境,和宿主機是完全隔離的,所以也不需要擔心環境衝突問題。
如果我們能夠把Scrapy專案製作成一個Docker映象,只要其他主機安裝了Docker,那麼只要將映象下載並執行即可,而不必再擔心環境配置問題或版本衝突問題。
接下來,我們嘗試把一個Scrapy專案製作成一個Docker映象。
一、本節目標
我們要實現把前文Scrapy的入門專案打包成一個Docker映象的過程。專案爬取的網址為:http://quotes.toscrape.com/。本章Scrapy入門一節已經實現了Scrapy對此站點的爬取過程,專案程式碼為:https://github.com/Python3WebSpider/ScrapyTutorial。如果本地不存在的話可以將程式碼Clone下來。
二、準備工作
請確保已經安裝好Docker和MongoDB並可以正常執行。
三、建立Dockerfile
首先在專案的根目錄下新建一個requirements.txt檔案,將整個專案依賴的Python環境包都列出來,如下所示:
scrapy
pymongo複製程式碼
如果庫需要特定的版本,我們還可以指定版本號,如下所示:
scrapy>=1.4.0
pymongo>=3.4.0複製程式碼
在專案根目錄下新建一個Dockerfile檔案,檔案不加任何字尾名,修改內容如下所示:
FROM python:3.6
ENV PATH /usr/local/bin:$PATH
ADD . /code
WORKDIR /code
RUN pip3 install -r requirements.txt
CMD scrapy crawl quotes複製程式碼
第一行的FROM
代表使用的Docker基礎映象,在這裡我們直接使用python:3.6的映象,在此基礎上執行Scrapy專案。
第二行ENV
是環境變數設定,將/usr/local/bin:$PATH
賦值給PATH
,即增加/usr/local/bin
這個環境變數路徑。
第三行ADD
是將本地的程式碼放置到虛擬容器中。它有兩個引數:第一個引數是.
,代表本地當前路徑;第二個引數是/code
,代表虛擬容器中的路徑,也就是將本地專案所有內容放置到虛擬容器的/code目錄下,以便於在虛擬容器中執行程式碼。
第四行WORKDIR
是指定工作目錄,這裡將剛才新增的程式碼路徑設成工作路徑。這個路徑下的目錄結構和當前本地目錄結構是相同的,所以我們可以直接執行庫安裝命令、爬蟲執行命令等。
第五行RUN
是執行某些命令來做一些環境準備工作。由於Docker虛擬容器內只有Python 3環境,而沒有所需要的Python庫,所以我們執行此命令來在虛擬容器中安裝相應的Python庫如Scrapy,這樣就可以在虛擬容器中執行Scrapy命令了。
第六行CMD
是容器啟動命令。在容器執行時,此命令會被執行。在這裡我們直接用scrapy crawl quotes來啟動爬蟲。
四、修改MongDB連線
接下來我們需要修改MongoDB的連線資訊。如果我們繼續用localhost是無法找到MongoDB的,因為在Docker虛擬容器裡localhost實際指向容器本身的執行IP,而容器內部並沒有安裝MongoDB,所以爬蟲無法連線MongoDB。
這裡的MongoDB地址可以有如下兩種選擇。
如果只想在本機測試,我們可以將地址修改為宿主機的IP,也就是容器外部的本機IP,一般是一個區域網IP,使用
ifconfig
命令即可檢視。如果要部署到遠端主機執行,一般MongoDB都是可公網訪問的地址,修改為此地址即可。
在本節中,我們的目標是將專案打包成一個映象,讓其他遠端主機也可執行這個專案。所以我們直接將此處MongoDB地址修改為某個公網可訪問的遠端資料庫地址,修改MONGO_URI
如下所示:
MONGO_URI = 'mongodb://admin:admin123@120.27.34.25:27017'複製程式碼
此處地址可以修改為自己的遠端MongoDB資料庫地址。
這樣專案的配置就完成了。
五、構建映象
接下來我們構建Docker映象,執行如下命令:
docker build -t quotes:latest .複製程式碼
執行過程中的輸出如下所示:
Sending build context to Docker daemon 191.5 kB
Step 1/6 : FROM python:3.6
---> 968120d8cbe8
Step 2/6 : ENV PATH /usr/local/bin:$PATH
---> Using cache
---> 387abbba1189
Step 3/6 : ADD . /code
---> a844ee0db9c6
Removing intermediate container 4dc41779c573
Step 4/6 : WORKDIR /code
---> 619b2c064ae9
Removing intermediate container bcd7cd7f7337
Step 5/6 : RUN pip3 install -r requirements.txt
---> Running in 9452c83a12c5
...
Removing intermediate container 9452c83a12c5
Step 6/6 : CMD scrapy crawl quotes
---> Running in c092b5557ab8
---> c8101aca6e2a
Removing intermediate container c092b5557ab8
Successfully built c8101aca6e2a複製程式碼
這樣的輸出就說明映象構建成功。這時我們檢視一下構建的映象,如下所示:
docker images複製程式碼
返回結果中的一行程式碼如下所示:
quotes latest 41c8499ce210 2 minutes ago 769 MB複製程式碼
這就是我們新構建的映象。
六、執行
映象可以先在本地測試執行,我們執行如下命令:
docker run quotes複製程式碼
這樣我們就利用此映象新建並執行了一個Docker容器,執行效果完全一致,如下圖所示。
如果出現類似圖上的執行結果,這就證明構建的映象沒有問題。
七、推送至Docker Hub
構建完成之後,我們可以將映象Push到Docker映象託管平臺,如Docker Hub或者私有的Docker Registry等,這樣我們就可以從遠端伺服器下拉映象並執行了。
以Docker Hub為例,如果專案包含一些私有的連線資訊(如資料庫),我們最好將Repository設為私有或者直接放到私有的Docker Registry。
首先在https://hub.docker.com註冊一個賬號,新建一個Repository,名為quotes。比如,我的使用者名稱為germey,新建的Repository名為quotes,那麼此Repository的地址就可以用germey/quotes來表示。
為新建的映象打一個標籤,命令如下所示:
docker tag quotes:latest germey/quotes:latest複製程式碼
Push映象到Docker Hub即可,命令如下所示:
docker push germey/quotes複製程式碼
Docker Hub便會出現新Push的Docker映象了,如下圖所示。
如果我們想在其他的主機上執行這個映象,主機上裝好Docker後,可以直接執行如下命令:
docker run germey/quotes複製程式碼
這樣就會自動下載映象,啟動容器執行。不需要配置Python環境,不需要關心版本衝突問題。
執行效果如下圖所示。
整個專案爬取完成後,資料就可以儲存到指定的資料庫中。
八、結語
我們講解了將Scrapy專案製作成Docker映象並部署到遠端伺服器執行的過程。使用此種方式,我們在本節開頭所列出的問題都迎刃而解。
本資源首發於崔慶才的個人部落格靜覓: Python3網路爬蟲開發實戰教程 | 靜覓
如想了解更多爬蟲資訊,請關注我的個人微信公眾號:進擊的Coder
weixin.qq.com/r/5zsjOyvEZ… (二維碼自動識別)