Scrapy中的持久性重复过滤

3 投票
1 回答
2404 浏览
提问于 2025-04-18 14:45

我刚开始使用Scrapy,想找个方法来保存之前爬取过的URL,这样我在后续的爬虫中就能只获取新的、未知的URL的数据。我看到有几种不同的方法可以用来过滤重复的链接,还有几种方法可以保存数据。我想知道在Scrapy 0.24版本中,推荐的做法是什么。以下是我看到的选项:

关于重复过滤

可以在settings.py文件中找到DUPEFILTER_CLASS,这个在文档中还有提到。我也看到文档提到可以在ItemPipeline中放一个重复过滤器,具体可以参考这里:http://doc.scrapy.org/en/latest/topics/item-pipeline.html?highlight=duplicates#duplicates-filter

大家是使用DUPEFILTER_CLASS,还是在Item Pipeline中放一个重复过滤器呢?

关于持久化重复跟踪

我尝试使用scrapy-redis来保存之前爬取过的URL,这样可以被重复过滤器使用,但似乎我使用的任何DUPEFILTER_CLASS都被忽略了。我还看到有spider.state,如果在运行时使用JOBDIR选项,它会存储一个字典,但这似乎不太适合用来做重复过滤。

有没有人能给我指个代码示例,能在批次之间保存数据并进行重复过滤?

1 个回答

1

我没有代码片段,也没有足够的积分来评论你的问题,但我可以给你一个关于持久化网址重复过滤的建议。

首先,保持一个已经抓取过的网址数据库。

然后,创建一个下载中间件,做以下事情(用类似Python的伪代码表示):

if url isn't present: 
   add url to databse
   return None    # this tells scrapy to keep handling request as normal
else:
   raise IgnoreRequest

希望这对你有帮助。

补充说明:

http://doc.scrapy.org/en/latest/topics/downloader-middleware.html

如果你在使用爬虫蜘蛛,可以这样做来进行非持久化的过滤:

    rules = (
        Rule(SgmlLinkExtractor(unique=True,
                           deny=[r'.*QuickInfo.*'],
                           allow_domains=allowed_domains,
                           restrict_xpaths=['//*[starts-with(@id, "e")]//a',
                                            '//*[starts-with(@id, "HP_Priority")]//a']),
         follow=True),)

设置unique=True可以过滤掉这个爬虫实例的重复请求。

撰写回答