在Scrapy中从数组中的多个请求收集项目

在Scrapy中从数组中的多个请求收集项目,scrapy,Scrapy,我写了一个小示例spider来说明我的问题: 类ListEntrySpider(scrapy.Spider): 起始URL=['https://example.com/lists'] def解析(自我,响应): 对于json.dumps(response.text)['id']中的i: 刮毛请求(f'https://example.com/list/{i} ,callback=self.parse_列表) def解析_列表(自身、响应): 对于json.dumps(response.text)[

我写了一个小示例spider来说明我的问题:

类ListEntrySpider(scrapy.Spider): 起始URL=['https://example.com/lists'] def解析(自我,响应): 对于json.dumps(response.text)['id']中的i: 刮毛请求(f'https://example.com/list/{i} ,callback=self.parse_列表) def解析_列表(自身、响应): 对于json.dumps(response.text)['list']中的条目: 收益率列表项目(**条目) 我需要将多个请求(所有
ListEntryItem
s)产生的所有项放在spider内的一个数组中,以便分派依赖于所有项的请求

我的第一个想法是链接请求,并在请求的meta属性中传递剩余的id和已经提取的项,直到到达最后一个请求

类ListEntrySpider(scrapy.Spider): 起始URL=['https://example.com/lists'] def解析(自我,响应): ids=json.dumps(response.text)['ids'] 屈服于自我。创建请求(ID,[]) def解析_列表(自身、响应): self.\u创建请求(response.meta['id',response.meta['items'].extend(list(self.\u extract\u list(response))) def完成(自我,响应): items=response.meta['items'].extend(list(self.\u extract\u list(response))) 定义提取列表(自我、响应): 对于json.dumps(response.text)['list']中的条目: 收益率列表项目(**条目) 定义创建请求(self,id:list,items:list[ListEntryItem]): i=ids.pop(0) 返回scrapy。请求( f'https://example.com/list/{i} ",, meta={'id':id,'items':items}, callback=self.parse\如果len(id)>1,则列出else self.finish )

正如你所看到的,我的解决方案看起来很复杂。我正在寻找更易读和不复杂的东西。

有不同的方法。一个是链接你所做的。发生的问题是链中的一个请求因为任何原因而被放弃。你必须非常小心,并且处理所有可能的错误。被忽略的请求

另一种方法是对所有“分组”请求使用单独的spider。 您可以通过编程方式启动这些spider,并将一个bucket(例如dict)作为spider属性传递。在管道中,您可以将每个请求中的项目添加到此bucket。从“外部”您可以侦听spider_closed信号,并获取此bucket,其中包含您的所有项目

在这里查看如何通过爬行器运行程序以编程方式启动爬行器:

调用爬虫程序运行程序的crawl()时,将一个桶传递给爬虫
crawler\u runner\u object.crawl(你的爬行器,bucket=dict())

并捕捉sider_关闭信号

from scrapy.signalmanager import dispatcher

def on_spider_closed(spider):
    bucket = spider.bucket

dispatcher.connect(on_spider_closed, signal=signals.spider_closed)
这种方法看起来可能比链接请求更复杂,但实际上它会使问题更加复杂,因为在spider中,您可以在不太关心所有其他请求的情况下发出请求