Scrapy爬取Watch.de劳力士手表数据出现重复如何解决
Scrapy劳力士商品爬取重复问题解决方案
核心原因
你遇到的重复爬取大多是因为同一款商品会出现在列表页、「最近浏览」「新品到货」多个板块,部分站点会给不同板块的同个商品链接加上不同的来源参数,导致Scrapy默认的URL去重机制将其识别为不同地址,触发多次爬取。
可落地的解决方法
- 方案1:用商品唯一ID做去重(最适配你的场景)
你抓取的字段里已经包含商品唯一id,只需要在爬虫内维护一个已爬取ID的集合,每次提取完数据先判断是否已经爬过,未爬过再返回数据即可。 - 方案2:清理URL冗余参数,触发默认去重
在跟进商品链接前先清理掉URL里的来源类查询参数,只保留核心路径,Scrapy自带的RFPDupeFilter会自动过滤重复的URL,从请求层面避免重复爬取。 - 方案3:从提取规则源头排除冗余板块
定位「最近浏览」「新品到货」板块的父级CSS选择器,提取商品链接时直接跳过这两个板块下的所有链接,从源头避免拿到重复的商品地址。
修正后的完整代码示例(集成ID去重+默认URL去重)
import scrapy from urllib.parse import urlparse class WatchbotSpider(scrapy.Spider): name = 'watchbot' start_urls = ['https://www.watch.de/germany/rolex.html'] # 初始化已爬取商品ID集合 crawled_ids = set() def parse(self, response, **kwargs): # 提取所有商品链接 for link in response.css('div.product-item-link a::attr(href)'): raw_url = link.get() # 清理URL冗余参数,只保留核心路径 parsed_url = urlparse(raw_url) clean_url = parsed_url._replace(query='').geturl() yield response.follow(clean_url, callback=self.parse_categories) def parse_categories(self, response): for product in response.css('div.product-item-link'): product_id = product.css('span.product-item-id.product-item-ref::text').get() # 跳过已经爬取过的商品ID if not product_id or product_id in self.crawled_ids: continue # 记录已爬取ID self.crawled_ids.add(product_id) yield { 'id': product_id, 'brand': product.css('div.product-item-brand::text').get(), 'model': product.css('div.product-item-model::text').get(), 'price': product.css('span.price::text').get(), 'year': product.css('span.product-item-id.product-item-year::text').get() }
额外优化
如果你的爬虫规模较大,可以把已爬取ID集合换成Redis等持久化存储,避免重启爬虫后重复爬取历史数据。
内容的提问来源于stack exchange,提问作者SyrixGG
相关产品推荐
相关产品推荐

