分散式爬蟲完成並可以成功執行了,但是有個環節非常煩瑣,那就是程式碼部署。
我們設想下面的幾個場景。
如果採用上傳檔案的方式部署程式碼,我們首先將程式碼壓縮,然後採用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提供了一系列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… (二維碼自動識別)