pyspider + RabbitMQ 使用記 - 上

接到一個爬蟲任務,項目比較巨大,原來想用 Requests 配合正則作爬蟲。後來得知了 pyspider 這個神器,才知道以前的想法 low 爆了。pyspider GitHubcss

按照 GitHub 上的安裝教程安裝好之後,咱們就能夠經過 pyspider 命令來啓動這個神器,而後在瀏覽器中打開 http://localhost:5000/ 就能夠看到界面了。首先是一個 Dashboard,咱們在這裏能夠建立爬蟲項目,點擊 Create 而後輸入項目名就能夠看到代碼了。html

關於項目的幫助能夠看文檔,在 GitHub 上能夠找到該項目的 Docs 連接,咱們如今上來直接看代碼,我用中文作下注釋。git

from pyspider.libs.base_handler import *
# 引入 pyspider 的 base_handler,這個是用來當基類的。
# 如下就是咱們寫的類。
class Handler(BaseHandler):
    crawl_config = {
    }
    # 這個是做爲整個項目的全局參數的設置,好比 proxy。
    @every(minutes=24 * 60)
    # 這句話是定時啓動的意思,這裏就是說每一天啓動一次。
    # 如下爲爬蟲的入口
    def on_start(self):
    # 抓 http://scrapy.org/ 的頁面,將返回的內容交給 index_page 函數來處理。
        self.crawl('http://scrapy.org/', callback=self.index_page)

    @config(age=10 * 24 * 60 * 60)
    # 每十天重啓一次
    def index_page(self, response):
        for each in response.doc('a[href^="http"]').items():
        # 這裏將 on_start 抓取 scrapy 首頁的返回結果進行過濾,採用了 CSS 選擇器選擇了 href 的值爲 http 開頭的全部 a 標籤。
        # 此處循環內的 each 即爲網頁中的 a 標籤。
            self.crawl(each.attr.href, callback=self.detail_page)
            # 再次調用 crawl 函數,對 a 標籤的 href 中目標網址進行抓取,返回給 detail_page 函數來處理。

    def detail_page(self, response):
        return {
            "url": response.url,
            # 返回 url 和網頁 title 組成的字典。
            "title": response.doc('title').text(),
        }

做者本身寫的中文教程裏面已經把不少操做都講清楚了,我就不抄來了。github

對於 ajax 請求的內容能夠直接 crawl 那個 ajax 請求的 URL,返回的 response.json 就變成了一個 Python 的字典。ajax

當每一個函數 return 的時候,return 的內容被傳遞到了 BaseHandler 這個基類中的 on_result 函數,其代碼以下:數據庫

def on_result(self, result):
        """Receiving returns from other callback, override me."""
        if not result:
            return
        assert self.task, "on_result can't outside a callback."
        if self.is_debugger():
        # 當在瀏覽器中調試運行時:
            pprint(result)
        if self.__env__.get('result_queue'):
        # 當被看成任務執行時,即在 Dashboard 中設置爲 RUNNING 時,
            self.__env__['result_queue'].put((self.task, result))

而後咱們就能夠經過重寫 on_result 函數,來將全部函數的返回值進行處理,再輸出到 RabbitMQ 的隊列中。json

隊列的另外一端是數據庫寫入腳本,該腳本一條一條地從隊列中取出消息,而後一個字段一個字段地插入到數據庫,不用擔憂數據庫寫入時的衝突問題了。瀏覽器

相關文章
相關標籤/搜索