先给结论:同一个 URL 在不同设备或登录状态下返回不同内容,通常不是“死链检测结果互相矛盾”,而是你比较的不是同一条访问路径。要对照,先把“访问身份”和“返回结果”拆开记录:用同一时间窗、同一请求方式,分别保存匿名桌面、匿名移动、已登录三种状态下的状态码、最终 URL、响应头和首屏可见正文,再判断差异来自重定向、权限门禁还是内容分发。只有把这三层证据分开,后续修复动作才不会误伤正常用户路径。
第一种解释是权限差异。已登录状态携带 Cookie 或令牌,服务器可能返回 200 并展示会员内容;匿名状态则可能返回 302 跳登录页,或返回 200 但正文只有登录提示。这种情况下,状态码相同不代表内容相同,状态码不同也不一定是链接失效。
第二种解释是设备分发。同一地址在移动端可能被重定向到 /m/ 路径,或由前端根据 User-Agent 渲染不同模块。此时桌面端看到的 404 可能只出现在某个设备分支,而另一分支正常。两种解释都会造成“同一地址结果不同”,但修复对象完全不同:前者要处理访问控制与爬虫可见性,后者要处理重定向规则与渲染一致性。
要区分上述解释,不能只看一个状态码。建议对每个目标地址做三次请求,并在同一时间窗内完成:
每次记录四项:HTTP 状态码、最终 URL、Location 或 Content-Location 等响应头、首屏可见正文摘要。对照时先看最终 URL 是否变化,再看可见正文是否包含目标内容。
可区分的原因证据:如果匿名桌面与匿名移动的状态码和最终 URL 一致,仅正文模块不同,更可能是设备分发或前端渲染;如果匿名请求都跳转到同一登录地址,而已登录请求返回 200 并显示目标内容,更可能是权限门禁;如果只有移动端最终 URL 进入一个不存在的路径并返回 404,则更可能是重定向规则写错。注意,单个状态码归零或某次抓取量下降,不能单独证明链接已死,也可能是限流、临时故障或请求头被拒绝。
假设某商品页在匿名桌面返回 200,在匿名移动返回 302 到 /m/old-item,而该路径返回 404;已登录桌面返回 200。此时不要立刻把原地址标记为死链。先做一步实际动作:把移动 User-Agent 的请求重放一次,并关闭自动跟随重定向,记录第一跳的 Location。如果第一跳指向 /m/old-item,而该路径确实不存在,那么修复对象是移动重定向规则,而不是原商品页本身。修复后,再用同一移动 User-Agent 请求原地址,确认最终 URL 回到可用路径且可见正文包含目标内容;只有这一步通过,才把原地址从待修复清单移出。
反过来,如果关闭重定向后原地址本身返回 404,而已登录请求返回 200,则修复对象是匿名可见性,不是移动路径。这个顺序能避免把权限问题误判为链接失效。
坑一:把登录后的 200 当成匿名可用。已登录状态看到正常内容,不代表搜索引擎或匿名用户能看到同一内容。判断死链时应以匿名请求的最终结果为准,登录结果只用于解释差异来源。
坑二:忽略最终 URL。只看初始状态码会漏掉 302 后的 404。必须记录重定向链的每一跳,至少记录第一跳和最终落点。
坑三:用 robots.txt 或站点地图代替实际请求。robots.txt 的抓取限制不等于可靠的索引移除,站点地图也不保证收录。它们不能回答“这个地址当前返回什么”,只能作为辅助线索。不同搜索引擎对重定向和渲染的处理须分别核查,不能用一个引擎的表现推断另一个。
对照完成后,按差异来源分派动作:权限门禁导致的匿名不可见,先确认是否应公开,再调整访问控制或提供匿名可读的替代路径;设备分发导致的路径分叉,先修正重定向规则,再验证移动与桌面最终 URL 都可达;渲染差异导致的正文缺失,先确认服务端返回的 HTML 是否包含目标内容,再决定是否调整渲染方式。每一步动作后,都用同一组三状态请求复测,并保存前后两份记录。只有复测中匿名请求的最终 URL 可达且可见正文包含目标内容,才能认为该地址的对照问题已闭环。