分散式爬蟲的部署之Scrapyd分散式部署

崔慶才丨靜覓發表於2018-05-30

分散式爬蟲完成並可以成功執行了,但是有個環節非常煩瑣,那就是程式碼部署。

我們設想下面的幾個場景。

  • 如果採用上傳檔案的方式部署程式碼,我們首先將程式碼壓縮,然後採用SFTP或FTP的方式將檔案上傳到伺服器,之後再連線伺服器將檔案解壓,每個伺服器都需要這樣配置。

  • 如果採用Git同步的方式部署程式碼,我們可以先把程式碼Push到某個Git倉庫裡,然後再遠端連線各臺主機執行Pull操作,同步程式碼,每個伺服器同樣需要做一次操作。

如果程式碼突然有更新,那我們必須更新每個伺服器,而且萬一哪臺主機的版本沒控制好,這可能會影響整體的分散式爬取狀況。

所以我們需要一個更方便的工具來部署Scrapy專案,如果可以省去一遍遍逐個登入伺服器部署的操作,那將會方便很多。

本節我們就來看看提供分散式部署的工具Scrapyd。

一、瞭解Scrapyd

Scrapyd是一個執行Scrapy爬蟲的服務程式,它提供一系列HTTP介面來幫助我們部署、啟動、停止、刪除爬蟲程式。Scrapyd支援版本管理,同時還可以管理多個爬蟲任務,利用它我們可以非常方便地完成Scrapy爬蟲專案的部署任務排程。

二、準備工作

請確保本機或伺服器已經正確安裝好了Scrapyd。

三、訪問Scrapyd

安裝並執行Scrapyd之後,我們就可以訪問伺服器的6800埠,看到一個WebUI頁面。例如我的伺服器地址為120.27.34.25,那麼我就可以在本地的瀏覽器中開啟:http://120.27.34.25:6800,就可以看到Scrapyd的首頁。這裡可以替換成你的伺服器地址,如下圖所示分散式爬蟲的部署之Scrapyd分散式部署成功訪問到此頁面,則Scrapyd配置就沒有問題。

四、Scrapyd的功能

Scrapyd提供了一系列HTTP介面來實現各種操作。在這裡以Scrapyd所在的IP地址120.27.34.25為例,我們可以將介面的功能梳理一下。

1. daemonstatus.json

這個介面負責檢視Scrapyd當前的服務和任務狀態。我們可以用curl命令來請求這個介面,命令如下:

curl http://139.217.26.30:6800/daemonstatus.json複製程式碼

我們就會得到如下結果:

{"status": "ok", "finished": 90, "running": 9, "node_name": "datacrawl-vm", "pending": 0}複製程式碼

返回結果是JSON字串,status是當前執行狀態,finished代表當前已經完成的Scrapy任務,running代表正在執行的Scrapy任務,pending代表等待被排程的Scrapyd任務,node_name就是主機的名稱。

2. addversion.json

這個介面主要是用來部署Scrapy專案用的。我們首先將專案打包成Egg檔案,然後傳入專案名稱和部署版本。

我們可以用如下的方式實現專案部署:

curl http://120.27.34.25:6800/addversion.json -F project=wenbo -F version=first -F egg=@weibo.egg複製程式碼

在這裡, -F 代表新增一個引數,同時我們還需要將專案打包成Egg檔案放到本地。

發出請求之後,我們可以得到如下結果:

{"status": "ok", "spiders": 3}複製程式碼

這個結果表明部署成功,並且Spider的數量為3。

此部署方法可能比較煩瑣,後文會介紹更方便的工具來實現專案的部署。

3. schedule.json

這個介面負責排程已部署好的Scrapy專案執行。

我們可以用如下介面實現任務排程:

curl http://120.27.34.25:6800/schedule.json -d project=weibo -d spider=weibocn複製程式碼

這裡需要傳入兩個引數,project即Scrapy專案名稱,spider即Spider名稱。

返回結果如下:

{"status": "ok", "jobid": "6487ec79947edab326d6db28a2d86511e8247444"}複製程式碼

status代表Scrapy專案啟動情況,jobid代表當前正在執行的爬取任務代號。

4. cancel.json

這個介面可以用來取消某個爬取任務。如果這個任務是pending狀態,那麼它將會被移除;如果這個任務是running狀態,那麼它將會被終止。

我們可以用下面的命令來取消任務的執行:

curl http://120.27.34.25:6800/cancel.json -d project=weibo -d job=6487ec79947edab326d6db28a2d86511e8247444複製程式碼

這裡需要傳入兩個引數,project即專案名稱,job即爬取任務代號。

返回結果如下:

{"status": "ok", "prevstate": "running"}複製程式碼

status代表請求執行情況,prevstate代表之前的執行狀態。

5. listprojects.json

這個介面用來列出部署到Scrapyd服務上的所有專案描述。

我們可以用如下命令來獲取Scrapyd伺服器上的所有專案描述:

curl http://120.27.34.25:6800/listprojects.json複製程式碼

