正文内容完全一致时,响应头仍会改变百度对页面的处理判断:它决定百度是否认为这个 URL 值得抓取、以哪个地址作为规范版本、以及抓到的字节是否可信。所以两个都返回相同 HTML 的地址,可能一个被正常处理,另一个长期停在发现未抓取或抓取异常状态。先确认差异落在哪一类响应头上,再决定合并、保留还是回退。
不要把所有响应头差异当成同一件事。对百度而言,至少有三组信号在起作用:
Retry-After、以及服务器是否稳定返回 200。它影响的是百度愿不愿意继续来抓。Location、Link: rel="canonical"、Vary。它影响的是百度把权重和收录记在哪个 URL 上。Content-Type 与字符集、Content-Encoding。它影响的是百度解析出的正文是否与用户看到的一致。两个页面 HTML 相同,但如果 A 返回 200 加正常 Content-Type: text/html; charset=utf-8,B 返回 301 指向 A,那么 B 基本不会作为独立结果存在。反过来,如果 B 返回 200 却带 Vary: User-Agent,百度可能把它当作按客户端变化的页面,降低对同一 URL 的复用信心。
第一种条件:两个地址面向同一批用户、内容确实相同、且没有独立外链或历史收录价值。此时应合并。动作是把弱侧地址用 301 永久指向主地址,或至少在主地址输出指向自身的 canonical。结果是百度后续抓取弱侧时得到明确信号,逐步把索引集中到主地址。下一步应观察弱侧是否从结果中减少,而不是立刻删除服务端配置。
第二种条件:两个地址面向不同地区、不同设备或不同登录状态,内容相同但必须分别可访问。此时不应简单 301 合并,而要用 Vary 明确声明差异维度,并让每个地址都有自洽的 canonical。代价是百度需要更多抓取预算来分别验证,收录速度通常慢于单地址。若 Vary 设置错误,比如对全部请求声明 Vary: User-Agent 而实际内容并不随 UA 变化,百度可能反复回抓却拿不到稳定版本。
假设同一篇文章可通过 /a 和 /a?from=home 访问,HTML 完全相同。若 /a 返回 200 且 canonical 指向自身,/a?from=home 返回 200 且 canonical 也指向 /a,百度大概率把后者视为重复,收录集中在前者。若把 /a?from=home 改成 302 临时跳转到 /a,百度会继续把 /a?from=home 当作原地址并反复检查,收录判断被推迟。若改成 301,信号更接近永久合并。
这里的关键不是哪个状态码“更好”,而是它是否与你的真实意图一致。临时活动参数适合 302,永久废弃地址适合 301。用错方向会让百度在“保留旧地址”和“转移信号”之间做出与你预期相反的选择。
发现两个地址内容相同但响应头不同后,按以下顺序处理:
curl -I 分别取两个地址的响应头,记录状态码、Location、Content-Type、Vary、Cache-Control。验证时注意:抓取日志里某地址请求量下降,不能单独证明处理正确。它也可能是百度降低了整体抓取、robots.txt 被改动、或服务器对百度 UA 返回了不同状态。要结合响应头和实际返回内容一起判断。
如果差异来自 CDN 或反向代理自动添加的头部,比如边缘节点给部分请求加了 Vary: Accept-Encoding,通常不影响百度对正文的判断,因为这是压缩协商而非内容差异。但如果代理把部分请求变成 403 或 503,百度看到的就是抓取失败,与内容是否相同无关。
另外,站点地图里同时列出两个地址,不代表百度会都收录;robots.txt 禁止抓取也不等于从索引移除。响应头只能解决“百度如何理解这个地址”的问题,不能替代内容质量、外链和站点整体可信度的判断。两种做法都成立的前提是:你的选择与地址的真实用途一致,并且能在响应头、页面 canonical 和站点地图三者之间保持一致。