基于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
相关产品推荐
相关产品推荐