這裡不需要傳入任何引數。

返回結果如下:

{"status": "ok", "projects": ["weibo", "zhihu"]}複製程式碼

status代表請求執行情況,projects是專案名稱列表。

6. listversions.json

這個介面用來獲取某個專案的所有版本號,版本號是按序排列的,最後一個條目是最新的版本號。

我們可以用如下命令來獲取專案的版本號:

curl http://120.27.34.25:6800/listversions.json?project=weibo複製程式碼

這裡需要一個引數project,即專案的名稱。

返回結果如下:

{"status": "ok", "versions": ["v1", "v2"]}複製程式碼

status代表請求執行情況,versions是版本號列表。

7. listspiders.json

這個介面用來獲取某個專案最新版本的所有Spider名稱。

我們可以用如下命令來獲取專案的Spider名稱:

curl http://120.27.34.25:6800/listspiders.json?project=weibo複製程式碼

這裡需要一個引數project,即專案的名稱。

返回結果如下:

{"status": "ok", "spiders": ["weibocn"]}複製程式碼

status代表請求執行情況,spiders是Spider名稱列表。

8. listjobs.json

這個介面用來獲取某個專案當前執行的所有任務詳情。

我們可以用如下命令來獲取所有任務詳情:

curl http://120.27.34.25:6800/listjobs.json?project=weibo複製程式碼

這裡需要一個引數project,即專案的名稱。

返回結果如下:

{"status": "ok",
 "pending": [{"id": "78391cc0fcaf11e1b0090800272a6d06", "spider": "weibocn"}],
 "running": [{"id": "422e608f9f28cef127b3d5ef93fe9399", "spider": "weibocn", "start_time": "2017-07-12 10:14:03.594664"}],
 "finished": [{"id": "2f16646cfcaf11e1b0090800272a6d06", "spider": "weibocn", "start_time": "2017-07-12 10:14:03.594664", "end_time": "2017-07-12 10:24:03.594664"}]}複製程式碼

status代表請求執行情況,pendings代表當前正在等待的任務,running代表當前正在執行的任務,finished代表已經完成的任務。

9. delversion.json

這個介面用來刪除專案的某個版本。

我們可以用如下命令來刪除專案版本:

curl http://120.27.34.25:6800/delversion.json -d project=weibo -d version=v1複製程式碼

這裡需要一個引數project,即專案的名稱,還需要一個引數version,即專案的版本。

返回結果如下:

{"status": "ok"}複製程式碼

status代表請求執行情況,這樣就表示刪除成功了。

10. delproject.json

這個介面用來刪除某個專案。

我們可以用如下命令來刪除某個專案:

curl http://120.27.34.25:6800/delproject.json -d project=weibo複製程式碼

這裡需要一個引數project,即專案的名稱。

返回結果如下:

{"status": "ok"}複製程式碼

status代表請求執行情況,這樣就表示刪除成功了。

以上介面是Scrapyd所有的介面。我們可以直接請求HTTP介面,即可控制專案的部署、啟動、執行等操作。

五、Scrapyd API的使用

以上的這些介面可能使用起來還不是很方便。沒關係,還有一個Scrapyd API庫對這些介面做了一層封裝,其安裝方式可以參考第1章的內容。

下面我們來看看Scrapyd API的使用方法。Scrapyd API的核心原理和HTTP介面請求方式並無二致,只不過Python封裝後的庫使用起來更加便捷。

我們可以用如下方式建立一個Scrapyd API物件:

from scrapyd_api import ScrapydAPI
scrapyd = ScrapydAPI('http://120.27.34.25:6800')複製程式碼

呼叫它的方法來實現對應介面的操作,例如部署的操作可以使用如下方式:

egg = open('weibo.egg', 'rb')
scrapyd.add_version('weibo', 'v1', egg)複製程式碼

這樣我們就可以將專案打包為Egg檔案,然後把本地打包的的Egg專案部署到遠端Scrapyd。

另外,Scrapyd API還實現了所有Scrapyd提供的API介面,名稱都是相同的,引數也是相同的。

例如,呼叫list_projects()方法即可列出Scrapyd中所有已部署的專案:

scrapyd.list_projects()
['weibo', 'zhihu']複製程式碼

還有其他的方法在此不一一列舉了,名稱和引數都是相同的。更加詳細的操作可以參考官方文件:http://python-scrapyd-api.readthedocs.io/。

六、結語

本節介紹了Scrapyd及Scrapyd API的相關用法,我們可以通過它來部署專案,並通過HTTP介面控制任務的執行。不過部署過程有一點不方便,專案需要先打包Egg檔案然後再上傳,這樣比較煩瑣。在下一節,我們介紹一個更加方便的工具來完成部署過程。


本資源首發於崔慶才的個人部落格靜覓: Python3網路爬蟲開發實戰教程 | 靜覓

如想了解更多爬蟲資訊,請關注我的個人微信公眾號:進擊的Coder

weixin.qq.com/r/5zsjOyvEZ… (二維碼自動識別)


相關文章