如何用Python Scrapy获取无重复的en.wikipedia.org域名网页URL?
解决Scrapy抓取维基百科出现重复URL的问题
一、先优化爬虫代码(最直接的解决方式)
你当前的爬虫里LinkExtractor未做过滤,会抓取页面里所有链接(包括同一页面带不同锚点的链接),这是重复URL的核心原因。修改rules里的LinkExtractor:
rules = ( Rule( LinkExtractor( allow_domains=['en.wikipedia.org'], # 明确只提取目标域名链接,彻底排除外部链接 process_value=lambda url: url.split('#')[0] if '#' in url else url # 去掉URL锚点,同一页面不同锚点统一为一个URL ), callback='parse_url', follow=True ), )
处理后,不管页面里的链接带什么锚点(比如#References),都会被转换成不带锚点的统一URL,从根源避免重复抓取。
二、settings.py的辅助配置(可选,强化去重)
如果仍有少量重复,确认以下配置(默认已开启,可明确设置):
- 确保去重过滤器启用:在settings.py里添加或确认:
# 默认基于请求指纹的去重过滤器 DUPEFILTER_CLASS = 'scrapy.dupefilters.RFPDupeFilter' # 若需调试去重逻辑,可设为True,会打印去重日志 DUPEFILTER_DEBUG = False
- 自定义URL指纹规则(处理特殊重复场景):若遇到URL参数不同但实际为同一页面的情况(维基百科中少见),可自定义指纹生成函数忽略无关参数。在settings.py里添加:
from scrapy.utils.request import request_fingerprint def custom_request_fingerprint(request): req = request.copy() # 去掉锚点 req.url = req.url.split('#')[0] # 如需去掉查询参数,可取消下面注释(示例:去掉所有查询参数) # req.url = req.url.split('?')[0] return request_fingerprint(req) URLFINGERPRINT_FUNCTION = __name__ + '.custom_request_fingerprint'
补充说明
维基百科页面里大量存在同一页面的章节锚点链接,这些URL主体相同仅锚点不同,Scrapy默认会判定为不同请求,导致重复输出。通过process_value去掉锚点,可解决90%以上的重复问题。
内容的提问来源于stack exchange,提问作者user166013
相关产品推荐
相关产品推荐

