电商数据抓取里,最容易被误判的不是“抓不到”,而是“抓到了很多,但真正新增的对象很少”。我在排查商品监测项目时见过一种典型情况:任务日志显示单日写入 48 万条商品记录,报表却只比前一天多出 1.7 万个有效商品;剩下的数据并非全部无用,而是同一商品从搜索页、类目页、活动页和店铺页反复出现,叠加任务重试、SKU 拆分和历史价格更新后形成的“数据虚胖”。因此,增长负责人自查采集目标时,第一件事不应是要求团队“再抓多一点”,而应先判断增长的是商品对象、页面记录,还是采集事件。
电商数据抓取:增长负责人自查表:采集目标最容易出现的重复数据多
在增长团队的周报里,“本周采集商品数”“竞品覆盖数”“新增 SKU 数”经常被放在同一张表中。但这几个指标的统计对象并不相同。采集商品数可能计算的是页面返回记录,竞品覆盖数计算的是去重后的商品实体,而新增 SKU 数还需要排除过去已经出现过的规格对象。如果没有先定义口径,采集任务越稳定,报表反而可能越不可信。
我通常会要求团队把“记录数、对象数、事件数”拆成三个独立指标。记录数回答“系统写入了多少行”,对象数回答“识别出了多少个商品或 SKU”,事件数回答“发生了多少次价格、库存或页面状态变化”。三者不能互相替代,尤其不能把记录数直接当作市场新增量。
| 统计对象 | 回答的问题 | 常见重复来源 | 是否应直接删除 |
|---|---|---|---|
| 页面记录 | 某次采集返回了多少条结果 | 多入口展示、分页重叠、推荐位重复 | 不一定,需保留来源信息 |
| 商品实体 | 实际识别出多少个商品 | 商品 ID 缺失、标题变化、店铺维度混乱 | 通常需要合并或去重 |
| SKU 实体 | 实际覆盖了多少个规格对象 | 规格拆分不一致、颜色尺码字段缺失 | 需要按业务主键判断 |
| 采集事件 | 某商品被采集或更新了多少次 | 任务重试、并发执行、消息重复消费 | 无效重复应抑制,有效变化应保留 |
| 历史快照 | 价格、库存和状态如何变化 | 相同时间、相同值反复写入 | 可压缩无变化快照,不能删除真实变化 |
重复数据的根源通常不是数据库里多了几行,而是系统没有回答清楚:这几行记录代表的是同一个对象,还是不同时间、不同页面、不同店铺下的有效事实。商品名称相同,可能是不同店铺的不同商品;商品名称不同,也可能只是促销词或包装词发生了变化。
因此,专业的去重逻辑不是“找相似文本后删除”,而是先建立对象身份,再决定哪些记录合并、哪些记录保留。最理想的身份组合通常是平台标识、店铺标识、商品 ID、SKU ID;当稳定 ID 不完整时,才使用品牌、型号、规格、店铺和规范化链接等字段辅助判断。
如果目标是建立商品主库,系统应该尽量避免同一商品生成多条当前状态记录。如果目标是监测价格变化,同一商品在不同时间出现多次是有价值的,删除它们会让价格趋势断裂。如果目标是分析搜索曝光,则同一商品在不同入口出现的次数可能本身就是重要指标。
所以,“去重率越高越好”是一个危险判断。更准确的目标是:删除无效重复,保留有效变化,让每一行数据都能解释自己的业务用途。

