You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scrapy去重失效求助:self.ids_seen集合始终为空

解决Scrapy去重Pipeline中self.ids_seen始终为空的问题

嗨,刚瞅了你的代码片段,发现俩关键问题导致去重失效、self.ids_seen一直是空集合,咱们一步步来 fix:

1. 别忘启用Pipeline!

Scrapy不会自动加载你写的Pipeline类,必须在项目的settings.py里配置ITEM_PIPELINES,把你的DuplicatesPipeline加进去:

ITEM_PIPELINES = {
    # 如果你还有其他Pipeline(比如数据库存储的),也可以放在这里
    '你的项目名.pipelines.DuplicatesPipeline': 300,  # 优先级数值按需调整,300是中等偏前的位置
}

优先级数值越小,Pipeline执行越早,去重逻辑一般放在前面比较合理,能避免后续Pipeline做无用功。

2. 核心bug:没把处理过的id加入集合!

看你贴的process_item代码,只判断了item['id']是否在self.ids_seen里,但完全没把新的id添加到集合中!这样集合永远是空的,根本没法记录已爬的id。修改后的代码应该是这样:

from scrapy.exceptions import DropItem  # 别忘了导入DropItem异常!
import logging

class DuplicatesPipeline(object):
    def __init__(self):
        self.ids_seen = set()
        logging.warning(self.ids_seen)  # 这里初始化时空集合是正常的,别慌

    def process_item(self, item, spider):
        if item['id'] in self.ids_seen:
            raise DropItem(f"Duplicate item found with id: {item['id']}")
        else:
            self.ids_seen.add(item['id'])  # 关键!把当前item的id加入集合
            return item  # 必须返回item,让后续Pipeline继续处理它

另外你之前的代码里没写return item,如果漏掉这个,后面的数据库Pipeline就拿不到这个item了,这也是个容易踩的坑。

小提醒:内存去重的局限性

self.ids_seen是存在于Pipeline实例的内存里的,每次重启爬虫都会被清空。如果需要跨爬虫运行的持久化去重,你得把已爬id存在Redis、数据库或者本地文件里,但新手阶段先搞定当前的内存去重就好啦。

先试试上面这两个修改,应该就能解决你的问题了!

内容的提问来源于stack exchange,提问作者Octorber12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:14:11