2014-09-22 89 views
6

我正在構建一個scrapy項目,其中有多個蜘蛛(每個域都有一個蜘蛛)。現在,被抓取的網址會動態地從給定查詢的用戶開始。所以基本上我不需要進行廣泛的抓取,甚至不需要鏈接。將有一個接一個的網址,我只需要使用選擇器提取。所以我想,如果我只是將URL傳遞到scrapy蜘蛛可以消耗的消息隊列中,我會沒事的。但我無法弄清楚。我已經檢查如何使scrapy中的start_url從消息隊列中消耗?

https://github.com/darkrho/scrapy-redis

,但我覺得它不適合我的目的,我需要多個隊列(每個蜘蛛單個隊列)。 正如我已經開始學習,一種方法似乎是重寫蜘蛛中的start_requests方法。但是在這裏我還不清楚該怎麼做(python和scrapy的新功能)。我可以將它作爲任何普通的python腳本處理,並且使用(任何)消息隊列的方法來處理它? 此外,我需要運行24 * 7的蜘蛛,並在隊列中有請求時進行刮擦。我想我應該使用信號並在某處提出DontCloseSpider異常。但我在哪裏做?我很迷茫。請幫忙。

下面是我在看的情景:

用戶 - >查詢 - > URL從abc.com - > ABC-蜘蛛

  -> url from xyz.com -> xyz-spider 

      -> url from ghi.com -> ghi-spider 

現在每個URL都有同樣的事情被刮掉了每個網站。所以我有選擇器在每個蜘蛛中做這件事。我需要的是,這只是一個單一的用戶場景。當有多人用戶時,會有多個不相關的網站進入同一個蜘蛛。所以這將是這樣的:

QUERY1,QUERY2,QUERY3

abc.com - > url_abc1,url_abc2,url_abc3

xyz.com - > url_xyz1,url_xyz2,url_xyz3

GHI url_ghi1,url_ghi2,url_ghi3

因此,對於每個網站,這些網址都將動態傳遞,並將其推送到各自的消息隊列中。 現在,每個爲網站設計的蜘蛛都必須使用它們各自的隊列,並且在消息隊列中有請求時給我抓取的物品

+0

問題是運行多個蜘蛛嗎? – Nabin 2014-09-22 05:17:05

+1

沒有。問題是如何使消息隊列中的蜘蛛消耗。 – Avinragh 2014-09-22 05:25:24

+0

看看http://stackoverflow.com/questions/21694386/running-more-than-one-spiders-one-by-one – Nabin 2014-09-22 05:27:09

回答

4

這是一種非常常見的(IMO)數據流水線;我一直這樣做。

你是正確的,你想重寫蜘蛛的start_requests()方法。我不知道scrapy的行爲如果你有start_requests()以及start_urls變量,但是我建議只使用start_requests(),如果你正在使用像數據庫這樣的動態源代碼。

一些示例代碼,未經測試,但應該給你正確的想法..請讓我知道,如果你需要更多的信息。它還假定您的隊列由另一個進程填充。

class ProfileSpider(scrapy.Spider): 
    name = 'myspider' 

    def start_requests(self): 
     while(True): 
      yield self.make_requests_from_url(
       self._pop_queue() 
      ) 

    def _pop_queue(self): 
     while(True): 
      yield self.queue.read() 

這會將您的隊列公開爲生成器。如果您希望最小化空循環的數量(因爲隊列可能爲空),您可以在_pop_queue循環中添加睡眠命令或指數退避。 (如果隊列爲空,則休眠幾秒鐘並嘗試再次彈出。)

假設您的代碼中沒有發生致命錯誤,我認爲這不應該因爲構建循環/生成器而終止。

+0

謝謝!我得到了我的蜘蛛與消息隊列 – Avinragh 2014-09-27 09:59:08

+0

無法正常工作。它抱怨錯誤獲取啓動請求,因爲它期望字符串URL作爲其獲取生成器 – 2017-06-07 07:33:25