一个商品通常不会只出现在一个页面。它可能同时进入关键词搜索结果、类目列表、店铺首页、活动会场、品牌馆、热销榜和相关推荐。对采集程序来说,这些页面都是不同任务;对商品主库来说,它们可能指向同一个对象。
如果系统用“页面行号”或“当前 URL”作为主键,那么同一商品在不同页面出现就会生成多条记录。如果直接用完整 URL 判断重复,活动参数、排序参数、追踪参数和分页参数变化,也会让同一个页面被误判为多个页面。
分页重复往往比多入口重复更隐蔽。常见原因包括页码从零开始还是从一开始、接口游标过期、排序字段不稳定、下一页游标没有正确更新,以及网络超时后重复请求上一页。此类重复通常集中在相邻页面边界,抽样查看前几页可能完全看不出来。
我的排查方法是把同一任务的 page_no、cursor、request_time 和返回的对象 ID 放在一起分析。只要发现相邻批次的对象集合交集明显偏高,就不能只归因于“商品本来就会重复”,而应继续检查翻页和游标状态。
采集任务失败后重跑,是电商数据系统里最容易被忽略的重复来源。请求已经成功,写入确认却因网络超时没有返回,调度器认为任务失败,于是重新执行。若数据库没有幂等键,第二次结果就会再次插入。
这类重复的特征很明显:重复记录往往拥有相同的 task_id、相近的采集时间、相同的商品字段和相同的原始链接。它与商品在多个页面自然出现不同,应该在任务执行和写入层解决,而不是等数据进入报表后再清洗。
同一商品的颜色、尺码、容量和套餐,可能在一个页面被合并成商品级记录,在另一个页面被拆成多个 SKU。如果团队只看商品名称,就会把多个规格错误合并;如果完全按照每个价格行入库,又可能把同一个 SKU 拆成许多条。
例如“某品牌运动鞋”是商品层对象,“黑色、42 码”是 SKU 层对象,“活动价 299 元”是某个时间点的状态。三者混在一张表里,后续无论是去重还是统计都会出现口径冲突。
这是增长团队最容易犯的误判之一。商品从 329 元变为 299 元,库存从 20 件变为 8 件,标题从“春季款”改成“新款”,都可能造成整行数据变化。但变化的是商品状态,不是商品身份。
如果商品主表以整行内容作为唯一判断条件,那么价格变化会被统计成新商品;如果价格历史表只保留最新值,又会丢掉竞品降价、促销持续时间和库存波动等关键信息。

