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

基于Scrapy框架统计网站重复URL数量及相关问题问询

如何统计Scrapy爬虫中的重复URL及次数

Scrapy自带的RFPDupeFilter只会判断URL是否重复并跳过,但不会记录重复次数。要实现统计需求,我们可以通过自定义去重过滤器继承原有逻辑并添加计数功能,最后在爬虫结束时输出结果。下面是具体步骤:

步骤1:自定义去重过滤器

在你的Scrapy项目中新建dupefilters.py文件,写入以下代码:

from scrapy.dupefilters import RFPDupeFilter
from scrapy.utils.request import request_fingerprint

class CountDupeFilter(RFPDupeFilter):
    def __init__(self, path=None, debug=False):
        super().__init__(path, debug)
        # 用字典存储URL与对应的重复次数
        self.url_counts = {}

    def request_seen(self, request):
        fp = request_fingerprint(request)
        url = request.url
        if fp in self.fingerprints:
            # 重复URL计数+1
            self.url_counts[url] = self.url_counts.get(url, 0) + 1
            return True
        self.fingerprints.add(fp)
        if self.file:
            self.file.write(fp + '\n')
        return False

步骤2:配置自定义过滤器到项目

打开项目的settings.py,找到DUPEFILTER_CLASS配置项,替换为我们自定义的类:

DUPEFILTER_CLASS = '你的项目名称.dupefilters.CountDupeFilter'

记得把你的项目名称替换成实际的项目文件夹名称。

步骤3:在爬虫结束时输出统计结果

在你的爬虫文件中重写close_spider方法,这里不能用yield输出item,但可以直接打印结果或写入文件保存:

class YourSpider(scrapy.Spider):
    name = '你的爬虫名称'
    # ... 其他爬虫配置(start_urls、parse方法等) ...

    def close_spider(self, spider):
        # 获取自定义去重过滤器的实例
        dupe_filter = spider.crawler.engine.downloader.middlewares.middlewares[0].dupefilter
        # 筛选出有重复记录的URL
        duplicate_urls = {url: cnt for url, cnt in dupe_filter.url_counts.items() if cnt > 0}
        
        if duplicate_urls:
            self.logger.info("=== 重复URL统计结果 ===")
            # 按重复次数从高到低排序输出
            for url, cnt in sorted(duplicate_urls.items(), key=lambda x: x[1], reverse=True):
                self.logger.info(f"URL: {url} | 被跳过的重复次数: {cnt}")
            
            # 写入文件持久化保存
            with open('duplicate_urls_stats.txt', 'w', encoding='utf-8') as f:
                f.write("=== 重复URL统计结果 ===\n")
                for url, cnt in sorted(duplicate_urls.items(), key=lambda x: x[1], reverse=True):
                    f.write(f"URL: {url} | 被跳过的重复次数: {cnt}\n")
        else:
            self.logger.info("本次爬取未发现重复URL")

补充说明

  • 这里统计的是被Scrapy跳过的重复次数,比如某个URL第一次被正常抓取,之后每次遇到都会计数+1。如果显示重复次数为3,说明该URL总共被尝试抓取了4次(1次成功+3次重复跳过)。
  • 如果想统计所有尝试抓取的次数(包含第一次),可以调整request_seen里的逻辑:不管是否重复,先对URL计数,再判断是否需要跳过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:39:58