结论是:只有当例外情况能被写成“可判定的条件 + 明确动作 + 不满足时的默认行为”时,才适合交给脚本执行;如果例外依赖人的临场判断,例如“看起来像旧内容就跳过”,那就不该硬写成脚本需求,而应先保留人工复核。一个会让上述结论失效的反例是:前提变化只发生在极少数页面,且每次变化都不同,此时把例外穷举进脚本,维护成本会高于人工处理。
人工经验里常见的说法是“这页不用动”“这种情况要跳过”。写脚本需求时,需要把“这种情况”翻译成脚本能读取的信号。可用的信号包括:页面返回的访问状态、页面标题是否为空、正文是否包含某个固定标记、链接是否指向站内、URL 是否带特定参数。假设一个场景:运营人员说“旧活动页不要继续优化”,脚本需求应写成“当 URL 参数包含 status=closed 时,跳过该页并记录原因”,而不是“旧活动页跳过”。前者的判定结果稳定,后者的“旧”没有边界。
动作也要写清。例外命中后是跳过、降级处理还是转人工,会直接影响下一步。如果写成“命中例外就跳过”,脚本会直接不再处理该页;如果写成“命中例外就转人工队列”,后续仍有人复核。两种写法对应的验收方式不同,不能混用。
写例外时容易只列“什么情况下不处理”,却漏掉“其余情况怎么处理”。脚本需要一个默认行为,否则遇到未列出的情况时,执行结果不可预期。假设需求只写了“标题为空时跳过”,但没写“标题不为空时做什么”,脚本可能既不处理也不报错,最后表现为整批页面没有变化。
更稳妥的写法是同时给出三层:命中例外时执行什么、未命中例外时执行什么、无法判定时执行什么。第三层尤其容易被忽略。无法判定包括读取失败、字段缺失、编码异常等。把无法判定单独归为一类,可以避免它被误当成“未命中例外”而继续处理。
假设某站点有一批页面,原先由人工逐页判断“是否需要更新摘要”。变化前,页面数量少,人工判断可行;变化后,页面数量增加,且判断依据集中在少数几个字段上。此时,把“字段为空则跳过、字段有值则更新”写成脚本是合理的。相反,如果变化后每页的判断仍需要看具体内容语义,脚本只能做粗筛,不能替代人工决定。
这里的取舍条件是:例外是否能用现有字段稳定判定。能稳定判定,就写成脚本;不能稳定判定,就把脚本限定在“筛出候选、交给人决定”这一步。这样脚本的作用从“替人决定”变成“减少人工翻页量”,风险更低。
脚本上线后,如果只比较改动前后的抓取量或请求量,容易把季节、搜索需求变化和采集差异误当成脚本效果。更稳妥的做法是:保留同一批未命中例外的页面作为对照,观察它们与命中例外页面在相同时间段内的差异。如果两类页面都出现相同方向的变化,就不能把变化单独归因于例外处理。
需要说明的是,请求量或抓取量归零,不能单独证明例外处理正确。它也可能是采集延迟、访问限制或页面本身不再被需要造成的。判断时要回到具体页面的访问状态和内容变化,而不是只看一个汇总数字。
实际动作是:在写脚本前,先做一张判定表,列出每个例外对应的条件字段、取值、命中后的动作、无法判定时的动作。做完这张表后,检查两件事:一是每个条件是否都能从页面或现有数据中直接读取;二是每个动作是否都有对应的记录方式。如果某个条件读不到,就先补数据采集,而不是先写脚本。这样,脚本需求里的例外描述就从“人的感觉”变成了可执行、可验收的规则,后续调整也有据可查。