能区分两种解释的证据是“开关状态与页面版本在时间轴上的一一对应关系”,而不是某次抓取结果本身。功能开关改变的是页面输出,抓取规则判断的是“是否允许取、取到什么”。如果只记录开关名称,不记录开关生效时的页面版本,事后就无法判断变化来自开关、来自缓存,还是来自抓取限制。可执行的做法是:每次开关变更时,同时保存开关状态、页面原始响应、渲染后内容和抓取规则文件,并给它们打上同一个版本标识。
假设一个页面把推荐模块放在功能开关后面。开关关闭时,服务端不再输出该模块;开关打开时,模块由客户端脚本注入。直觉上,关闭开关应该让页面更“旧”、更简单,抓取结果却可能显示模块仍然存在,甚至内容比关闭前更完整。这与直觉相反,但未必是抓取规则失效。
一个合理的解释是缓存与版本错位:抓取方拿到的响应来自开关切换前的缓存副本,或者中间层仍保留旧版本。另一个合理解释是渲染时序:抓取方执行了脚本,而脚本读取的开关配置来自另一个来源,导致渲染后内容与预期不一致。两种解释都会表现为“关闭后仍有模块”,但成因不同,处理动作也完全不同。
要支持这个解释,需要能证明响应内容与当前开关状态不一致,且这种不一致在绕过缓存后消失。可核对的证据包括:同一时间点分别请求带缓存与不带缓存的地址,比较响应正文;检查响应头中的缓存相关字段;确认开关配置的读取路径是否经过缓存。如果绕过缓存后模块消失,缓存解释就更成立。
要支持这个解释,需要证明服务端输出与渲染后输出不同,且差异与开关配置来源有关。可核对的证据包括:保存未执行脚本的原始响应,再保存执行脚本后的渲染结果;比对两者中模块是否存在;确认脚本请求的配置接口返回了什么。如果原始响应中模块已消失,而渲染后模块重新出现,渲染解释就更成立。
记录的目标不是“证明谁对”,而是让下一次变更时能快速排除错误解释。每次开关变更,至少保存以下字段,并让它们共享同一个版本标识:
switch_name 与 switch_state:开关名称和变更后的状态。raw_response:未执行脚本时的页面原始响应。rendered_content:执行脚本后的可见内容或关键节点快照。robots_snapshot:当时的抓取规则文件内容。timestamp 与 version_id:变更时间和统一版本标识。实际动作可以这样执行:在开关变更前先保存一份基线,变更后立即保存第二份,并记录两次之间的时间差。如果第二份中模块状态与开关状态不符,先按上面的证据区分缓存与渲染,再决定是清理缓存、调整配置读取路径,还是修改抓取规则。这个动作的结果会直接影响下一步:若证据指向缓存,下一步是核对缓存层级;若指向渲染,下一步是核对脚本读取的配置来源。
假设某页面用开关控制一段说明文字,开关状态为关闭。变更后保存的原始响应中说明文字不存在,渲染后内容中却出现了说明文字。仅凭“渲染后出现”不能断定开关失效,因为脚本可能读取了另一份配置。此时再保存脚本请求的配置接口响应,若该响应仍返回开启状态,就能把问题定位到配置来源,而不是抓取规则。若配置接口返回关闭,而渲染后仍出现,则需要检查脚本缓存或执行顺序。这个例子的数字和状态都是假设,只用于说明比较方法。
记录版本状态时,容易把抓取限制当成版本控制手段。robots.txt 的抓取限制不等于可靠的索引移除:它可能阻止抓取,但已收录的地址未必因此消失。站点地图也不保证收录,它只是提供发现线索。HTTPS 不保证安全无漏洞或排名。不同搜索引擎对同一规则的支持情况须分别核查。因此,版本记录应聚焦“开关状态与页面输出是否一致”,而不是用抓取规则文件替代版本标识。只有把开关状态、原始响应、渲染结果和抓取规则快照放在同一版本标识下,才能在出现反常结果时,用可核对的证据区分缓存、渲染和抓取限制三种解释,并据此决定下一步动作。