先给结论:不要用单一环境的返回结果判定某个地址是不是死链。正确做法是把“未登录+移动端UA”和“已登录+桌面端UA”当作两条独立证据链分别取样,只有当两条链在状态码、跳转终点和正文主体上同时指向失效,才把该地址归入死链。如果两者不一致,该地址应归入“条件性失效”,需要单独判定,不能直接批量清理。
同一URL在不同设备或登录状态下返回不同内容,常见成因有三类,每类的处理动作完全不同。
判断依据不是“哪个结果看起来更对”,而是哪个结果来自更接近源站、更少中间层的请求。回源结果优先于边缘缓存结果,未登录原始响应优先于登录后的重定向结果。
这个组合最接近搜索引擎爬虫的默认抓取环境,适合作为死链初筛的主口径。实施动作如下:
这一步的结果会直接决定下一步:如果初筛清单里大量地址返回200但正文为空,说明站点存在登录墙或UA分流,此时不能继续用这个口径批量判定,必须先补上“登录态对照”这一层。反之,如果初筛结果稳定,就可以直接进入修复流程。
登录态返回的内容代表真实用户可见状态,适合用来验证“未登录时看到的失效”是不是权限问题。实施要点:
这里有一个必须写清的边界:登录态取样不能规模化照搬。账号权限、会话有效期、并发限制都会让批量请求出现例外,个别样本成立不代表整站成立。可行的折中是先用手工取样确认分流规则,再用规则去匹配批量结果,而不是用登录态直接跑全站。
即使两条链都取了样,仍有三类现象会误导判断。
软404。状态码200但正文是“内容不存在”提示页。此时状态码不能作为依据,要看正文主体是否包含目标内容,而不是看响应头。
跳转到首页。很多站点把失效地址统一302到首页,这会让所有死链在状态码层面看起来正常。对照时要单独标记“终点为首页”的地址,它们应归入待确认,而不是有效。
抓取量骤降。某个目录的抓取量归零,可能是死链导致,也可能是robots.txt调整、站点地图变更、服务器限流或抓取预算重新分配。抓取量本身不能单独证明处理正确,需要结合日志中的状态码分布一起看。
假设某详情页在未登录移动端返回302到登录页,在已登录桌面端返回200且正文完整。按上面的口径,该地址不是死链,而是权限性失效,处理动作应是检查登录墙是否对爬虫UA也生效;如果生效,需要确认这是有意设计还是配置遗漏。再假设同一地址在两种条件下都返回404,则进入死链清单,修复后重新用未登录移动端口径复查状态码与正文,而不是用登录态复查,因为登录态不是搜索引擎看到的那一面。
把这两条链的字段固定下来之后,判断标准就不再依赖单次观察,而是依赖两组可对照的记录:状态码、跳转终点、正文主体。任何一项不一致,就先归入条件性失效单独处理,不进入批量删除。