如何让scrapy中的start_url从消息队列中消耗?

时间:2014-09-22 04:58:22

标签: python scrapy

我正在构建一个scrapy项目,其中我有多个蜘蛛(每个域都有一个蜘蛛)。现在,要删除的URL来自用户给定的查询。所以基本上我不需要做广泛的抓取甚至跟踪链接。将会有一个接一个的网址,我只需要使用选择器提取。所以我在考虑是否可以将URL传递给scrapy蜘蛛可以使用的消息队列,我没事。但我无法弄明白。我已经检查了

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

现在每个网址都有相同的东西要为每个网站抓取。所以我有选择器在每个蜘蛛中这样做。我需要的是,这只是一个用户场景。当有多人用户时,会有多个不相关的网址进入同一个蜘蛛。所以它会是这样的:

query1,query2,query3

abc.com - > url_abc1,url_abc2,url_abc3

xyz.com - > url_xyz1,url_xyz2,url_xyz3

ghi.com - > url_ghi1,url_ghi2,url_ghi3

因此,对于每个网站,这些网址将动态发送,并将其推送到各自的消息队列中。 现在,对于网站而言,每个蜘蛛必须使用各自的队列,并在消息队列中有请求时向我提供已删除的项目

1 个答案:

答案 0 :(得分:5)

这是一种非常常见且(IMO)将scrapy构建为数据管道的优秀方法;我一直这样做。

你想要覆盖蜘蛛的start_requests()方法是正确的。如果您定义了start_requests()以及start_urls变量,我不知道scrapy的行为方式,但如果您从动态源(如数据库)消耗,我建议您只使用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循环中添加睡眠命令或指数退避。 (如果队列为空,请休眠几秒钟并尝试再次弹出。)

假设您的代码中没有发生致命错误,我相信由于构建了循环/生成器,这不应该终止。