快速搭建python爬蟲管理平臺

爬蟲有多重要

對搜索引擎來說,爬蟲不可或缺;對輿情公司來說,爬蟲是基礎;對 NLP來說,爬蟲可以獲取語料;對初創公司來說,爬蟲可以獲取初始內容。但是爬蟲技術紛繁復雜,不同類型的抓取場景會運用到不同的技術。例如,簡單的靜態頁面可以用 HTTP 請求+HTML 解析器直接搞定;一個動態頁面需要用 Puppeteer 或 Selenium等自動化測試工具;有反爬的網站需要用到代理、打碼等技術;等等。那麼此時就需要一個成熟的爬蟲管理平臺,幫助企業或個人處理大量的爬蟲類別。

理解什麼是爬蟲管理平臺

定義

爬蟲管理平臺是一個一站式管理系統,集爬蟲部署、任務調度、任務監控、結果展示等模塊於一體,通常配有可視化 UI 界面,可以在 Web 端通過與 UI 界面交互來有效管理爬蟲。爬蟲管理平臺一般來說是支持分佈式的,可以在多臺機器上協作運行。

當然,上述這個定義是狹義的,通常針對於技術人員或開發者或技術經理。企業內部一般都會開發自己的內部爬蟲管理系統,以應對復雜的爬蟲管理需求。這樣的系統就是上述定義的狹義的爬蟲管理平臺。

廣義爬蟲管理平臺

而什麼是廣義的爬蟲管理平臺呢?您可能聽說過神箭手(後轉型為後羿采集器)和八爪魚吧。前者是基於雲服務的,可以在線上編寫、運行和監控爬蟲,在廣義爬蟲平臺中最接近狹義定義的爬蟲管理平臺;後者是一個大眾的商業爬蟲抓取工具,可以讓小白用戶拖拉拽編寫、運行爬蟲,導出數據。您也可能見過各種 API 聚合服務商,例如聚合數據,這是一個可以直接調用網站接口獲取數據的平臺,這其實也算作爬蟲平臺的一個變種,隻是它幫你完成瞭爬蟲編寫這一過程。而介於這兩者之間的呢,國外有一傢叫 Kimonolab 的公司,它開發瞭一個叫 Kimono 的 Chrome 插件,可以讓用戶在頁面上可視化的點擊元素並生成抓取規則,並在其網站上生成爬蟲程序,用戶提交任務,後臺就可以自動在網站上抓取數據瞭。Kimono 是一個偉大的爬蟲應用,但可惜的是,Kimonolab 已經被大數據公司 Plantir 收購,現在也就無法體驗瞭。

在本文中,我們主要關註狹義定義的爬蟲管理平臺,因此後面所講到的爬蟲管理平臺都是指狹義的定義。

爬蟲管理平臺模塊

以下是一個典型的爬蟲管理平臺所涉及的模塊。

爬蟲管理平臺架構

典型爬蟲管理平臺的模塊主要包含以下內容:

  • 任務管理:如何執行、調度爬蟲抓取任務,以及如何監控任務,包括日志監控等等;
  • 爬蟲管理:包括爬蟲部署,即將開發好的爬蟲部署(打包或復制)到相應的節點上,以及爬蟲配置和版本管理;
  • 節點管理:包括節點(服務器/機器)的註冊和監控,以及節點之間的通信,如何監控節點性能狀況等;
  • 前端應用:包括一個可視化 UI 界面,讓用戶可通過與其交互,與後臺應用進行通信。

當然,有些爬蟲管理平臺可能還不止這些模塊,它可能包括其他比較實用的功能,例如可配置的抓取規則、可視化配置抓取規則、代理池、Cookie 池、異常監控等等。

為什麼需要爬蟲管理平臺

