先给结论:当你用“查看源代码”看到的内容和浏览器里最终显示的内容不一致时,差异通常来自脚本渲染。定位方法不是反复刷新页面,而是把同一批二级域名拆成“静态层”和“渲染层”两组证据,分别采集,再比对哪一层缺失。下面用一个假设情境说明决策过程。
假设你运营一个站群,主域是 example.com,下面有 shop.example.com、docs.example.com、help.example.com 等二级域名。你抽查了 docs.example.com,发现直接请求得到的 HTML 里只有骨架,标题、正文、链接都要等脚本执行后才出现。于是你判断“所有二级域名都需要渲染才能拿到内容”。
这个判断在单个样本上成立,但不一定适用于全部。二级域名是独立的子域,每个子域可以部署不同的技术栈:有的用服务端模板输出完整 HTML,有的用前端框架在客户端拼装,有的两者混合(首屏静态、后续内容异步加载)。因此,定位差异的第一步是把每个二级域名按“首次响应是否已含正文”分类,而不是按主域的整体印象推断。
具体动作可以这样设计:对每个二级域名,分别保存两份材料——一份是关闭脚本执行后的原始响应,一份是脚本执行完成后的最终 DOM。然后逐项比对以下位置:
<a href>,还是靠脚本点击事件生成。比对结果会指向不同的下一步。如果原始响应已含正文,只是渲染后多出推荐模块,那差异属于增强内容,重点检查这些模块是否影响了主要内容的判断。如果原始响应几乎为空,正文完全依赖脚本,那差异属于内容交付方式问题,需要评估渲染环节是否稳定、是否会出现超时或失败。
继续上面的假设。你对三个二级域名做了同样的采集,得到三种情况:
shop.example.com:原始响应已含商品名和价格,渲染后只多了评论组件。差异小,静态层可信。docs.example.com:原始响应只有 <div id="app"></div>,正文全部由脚本生成。差异大,静态层不可信。help.example.com:原始响应含标题和部分段落,渲染后补齐剩余段落。差异中等,两层都需要检查。此时不能把 docs.example.com 的处理方式直接套到另外两个上。对第一种,继续依赖静态层即可;对第二种,需要确认渲染是否在合理时间内完成、失败时是否有回退内容;对第三种,要判断缺失的段落是否属于核心内容,还是可接受的次要部分。
单个样本成立、批量后出现例外,常见原因是变量没有固定。二级域名之间的差异可能来自:模板版本不同、缓存策略不同、脚本加载顺序不同、某个子域用了旧版构建产物。定位时先固定一个变量,例如只比较同一模板版本下的二级域名,看差异是否仍然存在。如果差异消失,说明问题出在版本不一致;如果差异仍在,再换下一个变量。
这个动作的结果会直接影响下一步:差异随版本收敛,就优先统一构建和发布流程;差异与版本无关,就要检查渲染环境本身,比如脚本依赖的外部资源是否在部分子域上不可达。注意,抓取限制文件只能约束抓取行为,不能替代对渲染结果的判断;站点地图提交也不保证内容被采用。把这两件事和渲染差异混在一起,会让定位方向跑偏。
最后,把每个二级域名的结论写成带条件的记录,例如“当原始响应已含正文时,以静态层为准;当原始响应正文为空且渲染成功时,以渲染层为准;当渲染失败时,回退到静态层并标记该子域”。这样下次出现例外时,你可以直接对照条件,而不是重新猜测。差异定位的价值不在于得出一个统一答案,而在于知道每个二级域名分别适用哪一层证据。