URL 适合追溯来源,不适合天然承担商品身份。一个商品可能有多个入口链接,链接中还可能附带排序、活动、推荐位和追踪参数。即使去掉参数,不同页面路径也可能仍然指向同一个商品。
更稳妥的做法是保留两个字段:一个是规范化后的 source_url,用于追踪采集来源;另一个是 object_key,用于判断业务对象身份。二者分开后,系统既能知道商品从哪里来,也不会把来源页面数量误当成商品数量。
标题相似度适合做候选匹配,不适合直接做最终合并。标题中可能出现品牌、型号、颜色、容量、包装数量和促销词。把这些字段混在一起计算相似度,容易出现两个方向的错误:不同规格被合并,同一商品因促销词变化被拆开。
我会把标题相似度放在“待审核队列”中,而不是直接删除。只有当店铺、品牌、型号、规格、链接特征等多个字段同时满足条件时,才允许自动合并;否则应保留原记录,并标记为疑似同款。
全部删除会损失两类信息。第一类是曝光信息:商品在多少个入口出现,可能代表平台分发范围。第二类是时间信息:同一个商品在不同时间的价格、库存和状态变化,是价格监测和竞品分析的基础。
正确的做法是分层存储。商品主表保存当前对象,来源表保存页面和入口,事件表保存采集行为,历史表保存可解释的状态变化。重复只在相应层级内判断,而不是对所有表执行同一条删除规则。
数据库重复率下降,并不代表数据质量一定提高。过度去重可能把有效 SKU 合并掉,也可能把价格变化压掉。增长负责人需要同时看误合并率、漏识别率、真实新增率和变化保留率。
例如,系统把 100 个相似商品合并成 60 个对象,重复率看起来下降了 40%,但如果其中 15 个本应属于不同店铺或不同型号,报表中的竞品数量和价格中位数就会被严重扭曲。
在报表里使用 distinct 或去重函数,能够暂时让数字变得好看,却不能解决源头问题。任务日志、原始响应、商品主表和价格历史表仍然会持续膨胀,下一张报表还会重新遇到同样的问题。
报表层去重可以作为应急措施,但最终应把规则前移到对象识别、数据清洗和幂等写入阶段,并保留去重前后的数量变化,以便追溯规则是否误伤。
采集工具能够帮助完成请求、解析和任务调度,但它并不会自动知道“同一个商品”在业务上应该如何定义。工具解决的是获取问题,数据模型解决的是身份问题,分析平台解决的是监控和决策问题。
例如使用九数云这类数据分析与可视化平台时,可以把采集批次、平台、店铺、商品 ID、SKU ID、采集时间和去重标记统一接入,持续观察新增量和重复量的变化。但平台本身不能替团队替换业务口径;使用者仍需先确定主数据、事件数据和历史快照如何拆分。
自查的第一问不是“今天抓了多少条”,而是“今天希望新增多少个什么对象”。对象可能是平台商品、店铺商品、品牌型号、SKU、价格事件或搜索曝光记录。不同目标对应不同主键,也对应不同的重复判断。
检查字段中是否有 platform_id、seller_id、product_id、sku_id 等稳定标识。如果平台提供的商品 ID 在不同入口一致,应优先采用。若 ID 只在部分页面出现,需要设计候选主键和人工核验机制,不能直接用标题顶替。
主键还必须可追溯。出现合并错误时,团队应能知道两个对象为什么被合并、依据了哪些字段、由哪一条规则触发,而不是只能看到一个最终结果。
这是最关键的数据模型检查。至少需要判断现有表中是否把以下字段混在一张表里:商品身份、规格身份、页面来源、采集批次、价格、库存和更新时间。字段混在一起时,任何一项变化都可能生成一条“新商品”。
| 数据层 | 推荐保留内容 | 重复判断依据 |
|---|---|---|
| 商品主表 | 平台、店铺、商品 ID、品牌、型号、当前状态 | 平台 + 店铺 + 商品 ID |
| SKU 表 | SKU ID、商品 ID、颜色、尺码、容量、规格值 | 平台 + 店铺 + SKU ID |
| 来源表 | 页面 URL、入口类型、关键词、页面位置 | 对象 ID + 页面来源 + 采集批次 |
| 价格历史表 | 商品或 SKU、价格、优惠、采集时间 | 对象 ID + 时间粒度 + 状态值 |
| 任务表 | 任务 ID、节点、重试次数、开始和结束时间 | 任务 ID + 对象范围 |
没有 batch_id、task_id、retry_count 和 node_id,就很难判断重复是源页面造成的,还是系统重复执行造成的。增长负责人不一定要查看代码,但应要求数据团队能回答:这条重复记录来自哪次任务?任务重试了几次?是不是多个节点同时处理?
如果某一批记录的重复量突然升高,先看任务状态和写入日志通常比先调整清洗规则更有效。重复数据有时间和批次特征,日志是定位根因的第一手证据。
URL 标准化通常包括去除无业务意义的追踪参数、统一协议和域名大小写、处理末尾斜杠以及识别分页参数。但要谨慎保留活动页、店铺页和商品页的入口差异,因为这些差异可能用于曝光分析。
标题标准化可以去除明显的促销词、重复空格和无意义符号,但不能删除型号、规格和包装数量。标准化字段应与原始字段同时保存,方便复核。
建议至少监控四类异常:单批次重复率、真实新增率、同一对象的单位时间写入次数、任务重试后的新增放大倍数。阈值不必一开始就非常精准,关键是建立基线并观察突变。
价格历史不必每次都重复保存完全相同的值,但也不能只保存最新状态。常见做法是保留价格或库存发生变化的记录,同时保留固定时间间隔的心跳快照,用于证明任务仍然运行。
如果业务需要分析促销持续时间,则价格相同但活动状态不同的记录不能简单合并。如果只做当前价格展示,则可以压缩连续无变化快照,以降低存储和计算成本。
去重规则不是一次性开发任务。平台页面、商品字段和业务目标都会变化。增长负责人应明确规则负责人、变更审批人、误合并反馈入口和回滚方式,避免每次数据异常都临时修改 SQL。

