先给结论:报告里的“页数”往往不是“对象数”,而是抓取记录、URL 变体或分页行的计数。去重的正确顺序是先把计数口径改成对象标识,再决定合并还是排除;在缺少完整数据或权限时,最小动作是导出一份含对象标识与来源列的清单,用标识分组核对,而不是直接按页数删行。
假设你运营一个小型内容站,用站长实用软件导出站点报告,看到“已发现 1200 页”,但后台实际文章、栏目和标签加起来只有 600 个左右。你没有服务器日志权限,只能拿到工具导出的 CSV。此时不能直接断定“工具重复统计”,也不能直接删掉一半行,因为 1200 与 600 的差异至少有三类解释:同一对象对应多个 URL、抓取过程产生了分页或参数变体、以及部分页面属于其他子域或历史路径。
把这个问题当成去重任务,第一步不是删,而是确认“一行代表什么”。如果一行代表一次抓取记录,那么同一对象出现多次是正常的;如果一行代表一个可索引 URL,那么差异更可能来自 URL 变体。判断依据来自导出文件里有没有对象标识列,例如文章 ID、栏目 ID 或规范化后的路径。
报告页数与对象数量不一致,通常卡在三个口径上。把口径写清楚,去重键就自然出现。
假设导出文件同时有“URL”和“文章 ID”两列,那么按文章 ID 分组后统计唯一值,得到的数量才接近实际对象数。如果只有 URL 列,就先做规范化,再按规范化 URL 分组。这个动作的结果会直接决定下一步:若分组后数量接近 600,说明差异主要来自 URL 变体;若仍明显高于 600,说明还有跨域、历史路径或抓取记录混入,需要继续加条件。
没有日志、没有数据库权限时,不要试图一次性还原全貌。可执行的最小动作是:在导出文件中新增两列,一列是规范化 URL,一列是对象标识;然后按对象标识排序,人工抽查前 50 行,看同一对象是否对应多个 URL。这个抽查不能证明整体重复率,但能告诉你重复属于哪一类。
如果抽查发现同一文章同时出现带 ?from= 参数和不带参数的地址,处理动作是统一去掉跟踪参数后再计数。如果发现同一文章对应栏目页、标签页和正文页三个地址,处理动作是按对象标识保留正文页,其余标记为“来源页”而不是删除,因为栏目页和标签页本身也可能是有效入口。这个动作的结果会影响下一步:保留来源页意味着总数仍会高于对象数,你需要把“对象数”和“入口页数”分开报告,而不是强行让两个数字相等。
去重后如果报告页数还是高于实际对象数,可以按下面几组证据区分原因,不要只凭一个数字下结论。
假设你按主机名和状态码过滤后,1200 行降到 700 行,仍比 600 多 100。此时合理的解释可能是部分对象确实有多个有效 URL,也可能是实际对象数本身不是 600,因为后台统计口径与工具口径不同。请求量或抓取量归零、某项统计突然下降,同样不能单独证明去重正确,它们还可能来自抓取频率变化、权限收窄或过滤条件写错。要验证去重是否正确,应回到对象标识的唯一值数量,而不是回到页数。
最后一步是把决策留下痕迹。清单至少包含:原始行数、去重键、过滤条件、去重后对象数、被排除行的原因。这样下次报告页数再次不一致时,你能判断是口径变了还是数据变了。如果工具没有对象标识列,就只能做到 URL 级去重,并在结论里注明“对象数无法从当前导出中确认”。这个限制不是失败,而是避免把 URL 数当成对象数继续传递错误。
去重的目标不是让两个数字相等,而是让每个数字都有明确含义。只要口径写清楚,报告页数高于实际对象数就不再是异常,而是一个可解释、可复查的统计结果。