scrapy 如何从RFPDupeFilter或CustomFiler生成项目

uqcuzwp8  于 2022-11-23  发布在  其他
关注(0)|答案(1)|浏览(108)

我正在使用Scrapy抓取不同网站的页面。对于每一个scrapy.Request(),我设置了一些 meta数据,用于生成一个项目。也有可能我的代码生成多个scrapy.Request(),用于相同的网址,但具有不同的元数据。

yield scrapy.Request(url='http://www.example.com', meta={'some_field': 'some_value'} ..)

现在我可以设置dont_filter=True,而scrapy不会阻止复制请求。

yield scrapy.Request(url='http://www.example.com', meta={'some_other_field': 'some_other_value'}, dont_filter=True, ..)

但是,由于对于重复请求,我只对scrapy.Request()上的元数据集感兴趣,所以我希望从RFPDupeFilterCustomDupFilter中产生一个Item,这样它将由item管道写入JSON。

class CustomDupFilter(BaseDupeFilter):

        def request_seen(self, request: Request) -> bool:
            fp = self.request_fingerprint(request)
            if fp in self.fingerprints:
                yield request.meta['some_other_value'] # yield metadata as Item
                self.fingerprints.add(fp)
                return True
            else:
                return False

任何帮助都是非常感谢的。

hvvq6cgz

hvvq6cgz1#

我不认为你可以在Dupefilter中产生项目,但我认为一种解决方法是禁用Filter,并在自定义蜘蛛中间件中处理重复请求。

class DupeFilterMiddleware:
    seen_requests = set()

    def process_spider_output(self, response, result, spider):
        for output in result:
            if isinstance(output, scrapy.Request) and fingerprint(output) in self.seen_requests:
                # yield from meta
            elif isinstance(output, scrapy.Request):
                self.seen_requests.add(fingerprint(output))
                yield output
            else:
                yield output

相关问题