我会把判断拆成两步。第一步确认两条记录是否代表同一个对象;第二步确认它们是否描述了同一对象的不同状态。如果身份不同,不能合并;如果身份相同但状态不同,通常应保留到历史表;如果身份相同、状态相同、时间和来源也相同,才属于高置信度无效重复。
这套逻辑可以避免一个常见错误:把“内容相似”当成“对象相同”。商品名称和图片很像,只能说明它们可能相似,不足以证明是同一个商品。相反,商品 ID 相同,即使标题发生变化,也更可能仍然是同一对象。
| 匹配等级 | 判断条件 | 处理建议 |
|---|---|---|
| 高置信度 | 平台、店铺、商品 ID 或 SKU ID 完全一致 | 自动归并到同一对象,保留来源和时间 |
| 中置信度 | 店铺、品牌、型号和规格一致,标题有轻微差异 | 进入规则匹配或抽样复核 |
| 低置信度 | 仅标题、图片或价格相似 | 不自动合并,保留疑似同款标记 |
| 冲突记录 | 商品 ID 相同但店铺、规格或平台字段冲突 | 暂停入库,优先检查解析和字段映射 |
竞品分析经常需要识别同款商品,但同款不一定是同一商品。不同店铺可能销售同一型号,供应链分析可以把它们归为同款集合;但店铺经营分析仍然需要保留不同 seller_id。若直接把同款合并成一个商品,店铺数量、渠道价格和销售主体都会丢失。
建议建立两层关系:product_id 表示平台或店铺内的商品身份,model_group_id 表示经过规则或人工确认的同款集合。这样既能做商品库统计,也能做型号级市场分析。
自动去重适合处理高置信度、重复量大且误合并代价低的场景。例如同一平台、同一店铺、同一商品 ID 的重复写入,通常可以直接使用唯一约束或幂等更新。
自动去重不适合处理跨店铺、跨平台、标题高度相似但规格不完整的场景。此类任务应输出疑似匹配结果,由业务人员抽样确认,再逐步扩大自动化范围。
每增加一层匹配规则,都有开发、计算、维护和误判成本。如果一个项目每月只有几千条低价值记录,复杂的图像相似度和实体解析未必划算;如果项目每天处理数百万条商品数据,简单的标题去重又会带来持续的业务损失。
我通常会用下面的方式估算:重复清理成本包括存储、计算、人工复核和错误决策损失;精细化成本包括开发、模型调用、规则维护和监控。只有当前者持续高于后者,才值得扩大匹配模型的复杂度。
下面的案例是我按真实项目中常见的链路整理出的脱敏情景,用来说明判断方法,不对应某一家企业的公开经营数据。某团队需要监测多个平台的品牌商品,每天采集关键词搜索页、类目页和活动页,并通过九数云建立采集量、有效新增量和价格变化看板。
项目初期,团队用“平台 + 商品标题 + 当前价格”作为去重条件。这样做的直接结果是:同一商品降价后被识别为新商品;活动页和搜索页的同一商品被识别为两条;同一商品的不同颜色因标题字段不完整而被错误合并。
第一周的情景数据如下:原始返回记录 126 万条,写入商品表 91 万条,去除完全重复后剩余 78 万条,历史商品库中真正首次出现的对象只有 6.4 万个。表面上看,采集量很大;从增长视角看,真正新增率只有 5.1%。
团队把 source_type 增加为搜索、类目、活动、店铺和推荐五类,并统计同一商品的来源数量。结果发现,约三分之一的商品至少同时出现在两个入口,活动期间同一商品在活动页和搜索页重复出现的比例明显上升。
这部分记录不应全部删除。对于商品主库,只保留一条商品实体;对于曝光分析,则保留商品出现过的入口、关键词和页面位置;对于活动分析,则记录它是否进入活动页。一次重复在不同业务表里可能代表不同含义。
随后团队对 task_id、retry_count 和 collected_at 做关联分析,发现某些时间段的网络超时会触发整批重试。重试批次中的商品字段几乎完全一致,且写入时间相差不到两分钟。这类重复与页面天然重复无关,应该通过幂等写入和任务状态确认解决。
如果只在九数云的分析看板里使用去重函数,数字可以暂时恢复正常,但原始库仍会继续膨胀。最终方案是为任务批次建立唯一约束,并让写入逻辑在重复执行时执行更新或跳过,而不是无条件插入。
团队又把商品主表和价格历史表拆开。商品主表以平台、店铺和商品 ID 维护当前状态;价格历史表按商品、采集时间和价格变化记录事件;来源表单独保存商品在哪个页面出现。
拆分完成后,商品主表中的真实新增量明显下降,但价格变化记录变得更完整。增长负责人不再看到一个虚高的“新增商品数”,而是同时看到有效新增、价格变动商品数和活动入口覆盖数,决策质量反而提高。

