先给结论:把同一个URL分别取“禁用脚本的原始响应”和“执行脚本后的DOM”,然后只比较内链的href来源、可点击锚点数量、目标URL三组数据。差异几乎总落在三类原因上——链接由脚本写入、链接被脚本改写、链接被脚本删除。定位顺序应从原始响应里的链接锚文本反查:如果原始响应中根本没有这条内链,问题在“生成方式”;如果有但渲染后消失或变形,问题在“脚本改写或条件渲染”。
整页diff噪声太大。选一条你确定应该存在的内链,例如从旧文章指向仍需保留的支柱页。记录它在两种结果中的状态:
<a href="/target-path">是否字面存在。如果原始响应里没有这条链接,而渲染后有,说明这条内链是客户端注入的。此时要判断它对抓取是否可见:脚本注入的链接能否被抓取,取决于渲染能力与执行时机,不能默认等价于静态链接。
不要只凭肉眼判断。按下面三层依次取证,每层都能排除一类原因:
href是否存在。不存在→生成方式问题;存在→进入下一层。javascript:、#。被改写→脚本逻辑问题。实际动作示例:对旧页面禁用JS后抓取原始响应,若目标内链缺失,就把这条链接改为服务端输出;改完后再次对比两种结果,若渲染前后一致,说明这条内链已不依赖脚本,下一步可以批量检查同类旧模板,而不是逐页修补。
旧内容退出时,常见做法是整块删除或整站跳转,但这会连带丢掉仍有价值的内链。更稳的处理是分层:
假设一个例子:某旧文章有20条内链,其中12条指向仍在维护的支柱页,8条指向已合并的栏目。处理时只对8条做替换或移除,12条原样保留。这样做的结果是可以缩小改动面,下一步只需验证这8条的目标URL是否返回正常状态,而不必重审整页。
渲染前后不同,不等于一定出问题。要区分“可见差异”和“影响差异”:
核查动作:对同一条内链,分别在原始响应和渲染结果中记录目标URL,然后用抓取工具请求该目标URL,确认状态码与内容一致。若一致,说明差异停留在呈现层;若不一致,说明脚本改变了链接语义,需要回到第二步修正。
单页定位完成后,不要停在“这条修好了”。把结论转成规则,才能覆盖同类旧页面:
这样做的结果是:你不再逐页比对静态与渲染结果,而是用一组可复现的检查点定位差异。下一步只需在发布前对旧模板抽样跑一遍这套检查,确认内链来源一致,再决定哪些旧内容整体退出、哪些保留。