问题描述
类似于链接中的操作: How can i use multiple requests and pass items in between them in scrapy python
我正在尝试像Dave McLain的回答一样将来自蜘蛛的请求链接起来。从parse函数返回一个请求对象可以正常工作,使蜘蛛程序可以继续下一个请求。
def parse(self,response):
# Some operations
self.url_index += 1
if self.url_index < len(self.urls):
return scrapy.Request(url=self.urls[self.url_index],callback=self.parse)
return items
但是,我有默认的Spider中间件,可以在spider_process_output中进行一些缓存和日志记录操作。首先从解析函数返回请求对象进入中间件。因此,中间件也必须返回请求对象。
def process_spider_output(self,response,result,spider):
# Called with the results returned from the Spider,after
# it has processed the response.
# Must return an iterable of Request,or item objects.
if hasattr(spider,'multiple_urls'):
if spider.url_index + 1 < len(spider.urls):
return [result]
# return [scrapy.Request(url=spider.urls[spider.url_index],callback=spider.parse)]
# Some operations ...
根据文档,它必须返回可迭代的Request或item对象。但是,当我返回结果(它是一个Request对象)或构造一个新的请求对象(如注释中所示)时,蜘蛛程序只是终止(通过给蜘蛛程序完成信号)而没有发出新的请求。
文档链接:https://docs.scrapy.org/en/latest/topics/spider-middleware.html#writing-your-own-spider-middleware
我不确定文档或我的解释方式是否存在问题。但是,从中间件返回请求对象不会发出新请求,而是会终止流程。
解决方法
解决问题非常简单但令人沮丧。中间件应该返回可迭代的请求对象。但是,将请求对象放入列表(可迭代)似乎不起作用。相反,可以在process_spider_output中间件函数中使用yield result
。
由于主要问题已解决,因此我将保留此答案作为参考。希望能对这种情况有更好的解释。