在这个情景里,采集系统并没有因为去重而变得“抓得更少”。它只是把原来混在一起的数字分成了几个可以解释的指标:页面覆盖量、商品实体数、SKU 数量、真实新增量和价格变化次数。
| 指标 | 治理前表现 | 治理后表现 | 业务含义 |
|---|---|---|---|
| 原始页面记录 | 126万条 | 126万条 | 采集覆盖和任务执行规模,没有被删除 |
| 商品主库记录 | 78万条 | 81.5万条 | 因SKU误合并被重新拆分,数量不一定下降 |
| 真实新增对象 | 无法稳定统计 | 6.4万个 | 与历史对象比对后的首次出现数量 |
| 价格变化事件 | 混入商品新增 | 单独统计 | 支持促销和竞品价格趋势分析 |
| 任务重试重复 | 无法定位 | 按批次追踪 | 可直接反馈给调度和写入链路 |
采集端最重要的不是马上得到干净结果,而是保留足够的原始事实。建议保存原始 URL、来源页面、请求批次、采集时间、解析版本和原始商品标识。这样当去重规则变化时,可以重新处理,而不必重新请求所有页面。
原始数据需要设置留存周期,避免无限增长。对高价值字段可以长期保留,对大体积响应和临时页面可以按业务需要压缩或定期删除。保留原始事实不等于永久保存所有内容。
身份字段包括平台、店铺、商品 ID、SKU ID、品牌、型号和规格;状态字段包括价格、库存、活动状态、评分、评论数和排名;来源字段包括页面 URL、关键词、入口和页面位置;执行字段包括 task_id、batch_id、node_id 和 collected_at。
字段分层后,规则会更容易解释。身份字段变化需要触发实体判断,状态字段变化需要写入历史事件,来源字段变化需要更新曝光关系,执行字段变化则用于定位任务重复。
硬规则适合处理明确身份,例如平台、店铺和商品 ID 完全一致。软匹配适合处理缺失 ID 或跨店铺同款识别,但必须保留评分、匹配依据和审核状态。
不要一开始就使用复杂模型解决所有重复。先统计硬规则可以覆盖多少重复,再观察剩余疑似重复的业务价值。如果大部分问题来自任务重试和主键缺失,增加文本模型只会掩盖真正的工程缺陷。
幂等键的设计要和表的用途对应。商品主表可以使用平台、店铺和商品 ID;SKU 表可以使用平台、店铺和 SKU ID;价格历史表可以使用对象 ID、采集时间粒度和状态值;来源表则需要加入页面入口和批次。
如果平台没有稳定 ID,可以先生成内部 object_key,但必须保存生成规则和候选字段。内部键不能成为黑箱,否则后续无法解释为什么两条记录被归为一个对象。
-- 以下为通用示意,不对应特定平台接口 CREATE UNIQUE INDEX uq_product_identity ON product_current (platform_id, seller_id, product_id); CREATE UNIQUE INDEX uq_collection_event ON price_history (platform_id, seller_id, product_id, collected_at, price); CREATE INDEX idx_collection_batch ON collection_raw (task_id, batch_id, collected_at);
示意代码表达的是数据治理思路,不代表所有平台都适用同样的主键。若商品 ID 可能为空,应先建立缺失值处理策略,不能让空值把不同对象错误地归为同一条记录。
在分析看板中,我建议把原始记录数、去重后对象数、真实新增数、变化事件数和疑似重复数放在同一张概览页。数字之间的差距本身就是诊断信息:原始记录暴增而真实新增不变,往往说明采集入口或任务执行出了问题。
使用九数云等分析平台时,可以将任务批次、商品主键和去重状态作为筛选条件,分别查看平台、店铺、品类、入口和日期维度。重要的是不要只制作一个“去重后商品数”卡片,而要让业务人员能够从结果回溯到来源和处理过程。

优先建立商品实体表和来源关系表。商品实体表只保留对象身份和当前状态,来源关系表记录它出现在哪个页面、关键词和活动入口。这样可以同时满足商品覆盖和页面曝光两个目标。
优先修复任务状态确认、幂等写入和唯一约束,不要先做标题相似度。检查请求成功但回执超时的情况,区分“任务未完成”和“任务已完成但状态未确认”。对于可重试任务,应让第二次执行具备安全重放能力。
同时增加 retry_count、last_error、write_status 和 idempotency_key。只有能定位重试链路,团队才能判断是网络问题、调度问题还是数据库写入问题。
先定义商品层与 SKU 层的边界,再补齐颜色、尺码、容量和套餐字段。规格信息缺失时,不要强行从标题中提取并自动合并所有结果,应把低置信度记录放入待确认队列。
对服装、食品、家电和美妆等品类,规格字段的重要性不同。服装需要重视颜色和尺码,食品需要重视净含量和包装数量,家电需要重视型号和版本,美妆需要重视容量和套装关系。统一模板往往不如品类化规则准确。
先建立规范化字段,保留原始标题和原始链接。标准化时可以处理大小写、空格、追踪参数和常见促销词,但不能随意删除型号、规格、版本和包装数量。
对于跨店铺同款识别,应增加 model_group_id,而不是直接覆盖 product_id。只有当业务明确要做型号级分析时,才将多个店铺商品关联为同款集合。
把价格、库存和活动状态从商品身份字段中拆出来,建立历史事件表。主表只更新当前值,历史表按照业务需要记录变化点。
如果企业需要计算促销持续时间,必须保留价格开始时间和结束时间;如果只关注每日竞品价格,则可按天保留最后一次有效快照。两种需求的存储成本不同,不能用同一种保留策略。
优先治理高频、高损失、可确定的重复。通常顺序是:任务重试、并发写入、稳定 ID 去重、主数据与历史数据拆分、疑似同款人工复核。不要把有限的人力先投入到所有长尾标题的语义匹配。
可以从一个平台、一个品类或一个核心店铺开始建立基线,验证规则的误合并率和漏识别率,再逐步推广。小范围验证的价值在于把规则风险控制在可回滚范围内。

