如何構建一個分佈式爬蟲:基礎篇

上篇咱們談論了Celery的基本知識後,本篇繼續講解如何一步步使用Celery構建分佈式爬蟲。此次咱們抓取的對象定爲celery官方文檔html

首先,咱們新建目錄distributedspider,而後再在其中新建文件workers.py,裏面內容以下python

from celery import Celery
app = Celery('crawl_task', include=['tasks'], broker='redis://223.129.0.190:6379/1', backend='redis://223.129.0.190:6379/2')
# 官方推薦使用json做爲消息序列化方式
app.conf.update(
    CELERY_TIMEZONE='Asia/Shanghai',
    CELERY_ENABLE_UTC=True,
    CELERY_ACCEPT_CONTENT=['json'],
    CELERY_TASK_SERIALIZER='json',
    CELERY_RESULT_SERIALIZER='json',
)

上述代碼主要是作Celery實例的初始化工做,include是在初始化celery app的時候須要引入的內容,主要就是註冊爲網絡調用的函數所在的文件。而後咱們再編寫任務函數,新建文件tasks.py,內容以下git

import requests
from bs4 import BeautifulSoup
from workers import app
@app.task
def crawl(url):
    print('正在抓取連接{}'.format(url))
    resp_text = requests.get(url).text
    soup = BeautifulSoup(resp_text, 'html.parser')
    return soup.find('h1').text

它的做用很簡單,就是抓取指定的url,而且把標籤爲h1的元素提取出來github

最後,咱們新建文件task_dispatcher.py,內容以下redis

from workers import app
url_list = [
    'http://docs.celeryproject.org/en/latest/getting-started/introduction.html',
    'http://docs.celeryproject.org/en/latest/getting-started/brokers/index.html',
    'http://docs.celeryproject.org/en/latest/getting-started/first-steps-with-celery.html',
    'http://docs.celeryproject.org/en/latest/getting-started/next-steps.html',
    'http://docs.celeryproject.org/en/latest/getting-started/resources.html',
    'http://docs.celeryproject.org/en/latest/userguide/application.html',
    'http://docs.celeryproject.org/en/latest/userguide/tasks.html',
    'http://docs.celeryproject.org/en/latest/userguide/canvas.html',
    'http://docs.celeryproject.org/en/latest/userguide/workers.html',
    'http://docs.celeryproject.org/en/latest/userguide/daemonizing.html',
    'http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html'
]
def manage_crawl_task(urls):
    for url in urls:
        app.send_task('tasks.crawl', args=(url,))
if __name__ == '__main__':
    manage_crawl_task(url_list)

這段代碼的做用主要就是給worker發送任務,任務是tasks.crawl,參數是url(元祖的形式)json

如今,讓咱們在節點A(hostname爲resolvewang的主機)上啓動workercanvas

celery -A workers worker -c 2 -l info網絡

這裏 -c指定了線程數爲2, -l表示日誌等級是info。咱們把代碼拷貝到節點B(節點名爲wpm的主機),一樣以相同命令啓動worker,即可以看到如下輸出app

兩個節點

能夠看到左邊節點(A)先是all alone,表示只有一個節點;後來再節點B啓動後,它便和B同步了分佈式

sync with celery@wpm

這個時候,咱們運行給這兩個worker節點發送抓取任務

python task_dispatcher.py

能夠看到以下輸出

分佈式抓取示意圖

能夠看到兩個節點都在執行抓取任務,而且它們的任務不會重複。咱們再在redis裏看看結果

backend示意圖

能夠看到一共有11條結果,說明 tasks.crawl中返回的數據都在db2(backend)中了,而且以json的形式存儲了起來,除了返回的結果,還有執行是否成功等信息。

到此,咱們就實現了一個很基礎的分佈式網絡爬蟲,可是它還不具備很好的擴展性,並且貌似太簡單了...下一篇我將以微博數據採集爲例來演示如何構建一個穩健的分佈式網絡爬蟲。


對微博大規模數據採集感興趣的同窗能夠關注一下分佈式微博爬蟲,用用也是極好的

相關文章
相關標籤/搜索