有瞭爬蟲管理平臺,開發者特別是爬蟲工程師就能夠方便的添加爬蟲、執行任務、查看結果,而不用在命令行之間來回切換,非常容易出錯。一個常見的場景就是爬蟲工程師最初技術選型用瞭 scrapy 和 crontab 來管理爬蟲任務,他不得不小心翼翼的選擇定時任務的時間區間,以至於不會將服務器 CPU 或內存占滿;更棘手的問題是,他還需要將 scrapy 產生的日志存到文件裡,一旦爬蟲出錯瞭,他不得不用 shell 命令一個一個來查看日志來定位錯誤原因,嚴重時會花上一個整天;還有個嚴重的問題,爬蟲工程師可能發現公司業務量在增加,他需要寫上百個爬蟲來滿足公司的業務需求,而用 scrapy 和 crontab 來管理完全就是個噩夢。可憐的爬蟲工程師其實完全可以選擇一個合適爬蟲管理平臺來解決他的問題。

如何選擇一個合適的爬蟲管理平臺

當您願意解決前面提到的爬蟲工程師遇到的困難問題,而轉而想選擇一個合適的爬蟲管理平臺時。

您首先應該回答的問題是:我們是否需要從零開始開發一套系統(Start from scratch)?要回答這個問題,您應該先回答下面幾個問題:

1.我們的需求是否復雜到需要完全定制化開發一套新系統(例如要求復雜的權限管理)?

2.我們的團隊是否有足夠的技術實力來開發這套系統(例如有經驗豐富的前後端開發工程師)?

3.我們的時間資源是否足夠我們開發這套系統(例如項目計劃周期為一年)?

如果上述三個問題的答案任意一個為“否”,您應該好好考慮利用市面上已有的開源爬蟲管理平臺來滿足您的需求。

以下為市面上已有的開源爬蟲管理平臺:

總的來說,SpiderKeeper 可能是最早的爬蟲管理平臺,但功能相對來說比較局限;Gerapy 雖然功能齊全,界面精美,但有不少 bug 需要處理,建議有需求的用戶等待 2.0 版本;Scrapydweb是一個比較完善的爬蟲管理平臺,不過和前兩者一樣,都是基於 scrapyd 的,因此隻能運行 scrapy 爬蟲;而Crawlab是一個非常靈活的爬蟲管理平臺,可以運行 Python、Nodejs、Java、PHP、Go 寫的爬蟲,而且功能比較齊全,隻是部署起來相對於前三者來說要麻煩一些,不過對於 Docker 使用者來說可以做到一件部署(後面我們會講)。

因此,對於重度 scrapy 爬蟲依賴的、又不想折騰的開發者,可以考慮 Scrapydweb;而對於有各種類型的、復雜技術結構的爬蟲開發者來說,應該優先考慮更靈活的 Crawlab。當然,不是說 Crawlab 對 scrapy 支持不友好,Crawlab 同樣可以很好的集成 scrapy,後面會介紹。

作為 Crawlab 的作者,不想王婆賣瓜,自賣自誇,作者僅僅希望將最好的技術選型推薦給開發者,讓開發者根據自身的需求來決定該使用哪種爬蟲管理平臺。

爬蟲管理平臺 Crawlab 介紹簡介

Crawlab 是基於 Golang 的分佈式爬蟲管理平臺,支持 Python、NodeJS、Java、Go、PHP 等多種編程語言以及多種爬蟲框架。

Crawlab 自今年三月份上線以來受到爬蟲愛好者們和開發者們的好評,不少使用者還表示會用 Crawlab 搭建公司的爬蟲平臺。經過近數月的迭代,Crawlab 陸續上線瞭定時任務、數據分析、網站信息、可配置爬蟲、自動提取字段、下載結果、上傳爬蟲等功能,將平臺變得得更加實用,更加全面,能夠真正幫助用戶解決爬蟲管理困難的問題。如今在 Github 上有近 1k 的 star,相關社區也建立起來,四分之一的用戶表示已經將 Crawlab 應用於企業爬蟲管理。可以看出,Crawlab 是受開發者們關註和喜歡的。