如果主要痛点是数据库和计算成本,可以优先压缩连续相同的价格、库存和状态快照。保留首次出现、最后一次出现以及发生变化的节点,通常比每天无差别保存全部记录更节省资源。
但压缩前要确认业务是否需要证明某个状态在一段时间内持续存在。对于促销持续时间、库存断货时长和排名波动分析,过度压缩可能会损失时间边界。
新市场探索和竞品发现更害怕漏掉真实商品,而不是多保留一些疑似重复记录。此时自动合并阈值应更保守,低置信度对象先保留,再通过人工抽样和后续数据补全确认关系。
这类场景的核心指标不是重复率最低,而是有效商品召回率和误合并率。一个被错误合并的竞品可能会直接影响市场规模、价格带和品牌排名判断。
价格监测不应只保留最新价格。至少需要记录对象、价格、优惠类型、采集时间和来源。若只使用当前状态表,无法回答“什么时候开始降价”“促销持续了多久”“价格是否在活动结束后恢复”等问题。
在价格数据中,重复的同值快照可以压缩,但价格发生变化的记录不能因为“商品已经存在”而删除。商品身份重复和价格事件重复必须采用两套规则。
实时系统往往需要先快速接收数据,再异步完成去重和归并。此时可以允许原始层短时间存在重复,但必须明确数据进入业务看板的延迟和最终一致性时间。
如果业务人员不知道看板处于“实时原始状态”还是“清洗完成状态”,就会把两个时点的数字互相比较,产生新的误判。因此,页面上应显示数据更新时间、清洗状态和统计口径。
跨平台同款识别涉及品牌、型号、规格、包装和店铺关系,自动化很难在所有品类上保持稳定。对于核心商品和高价值竞品,可以保留人工复核;对于长尾商品,则采用疑似同款标签而不是强制合并。
人工复核并不意味着系统失败。只要系统能把低置信度候选准确筛出来,把复核结果沉淀为规则,人工工作量就会逐步下降。真正低效的是让人工从数十万条原始记录中盲目寻找重复。
建议首页至少放置原始记录数、商品实体数、SKU 实体数、真实新增数、价格变化数和疑似重复数。每个指标都要显示统计周期、去重口径和更新时间,避免不同团队用不同数字讨论同一件事。
如果使用九数云搭建管理看板,可以把平台、店铺、品类、入口、任务批次和日期作为联动筛选项。增长负责人先看总体异常,再下钻到具体平台和任务;数据工程师则可以继续查看重复记录的原始来源。
一个很实用的指标是新增转换率,即真实新增对象数除以原始采集记录数。它不是越高越好,也不是跨项目完全可比,但在同一项目内可以用来观察异常。若采集量稳定而新增转换率突然下降,应检查入口重叠、任务重试和历史库匹配。
另一个指标是重复放大倍数,即原始记录数除以去重后对象数。放大倍数长期偏高,可能说明采集入口过多,也可能说明目标本身具有高频曝光特征。只有结合来源类型和业务目标,才能判断它是问题还是有效现象。
平均重复率容易掩盖异常店铺和异常任务。建议按平台、店铺、品类、入口和任务批次查看分布,寻找重复率最高的长尾对象。某个平台整体重复率 20%,并不代表每个店铺都一样,可能只有少数店铺或活动任务贡献了大部分重复。
对于同一商品的采集次数,也可以查看频次分布。大量商品只出现 1 至 3 次属于正常覆盖;少数商品出现数百次,可能是推荐位循环、分页错误或重试异常,需要单独检查。

