Python 使用Scrapy连续抓取域
我在数据库中有要连续爬网的站点,即:Python 使用Scrapy连续抓取域,python,scrapy,web-crawler,scrapy-spider,Python,Scrapy,Web Crawler,Scrapy Spider,我在数据库中有要连续爬网的站点,即: 将域添加到允许的域列表(应为空) 将此域添加到请求中(将http://添加到请求中效果很好) 根据允许的域对请求进行爬网 前进到下一个域,仅将其添加到允许的域列表中。它将是那里唯一的一个,因此不会发生交叉。注意:这对我没有帮助,但也许我遗漏了什么 抓取此请求 连续完成我拥有的所有域 到目前为止,我所取得的成就是对域进行爬网,它做得非常好,能够完美地对请求进行爬网。 我唯一的问题是允许的\u域似乎没有更新,它会爬网所有类型的站点 我设置了DEPTH\u LIM
http://
添加到请求中效果很好)允许的\u域
似乎没有更新,它会爬网所有类型的站点
我设置了DEPTH\u LIMIT=1
,这样它就不会是无限爬网,我还添加了DF爬网而不是BF爬网:
DEPTH_LIMIT= 1
SCHEDULER_DISK_QUEUE = 'scrapy.squeues.PickleFifoDiskQueue'
SCHEDULER_MEMORY_QUEUE = 'scrapy.squeues.FifoMemoryQueue'
以下是我的spider的代码(只是开始;因为您并不真正关心我的项目处理…):
extract\u raw\u recipe
的代码没有请求或解析下一个url,它只是工作,所以不需要编辑它。但是如果我需要添加一些内容,请告诉我,因为这可能是缺少的链接。当前代码向项添加一个字典,然后将该项放入数据库中
总之:我需要添加什么,使它在每次爬网请求时过滤域
如果需要提供更多的代码,请告诉我。我的建议是采取完全不同的方法。在需要爬网的域数据库中创建一个队列(基于您想要的任何标准),然后选择一个域进行爬网,并使用
允许的\u域列表中的相关域初始化爬行器。爬行器完成后,重新开始下一个域的另一次爬网。重复此操作,直到队列中的所有域都完成
这将为您提供对整个过程的更多控制(例如,重新排队失败的爬网、取消有问题的爬网并在不丢失进度的情况下继续前进、一次爬网多个域而无“串扰”等)。如果您计划扩展此功能,它还将允许您执行自定义设置等操作(例如,用户代理、DUPEFILTER、下载延迟)或基于每个域的自定义规则,显著扩展了爬行器的可用性
如果这不是一个选项,你可以重置你的允许的\u域列表。这样做有一些问题,但首先要了解一下Scrapy的异地过滤的背景
OffSiteMiddleware
负责根据allowed_domains
编译允许域的列表。它为此使用了一个正则表达式,在spider启动时只编译一次(使用spider_opened
信号)。更新变量allowed_domains
将不会对爬行器产生影响,除非您还强制offsedimiddleware
重新编译其正则表达式
以下方法(放置在spider中)应可用于用新列表替换允许的\u域
:
from scrapy.spidermiddlewares.offsite import OffsiteMiddleware
def change_allowed_domains(self, allowed_domains):
self.allowed_domains = allowed_domains
for middleware in self.crawler.engine.scraper.spidermw.middlewares:
if isinstance(middleware, OffsiteMiddleware):
middleware.spider_opened(self)
这将重置OffsiteMiddleware
所使用的域
集()
,因此,如果您将其用于其他用途,请记住这一点
因此,花一秒钟的时间来消化所有这些,一个问题开始浮出水面:当您在start\u请求()
中对每个域排队时,您当前更改允许的\u域的方法将不起作用,因为Spider
类只跟踪一个允许的\u域
正则表达式(与请求/响应对象完全不关联)。如果在爬行器开始爬网之前将20个请求排队到不同的域(每次更改允许的\u域
列表),它将使用最新编译的正则表达式(即最后排队的域的允许的\u域
)
要克服这一点,您需要对一个域的所有请求进行爬网,编写自己的OffsiteMiddleware
,并让它处理所有筛选。或者您可以创建一个不同的域,以便在队列中的所有请求完成且下载程序中的所有插槽都为空时,将下一个域添加到列表中(可能是通过检查self.crawler.engine.slot.inprogress
和'self.crawler.engine.slot.scheduler')
祝你好运!对不起,现在只有时间和资源来阅读你的答案。哇,它给了我很多思考和考虑,非常感谢,会尝试和更新。尝试它,它很好地分离请求,并让刮处理每个网站作为一个单独的线程。
from scrapy.spidermiddlewares.offsite import OffsiteMiddleware
def change_allowed_domains(self, allowed_domains):
self.allowed_domains = allowed_domains
for middleware in self.crawler.engine.scraper.spidermw.middlewares:
if isinstance(middleware, OffsiteMiddleware):
middleware.spider_opened(self)