把人工经验写成脚本需求,例外情况不能写成“遇到异常就跳过”,而要先区分两类例外:一类是规则本身允许的合理偏差,另一类是数据或环境不满足执行前提。前者应写成带条件的放行逻辑,后者应写成停止并输出待核清单。判断依据不是感觉,而是这条例外是否能在不改变判断标准的前提下被复现。
人工操作时,很多例外靠经验顺手处理了,写进脚本需求时却容易被压成一句“特殊情况特殊处理”。更可用的做法是追问:这个例外改变的是判断结果,还是只改变执行路径?
如果判断结果不变,只是路径不同,就属于规则内偏差。例如人工判断某个页面是否值得继续分析时,遇到页面主体内容为空但导航完整,仍然会判定为“低价值页”,只是不再提取正文。脚本需求里应写成:满足低价值判定条件时输出标记,跳过正文提取,继续记录导航链接数量。
如果判断前提本身不成立,就属于前提失效。例如页面返回内容与预期结构完全不符,人工会先停下来核对,而不是硬套规则。脚本需求里应写成:检测到结构不匹配时停止该条处理,输出原始响应摘要和待核原因,不进入后续判定。
这两种写法带来的结果不同:前者让脚本继续跑完并保留可比较的标记,后者让脚本在证据不足时留下可复查的断点。下一步动作也随之不同——前者可以进入汇总比较,后者必须先补样本或修前提。
出现与直觉相反的结果时,最常见的误判是把“数据没采到”当成“问题不存在”。假设一次人工抽查发现某类页面标题重复率很高,但脚本跑出来的重复率很低。此时至少有两种合理解释:一是脚本把动态插入的标题也算作不同值,二是抽取范围只覆盖了部分模板。
区分方法不是看总数,而是看可核对证据:
如果差异集中在少数模板,说明是范围问题;如果差异分散且原文不同,说明是取值时机或取值对象问题。两种解释对应两种脚本需求改法:前者补模板清单,后者补等待条件或取值节点。请求量、抓取量或某项统计归零,不能单独证明处理正确,它也可能是采集范围缩小、去重规则变化或环境差异造成的。
脚本需求里只写“如果异常则记录日志”几乎无法验收,因为不同人对异常的定义不同。更可执行的做法是每个例外都写清三件事:
假设一个需求是“批量检查页面是否包含目标词”。例外可以写成:当页面正文提取结果为空且响应状态正常时,不判定为不包含,而是输出“正文为空”标记,并保留页面地址与响应长度。这个动作的结果是:汇总时能把“确实不包含”和“没能判断”分开,下一步可以只针对“正文为空”的样本补抽取规则,而不是重新跑全量。
这里的关键取舍是:例外越多,脚本分支越多,维护成本越高。因此只把会影响判断结论的例外写成独立分支,其余合并为统一待核输出。若某类例外反复出现,再考虑提升为正式规则。
条件一:人工经验已经稳定,且例外有明确可观察特征。此时应把例外写成放行或标记逻辑,让脚本继续执行,保证样本量不被例外打断。实施动作是给每个例外分配固定输出字段,跑完后先看字段分布,再决定是否调整规则。
条件二:人工经验本身还在摸索,例外边界说不清。此时应把例外写成停止并收集证据,而不是急着自动处理。实施动作是让脚本在触发例外时保留原始输入和中间结果,先人工核对一批,再回到需求里补条件。两种条件的选择依据是:例外是否已经能被稳定描述。不能稳定描述时,自动化只会把错误藏得更深。
无论选哪种,比较改动前后都要考虑季节、搜索需求变化和数据采集差异,不能把一次前后对比直接当成改动效果。例外描述写得越具体,后续越容易判断是规则问题、采集问题,还是需求本身还没想清楚。