解決問題

Crawlab 主要解決的是大量爬蟲管理困難的問題,例如需要監控上百個網站的參雜 scrapy 和 selenium 的項目不容易做到同時管理,而且命令行管理的成本非常高,還容易出錯。Crawlab 支持任何語言和任何框架,配合任務調度、任務監控,很容易做到對成規模的爬蟲項目進行有效監控管理。

界面及使用

下面是 Crawlab 爬蟲列表頁面的截圖。

Crawlab 爬蟲列表

用戶隻需要將爬蟲上傳到 Crawlab,配置執行命令,點擊“運行”按鈕,就可以執行爬蟲任務瞭。爬蟲任務可以在任何節點上運行。從上圖可以看到,Crawlab 有節點管理、爬蟲管理、任務管理、定時任務、用戶管理等模塊。

整體架構

以下是 Crawlab 的整體架構圖,由五大部分組成:

1.主節點(Master Node):負責任務派發、API、部署爬蟲等;

2.工作節點(Worker Node):負責執行爬蟲任務;

3.MongoDB 數據庫:存儲節點、爬蟲、任務等日常運行數據;

4.Redis 數據庫:儲存任務消息隊列、節點心跳等信息。

5.前端客戶端:Vue 應用,負責前端交互和向後端請求數據。

Github地址及Demo

查看演示 DemoGithub: https://github.com/tikazyq/crawlab

使用 Docker 部署安裝 Crawlab

Docker 鏡像

Docker 是部署 Crawlab 最方便和簡潔的方式。其他部署方式包括直接部署,不過對於想快速搭建平臺的開發者來說不推薦。Crawlab 已在Dockerhub上註冊瞭相關的鏡像,開發者僅需要執行docker pull tikazyq/crawlab命令就可以將 Crawlab 的鏡像下載下來。

讀者可以去 Dockerhub 上查看 Crawlab 的鏡像,隻有僅不到 300Mb。地址:https://hub.docker.com/r/tikazyq/crawlab/tags

Dockerhub Page

安裝 Docker

要使用 Docker 來部署 Crawlab,您首先得保證 Docker 已經安裝好。請參考以下文檔來安裝。

安裝 Docker Compose

Docker Compose 是簡單的運行 Docker 集群的工具,非常輕量級,我們將用到 Docker Compose 來一鍵部署 Crawlab。

Docker 的官方網站已經有如何安裝 Docker Compose 的教程,點擊鏈接查看。這裡簡單介紹一下。

Linux 用戶請用以下命令安裝。

# 下載 docker-compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose`

# 將 docker-compose 變成執行文件
sudo chmod +x /usr/local/bin/docker-compose

拉取鏡像

在拉取鏡像之前,您需要配置一下鏡像源。因為在國內,使用原有的鏡像源速度不是很快,需要使用 DockerHub 在國內的加速器。請創建/etc/docker/daemon.json文件,輸入如下內容。

{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}

然後拉取鏡像,就會快很多瞭。當然,您也可以用其他鏡像源,可以網上去搜索一下。執行以下命令將 Crawlab 鏡像拉取下來。

docker pull tikazyq/crawlab:latest

下圖為拉取鏡像時的命令行界面。

docker pull

啟動 Crawlab

我們將用 Docker Compose 啟動 Crawlab 以及其依賴的數據庫 MongoDB 和 Redis。首先我們需要修改一下 Docker Compose 的 yaml 配置文件docker-compose.yml。這個配置文件定義瞭需要啟動的容器服務(Container Services)以及網絡配置(Network Configuration)。這裡我們用 Crawlab 自帶的docker-compose.yml。

