先给结论:把静态响应当作“服务器原始输出”,把脚本渲染结果当作“浏览器执行后的最终DOM”,两者不一致时,优先怀疑三类来源——原始响应本身已经错了、脚本在客户端改写了链接或内容、以及抓取环境没有执行脚本。定位顺序应是先固化同一URL的原始响应,再对比执行后的DOM,最后判断差异是否影响死链判定。
假设一个内容站有约两千个详情页,每页底部有“相关阅读”模块。用静态方式抓取时,所有相关阅读链接都返回200,站点地图里的URL也都能正常访问。但用执行脚本的方式抓取时,部分页面的相关阅读链接指向了不存在的路径,返回404。这个假设里,静态与渲染结果分叉,正是本篇要处理的场景。
注意边界:这个假设只适用于“页面依赖客户端脚本生成或改写链接”的站点。如果相关阅读是服务端直接输出的静态HTML,静态与渲染结果通常不会分叉,不能把本方法直接照搬。
差异可能出现在三个层次,需要分别取证:
可区分的证据:直接请求URL并保存原始响应,搜索目标链接的字面量;再在执行脚本的环境里读取最终DOM,对比同一位置的链接。如果原始响应里链接正确、最终DOM里链接错误,差异就落在脚本执行层;如果原始响应里链接已经错误,则与脚本无关。
实际操作:选一个静态正常、渲染异常的样本URL,先关闭脚本执行抓一次,再开启脚本执行抓一次,把两次结果里的目标链接逐一列出。这个动作的结果会直接决定下一步:
这里要说明一个适用条件:对照必须控制变量,同一URL、同一网络出口、同一抓取配置。否则差异可能来自环境而非页面本身。
静态与渲染结果不同,不等于一定产生了死链。需要继续确认两件事:
另外,请求量、抓取量或某项统计归零,不能单独证明处理正确。它也可能来自抓取频率调整、缓存变化或统计口径变更。要结合原始响应和最终DOM的对照结果一起判断。
个别样本成立、规模化后出现例外,通常是因为脚本行为依赖数据、用户状态或加载顺序。此时不要直接照搬单样本结论,而应:
如果某个组的差异无法稳定复现,先保留样本和抓取配置,不要急于修改模板。稳定复现是判断修复是否有效的前提。
假设某详情页原始HTML中相关阅读链接为 /article/1001,脚本执行后变为 /article/undefined。先确认原始响应里是 1001,再确认最终DOM里是 undefined,然后检查脚本中读取文章ID的字段名是否与接口返回一致。若字段名不一致,脚本取到空值,拼接出错误路径。修正字段名后,重新用同一URL对照,若最终DOM恢复为 /article/1001,则说明差异来源已定位;若仍为 undefined,则继续检查接口返回时序,而不是直接改链接文本。
整个定位过程的核心是:先分清差异属于原始响应、脚本执行还是抓取环境,再用同一URL、同一配置的对照结果决定下一步动作,而不是看到静态与渲染不同就立刻批量替换链接。