| 异常信号 | 优先检查位置 | 建议动作 |
|---|---|---|
| 记录数突然翻倍 | 任务重试、并发节点、写入日志 | 核对批次和幂等键,暂停异常任务重跑 |
| 新增率连续下降 | 入口重叠、历史库匹配、分页逻辑 | 按入口拆分对象交集,抽查相邻分页 |
| 某品类重复率极高 | 规格字段、标题解析、品类规则 | 检查颜色、容量、包装和型号是否缺失 |
| 价格事件明显减少 | 历史表写入、变化判断、时间粒度 | 确认是否因过度去重丢失有效变化 |
| 不同店铺商品大量合并 | 同款规则、seller_id、model_group_id | 恢复店铺维度,暂停低置信度自动合并 |
电商数据抓取首先要确认访问权限、平台规则、业务必要性和适用法律要求。公开展示不代表可以无限频率批量获取,也不代表可以把所有字段用于新的商业目的。增长负责人应让采集范围与实际业务目标对应。
本文讨论的是数据质量、对象识别和治理方法,不涉及绕过验证、规避访问控制或隐藏采集行为等做法。技术方案越复杂,越需要把数据来源、访问授权和用途记录清楚。
商品、价格、库存和公开页面状态通常与商品分析直接相关;消费者姓名、联系方式、订单信息和个体行为数据则可能与采集目标无关。无关字段不应因为“顺手可以拿到”就纳入数据仓库。
如果任务确实涉及敏感字段,应设置最小化采集、脱敏、权限隔离、访问审计和定期删除机制。数据表中的字段越多,泄露和误用的风险越高,治理成本也越高。
原始页面或响应数据便于回溯,但大体积原始数据会带来存储和权限风险。建议根据字段价值设置分层留存:身份和审计字段保留更久,临时解析内容和无业务价值的原始响应按周期清理。
删除策略也应记录在任务文档中,包括保留期限、责任人、备份处理和异常恢复方式。没有删除机制的数据仓库,最终会把历史错误、过期商品和无用快照长期混在一起。
电商数据抓取的核心竞争力,不是把页面抓得越多越好,而是让采集结果能够支撑真实判断。增长负责人需要区分商品实体、SKU 实体、页面来源、采集事件和历史快照;数据团队需要用稳定主键、幂等写入和分层模型把这些对象分别管理;分析团队则需要把原始记录、真实新增和有效变化同时呈现。
我建议下一步不要从“重新写一套去重程序”开始,而是先做一次半天的采集目标盘点:列出所有统计指标,写清每个指标的对象、主键、时间口径和允许重复的范围。然后抽取一个高频平台或核心品类,随机检查 1000 条重复记录,给每条记录标记为多入口、任务重试、SKU 混乱、价格变化、同款关系或真正无效重复。
完成这一步后,团队通常会发现,重复并不是一个单一问题,而是几种不同问题叠加。能把重复记录解释清楚,比单纯把重复率降到最低更重要;能让增长负责人知道哪些新增是真新增,比让采集总量看起来更大更有价值。
如果需要建立长期监控,可以把任务批次、对象主键、重复类型、真实新增率和变化保留率接入统一分析看板,例如使用九数云进行多平台数据关联、指标拆解和异常追踪。最终目标不是让数据库变小,而是让每一个“新增”“覆盖”“降价”和“竞品数量”都经得起回溯。
我负责过一次跨平台商品监测项目,最初每天采集约42万条记录,但业务团队发现报表里的“新增商品数”明显虚高。我原以为是解析程序重复写入,后来按商品、页面、任务批次三个维度拆开核对,才发现重复并不是单一故障,而是多个入口和重试机制叠加造成的。
重复数据通常不是某一个采集脚本写错了,而是“同一对象被多次看见”和“同一任务被多次执行”混在了一起。搜索页、分类页、活动页和店铺页可能同时返回同一个商品;网络超时后的任务重试,又可能把整批结果再次写入。
在那次项目中,我们将42万条原始记录按平台商品ID、店铺ID和SKU ID重新归并,发现其中约31%的记录来自多入口重复,约7%来自任务重试,另有一部分是因为商品标题变化被误判为新商品。真正可计入“新商品”的数量,只有原始记录的约六成。
重复来源典型表现优先检查字段 多页面出现同一商品在搜索页和活动页各出现一次商品ID、来源页面 任务重试同一批商品在相近时间重复写入task_id、batch_id、采集时间 身份识别错误促销词变化后被当成新商品标题、规格、店铺ID 所以,增长负责人第一步不应要求团队“马上去重”,而应先问:这些记录是重复商品、重复页面,还是有价值的历史快照?
只有先分清对象和事件,后续删除或合并才不会误伤业务数据。
我以前遇到过一个看似合理的去重方案:以商品ID为唯一键,只保留最新一条记录。上线后,商品总量变得干净了,但价格趋势报表失去了变化轨迹,运营无法判断竞品什么时候降价。这个坑让我意识到,去重规则必须跟数据用途绑定,不能让一套规则覆盖所有数据表。
判断标准不是“内容相同就删除”,而是看这条记录承担什么业务职责。商品主表关注当前有哪些商品,通常需要一件商品一条有效记录;价格、库存和排名表关注变化过程,同一商品在不同时间出现多次,反而是有价值的数据。可以用“对象层”和“事件层”拆分处理。
对象层的唯一键通常是平台ID、店铺ID、商品ID或SKU ID的组合;事件层则需要把对象ID、采集时间、价格、库存、排名等字段一起纳入判断。
数据类型是否允许同一商品多条记录建议规则 商品主数据通常不允许按平台、店铺、商品ID幂等更新 价格历史允许保留有效价格变化,过滤同时间同价格重复写入 库存快照允许按采集时间和库存状态保留变化 页面来源记录允许保留来源,用于分析曝光入口 我的判断经验是:如果删除一条记录后,业务无法回答“这个商品什么时候变价、从哪个入口发现、哪次任务采到”,那它可能不是无效重复,而是被错误归类的历史事件。
我曾经看过一份周报,采集量从每天18万条涨到29万条,团队把它解释为覆盖能力提升。但我把采集量、新增对象数和去重后的有效对象数放在同一张表后,发现采集量上涨主要来自页面扩展和任务重跑,真实新增率反而从64%降到了41%。
只看采集总量,几乎一定会高估增长。增长负责人至少要同时看记录量、真实新增量、重复率和覆盖率,否则很容易把采集系统的忙碌程度误认为市场数据的增长。我建议每天保留一张四列对照表:原始采集记录、去重后对象数、真实新增对象数、有效变化事件数。
四个数字分别回答“抓了多少”“识别出多少对象”“真正新增多少”“发生了多少业务变化”。
指标计算思路异常信号 记录重复率重复记录÷原始记录突然升高,可能是多入口或重试 真实新增率新对象数÷原始记录持续下降,说明采集量在虚增 任务重试重复率重复批次记录÷总记录集中出现在超时或失败任务后 有效变化率价格、库存等有效变化事件÷对象快照数过度去重可能丢失业务变化 我的经验是,异常告警不要只设置“采集量下降”。
更实用的规则是:采集量增长超过30%,但真实新增率下降超过15%;或者同一批次的重复记录超过历史均值两倍,就触发人工排查。
我评估过几种数据服务,最容易踩的坑是只看“每天能采多少条”和“支持多少平台”。有一家服务商演示的数据量很大,却无法提供商品ID、任务批次和原始链接,出了重复问题后只能重新跑一遍,最后增加的不是有效覆盖,而是存储和清洗成本。
判断服务商是否真正解决重复问题,不能只听“支持自动去重”。这句话可能只代表按标题或URL做简单合并,无法说明它是否区分了商品实体、SKU、页面来源和历史快照。
我在评估时会要求对方用一组故意制造重复的样本现场演示:同一商品出现在三个页面、同一任务重试两次、商品标题增加促销词、价格发生变化、不同店铺销售同款商品。只要对方无法解释每种情况的保留或合并逻辑,后续就很难稳定使用。
测试问题合格表现风险表现 同商品多页面出现主数据不重复,但保留来源页面简单删除来源记录 任务失败后重跑支持批次追踪和幂等写入重跑后记录直接翻倍 价格发生变化主表更新,历史表保留变化把变化当成新商品或直接覆盖 不同店铺销售同款按业务口径决定合并或拆分只按标题强行合并 签约前还应要求查看字段清单和异常处理流程,至少确认是否提供平台ID、店铺ID、商品ID、SKU ID、采集时间、任务批次、来源URL和原始数据指纹。
真正成熟的服务,不是承诺“零重复”,而是能说明重复从哪里产生、哪些记录被合并、哪些变化被保留。


读者评论
文章把页面记录、商品对象、SKU和采集事件区分开,解释得比较清楚。实际项目中,先统一统计口径,确实比单纯追求采集量更重要。
按标题或完整URL去重容易误合并,这一点很有参考价值。尤其是价格监测场景,历史快照不能简单删除,否则会影响趋势判断。
文中的排查思路比较落地,分页游标、任务重试和幂等写入都属于常见问题。建议再结合误合并率和漏识别率设置长期质量指标。