version: '3.3'  # Docker Compose 的版本號(請看後續說明)
services:  # 服務
  master:  # 服務名稱
    image: tikazyq/crawlab:latest  # 服務對應的鏡像名稱
    container_name: master  # 服務對應的容器名稱
    environment:  # 這裡定義傳入的環境變量
      CRAWLAB_API_ADDRESS: "localhost:8000"  # 前端調用的 API 地址,默認為 localhost:8000
      CRAWLAB_SERVER_MASTER: "Y"  # 是否為主節點,Y/N
      CRAWLAB_MONGO_HOST: "mongo"  # MongoDB host,由於在 Docker Compose 裡,可以引用服務名稱
      CRAWLAB_REDIS_ADDRESS: "redis"  # Redis host,由於在 Docker Compose 裡,可以引用服務名稱
    ports:  # 映射的端口
      - "8080:8080" # 前端端口
      - "8000:8000" # 後端端口
    depends_on: # 依賴的服務
      - mongo  # MongoDB
      - redis  # Redis
  worker:  # 工作節點,與主節點配置類似,不重復寫瞭
    image: tikazyq/crawlab:latest
    container_name: worker
    environment:
      CRAWLAB_SERVER_MASTER: "N"
      CRAWLAB_MONGO_HOST: "mongo"
      CRAWLAB_REDIS_ADDRESS: "redis"
    depends_on:
      - mongo
      - redis
  mongo:  # MongoDB 服務名稱
    image: mongo:latest  # MongoDB 鏡像名稱
    restart: always  # 重啟策略為“總是”
    ports:  # 映射端口
      - "27017:27017"
  redis:  # Redis 服務名稱
    image: redis:latest  # Redis 鏡像名稱
    restart: always  # 重啟策略為“總是”
    ports:  # 映射端口
      - "6379:6379"

讀者可以根據自己的要求來配置docker-compose.yml。尤其需要註意CRAWLAB_API_ADDRESS這個環境變量,很多初學使用者都是因為該變量配置不正確而導致無法登陸。大多數情況,您不用做任何配置更改。請參考Q&A來處理常見問題,以及詳細的環境變量配置文檔來幫助根據自身環境配置 Crawlab。

然後,運行下列命令啟動 Crawlab。可以加一個-d參數讓 Docker Compose 後臺運行。

docker-compose up

運行上述命令後,Docker Compose 會去拉取 MongoDB 和 Redis 的鏡像,這可能會花幾分鐘時間。拉取完畢後,四個服務會依次啟動,您將會在命令行中看到如下內容。

docker-compose

正常情況下,您應該可以看到四個服務都啟動成功,並能夠順利打印日志。

如果您是在本機上啟動的 Docker Compose,可以在瀏覽器中輸入http://localhost:8080,然後就能看到登陸界面瞭;如果您是在其他機器上啟動的 Docker Compose,您需要在瀏覽器中輸入http://<your_ip>:8080來看到登陸界面,<your_ip>是其他機器的 IP 地址(請保證 8080 端口在該機器已對外開放)。

login

初始登陸用戶名密碼是 admin/admin,您可以使用這個用戶名密碼來登陸。如果您的環境變量CRAWLAB_API_ADDRESS設置得不正確,您可能會看到點擊登陸後登陸按鈕會一直轉圈而沒有任何提示。這時請重新在docker-compose.yml中設置正確的CRAWLAB_API_ADDRESS(將localhost替換為<your_ip>),重新啟動docker-compose up。然後在瀏覽器中輸入http://<your_ip>:8080。

登陸之後您將看到 Crawlab 的主頁。

home

本篇文章主要介紹如何搭建爬蟲管理平臺 Crawlab,因此不會詳細介紹如何使用 Crawlab(可能會創建另一篇文章來詳細介紹,有興趣者可以關註一下)。如果您有困惑,請查看相關文檔來瞭解如何使用。

如何將 Scrapy 等爬蟲集成到 Crawlab

眾所周知,Scrapy 是非常受歡迎的爬蟲框架,其靈活的框架設計、高並發、易用性以及可擴展性讓很多開發者和企業大量采用。市面上的爬蟲管理平臺幾乎都支持 Scrapy 爬蟲,Crawlab 也不例外,但 Crawlab 可以運行 puppeteer、selenium 等其他爬蟲。下面將介紹一下在 Crawlab 中如何運行 scrapy 爬蟲。

