核心做法是:在脚本需求里把例外写成“可判定的条件 + 触发后的动作 + 记录什么”,而不是写成“遇到特殊情况再处理”。缺少完整数据或权限时,先保留人工兜底,只把可稳定判定的例外交给脚本;判定证据不足的例外应改写为待确认清单,退出自动流程。这样做的结果是,脚本不会把不确定情况误判成正常或异常,后续才能根据记录决定是否扩大自动化范围。
人工操作时,经验往往表现为“看情况”。写成脚本需求前,必须把“看情况”拆成三类。可判定例外有明确字段或状态,例如页面返回状态码、canonical 指向、robots 规则命中、链接目标是否存在。可观察例外只能看到现象,不能直接得出原因,例如某批页面抓取量下降、索引量波动、日志中某类请求减少。只能人工判断的例外包括内容是否满足搜索意图、页面是否与其他页面高度重复、某次改版是否属于业务上的合理调整。
三类例外的处理方式不同。可判定例外适合写入脚本分支;可观察例外适合先记录并触发人工复核;只能人工判断的例外不应硬编码成自动结论。一个实际动作是:在需求文档中为每条例外标注类型,并写明判定所需字段。若某条例外既没有字段也没有权限获取证据,就把它从自动处理范围移出,改为输出待确认项。这个动作会直接影响下一步:脚本只对可判定例外自动执行,其余情况进入人工队列,避免自动改动误伤正常页面。
面对例外,需求里通常有三种取舍。
三种取舍不必同时使用。缺少完整数据或权限时,优先退出不可判定项,再保留可判定项,最后才考虑改写规则。
一条例外描述至少包含四部分:触发条件、执行动作、记录字段、复核方式。触发条件要写成脚本能判断的表达式,而不是自然语言概括。例如不要写“如果页面不重要就跳过”,而要写“如果 URL 命中参数 ?sort= 且 canonical 指向自身,则跳过索引检查”。执行动作要明确是跳过、告警、写入清单还是继续处理。记录字段要能回答“为什么触发”,例如 URL、命中规则、证据来源、时间。复核方式要说明由谁、在什么条件下重新判断。
假设一个场景:你需要检查一批商品页的内链是否指向有效页面,但只有页面 HTML,没有日志和权限。可判定的例外是链接目标返回 404 或 410;可观察的例外是链接目标返回 301 但无法确认最终目标是否相关;只能人工判断的例外是链接锚文本是否自然。此时需求可以写成:404/410 进入待修复清单;301 只记录目标地址,不自动替换;锚文本问题不进入脚本判断。这个假设说明,缺少数据时仍可执行最小动作——收集 404/410 和 301 目标,但不能据此推出“所有 301 都应替换”或“锚文本不影响效果”。
脚本上线后,例外记录本身就是验证材料。你可以比较处理前后同一类例外的数量、人工复核结果和误判比例。但要注意,请求量、抓取量或某项统计归零,不能单独证明处理正确;它还可能来自采集周期变化、权限调整、页面模板改版、搜索需求季节性波动,或统计口径变化。一次改动前后比较要考虑季节、搜索需求变化和数据采集差异,不能把相关当成因果。
一个可执行动作是:为每条例外规则设置复核条件,例如“连续两个采集周期都出现同一类未判定项”或“人工复核中同一原因出现多次”。当条件满足时,再决定是否把该例外从退出改为保留,或从保留改为改写。结果是规则逐步收敛,而不是一次性把所有人判断都塞进脚本。
如果当前只能写一版需求,可以按下面顺序组织:
这样写出的需求,不会把“例外”当成一句模糊备注,而是让每条例外都有可执行的去向。缺少数据或权限时,先退出的部分不会拖累可判定部分;后续拿到新证据,再按复核条件逐条改写,而不是重新拍脑袋。