我正在构建一个刮刮的项目,在其中我有多个蜘蛛(每个域一只蜘蛛)。现在,要抓取的urls动态地来自给定查询的用户。因此,基本上我不需要做广泛的爬行,甚至跟随链接。会有一个接一个的urls,我只需要使用选择器来提取。所以我在想,如果我能把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都有相同的东西要为每个网站进行抓取。所以我在每只蜘蛛身上都有选择器。我需要的是,这只是一个单一的用户场景。当有多个用户时,同一个蜘蛛会有多个不相关的urls。所以会是这样的:
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
因此,对于每个网站,这些urls将动态地被推送到各自的消息队列中。现在,用于网站的每个蜘蛛都必须使用它们各自的队列,并在消息队列上有请求时给我刮掉的项。
发布于 2014-09-25 23:51:57
作为数据管道的一部分,这是一种非常常见且(IMO)非常优秀的构建刮取的方法;我一直在这样做。
要重写蜘蛛的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循环中添加睡眠命令或指数退避。(如果队列为空,则休眠几秒钟,然后再次尝试弹出。)
假设代码中没有发生致命错误,我认为这不应该因为循环/生成器的构造而终止。
https://stackoverflow.com/questions/25966941
复制相似问题