Crawlab 是執行爬蟲基本原理

Crawlab 執行爬蟲的原理很簡單,其實就是一個 shell 命令。用戶在爬蟲中輸入執行爬蟲的 shell 命令,例如scrapy crawl some_spider,Crawlab 執行器會讀取這個命令,並在 shell 中直接執行。因此,每一次運行爬蟲任務,就是執行瞭一次 shell 命令(當然,實際情況要比這個復雜很多,感興趣的可以去參考官方文檔)。Crawlab 是支持展示和導出爬蟲結果的,不過這需要稍微多做一些工作。

編寫 Pipeline

要集成 scrapy 爬蟲,無非就是將爬蟲抓取的數據存到 Crawlab 的數據庫裡,然後用任務 ID 關聯起來。每次執行爬蟲任務,任務 ID 會通過環境變量傳到爬蟲程序中,因此我們需要做的就是將任務 ID 加上結果存到數據庫裡(Crawlab 現在隻支持 MongoDB,後期會開發 MySQL、SQL Server、Postgres 等關系型數據庫,有需求的用戶可以關註一下)。

在 Scrapy 中,我們需要編寫儲存邏輯。示意代碼如下:

# 引入相關的庫,pymongo 是標準連接 MongoDB 的庫
import os
from pymongo import MongoClient

# MongoDB 配置參數
MONGO_HOST = '192.168.99.100'
MONGO_PORT = 27017
MONGO_DB = 'crawlab_test'

class JuejinPipeline(object):
    mongo = MongoClient(host=MONGO_HOST, port=MONGO_PORT)  # mongo 連接實例
    db = mongo[MONGO_DB]  # 數據庫實例
    col_name = os.environ.get('CRAWLAB_COLLECTION')  # 集合名稱,通過環境變量 CRAWLAB_COLLECTION 傳過來

 # 如果 CRAWLAB_COLLECTION 不存在,則默認集合名稱為 test
    if not col_name:
        col_name = 'test'
 
    col = db[col_name]  # 集合實例

 # 每一個傳入 item 會調用的函數,參數分別為 item 和 spider
    def process_item(self, item, spider):
        item['task_id'] = os.environ.get('CRAWLAB_TASK_ID')  # 將 task_id 設置為環境變量傳過來的任務 ID
        self.col.save(item)  # 保存 item 在數據庫中
        return item

同時,您也需要在items.py中加入task_id字段,已保證值能夠被賦上(這很重要)。

上傳並配置爬蟲

在運行爬蟲之前,您需要上傳爬蟲文件到主節點。步驟如下:

1.將爬蟲文件打包成 zip(註意,要保證在根目錄下直接打包);

2.在側邊欄點擊“爬蟲”導航至爬蟲列表,點擊“添加爬蟲”按鈕,選擇“自定義爬蟲”;

3.點擊“上傳”按鈕,選擇剛剛打包好的 zip 文件

4.上傳成功後,爬蟲列表中會出現新添加的自定義爬蟲,這樣就算上傳成功瞭。

可以在爬蟲詳情中點擊“文件”標簽,選擇一個文件,可以在文件中編輯代碼。

接下來,您需要在“概覽”標簽中的“執行命令”一欄輸入爬蟲的 shell 執行命令。Crawlab 的 Docker 鏡像裡是內置瞭 scrapy 的,因此可以直接運行 scrapy 爬蟲。命令就是scrapy crawl <some_spider>。點擊“保存”按鈕保存爬蟲配置。

運行爬蟲任務

然後就是運行爬蟲任務瞭。其實很簡單,在“概覽”標簽中點擊“運行”按鈕,爬蟲任務就開始運行瞭。如果日志提示找不到 scrapy 命令,可以將scrapy改為絕對路徑/usr/local/bin/scrapy,這樣就會運行成功。

任務運行情況會在“任務”頁面或者爬蟲“概覽”裡展現,會每 5 秒鐘更新一次,大傢可以在這上面查看。而且在爬蟲“結果”標簽裡,可以預覽結果的詳情,還可以導出數據成 CSV 文件。

構建持續集成(CI)工作流

對於企業來說,軟件開發一般是一個自動化過程。它會經歷需求、開發、部署、測試、上線這幾個步驟。而這個流程一般是不斷迭代(Iterative)的,需要不斷更新和發佈。

以爬蟲為例,您上線瞭一個爬蟲,這個爬蟲會定期抓取網站數據。但突然有一天您發現數據抓不到瞭,您快速定位原因,發現原來是網站改版瞭,您需要更改爬蟲抓取規則來應對網站的改版。總之,您需要發佈一個代碼更新。最快的做法是直接在線上更改代碼。但這樣做非常危險:第一,您無法測試您更新後的代碼,隻能通過不斷調整線上代碼來測試是否抓取成功;第二,您無法記錄這次更改,後期如果出瞭問題您很可能會忽略掉這次更改,從而導致 bug。您需要做的,無非是將您的爬蟲代碼用版本管理工具管理起來。我們有很多版本管理工具,最常用的就是 git、subversion,版本管理平臺包括 Gitlab、Bitbucket、自搭 Git 倉庫等。

當我們更新瞭代碼,我們需要將更新後的代碼發佈到線上服務器。這時您需要用自己寫部署腳本,或者更方便的,用 Jenkins 作為持續集成(Continuous Integration)管理平臺。Jenkins 是一個持續集成平臺,可以通過獲取版本庫來更新部署代碼,是非常實用的工具,在很多企業中都有用到。下圖是如何將 Crawlab 爬蟲應用到持續集成工作流程中的例子。

ci

要在 Crawlab 中創建或更新爬蟲有兩種方式:

1.上傳打包成後的 zip 文件;

2.通過更改主節點中目錄CRAWLAB_SPIDER_PATH中的爬蟲文件。

我們做持續集成,就是針對第二種方式。步驟如下:

1.用 Gitlab 或其他平臺搭建好代碼倉庫;

2.在 Jenkins 中創建一個項目,在項目中將代碼源指向之前創建的倉庫;

3.在 Jenkins 項目中編寫工作流,將發佈地址指向 Crawlab 的CRAWLAB_SPIDER_PATH,如果是 Docker 註意將該地址掛載到宿主機文件系統;

4.Jenkins 項目的工作可以直接編寫,也可以用 Jenkinsfile,具體可以查相關資料;

5.這樣,每一次代碼更新提交到代碼倉庫後,Jenkins 就會將更新後的代碼發佈到 Crawlab 裡,Crawlab 主節點會將爬蟲代碼同步到工作節點,以待抓取。

總結

本篇文章主要介紹瞭爬蟲管理平臺的定義、如何選擇爬蟲管理平臺,著重介紹瞭如何搭建開源爬蟲管理平臺 Crawlab,另外還講到瞭如何集成 scrapy 爬蟲以及如何打造持續集成工作流。本篇文章沒有涉及到的內容還有很多,包括如何 Crawlab 的原理和架構詳情、如何使用 Crawlab、如何編寫大規模爬蟲、如何使用 Jenkins 等等。這些內容可能會在其他文章中發佈,請感興趣的讀者多多關註。另外,Crawlab 還有一些需要提升的地方,例如異常監控(零值、空值)、可配置爬蟲、可視化抓取、日志集中收集等等。這些功能都將在以後陸續開發和發佈,請大傢也多多關註。

以上就是快速搭建python爬蟲管理平臺的詳細內容,更多關於搭建python爬蟲平臺的資料請關註WalkonNet其它相關文章!

推薦閱讀: