关键是把例外写成“条件—判定—动作—回退”四段式,而不是只写正常流程。你手上那页关于百度SEO方法的操作记录,如果只写“标题过长就截断”,脚本执行时遇到标题里带分隔符、空格或全角符号,就会给出和人工判断不同的结果。先做一件事:从记录里挑出一条你反复手动处理的规则,把它拆成可判定的条件,再补上例外分支。
人工经验里被省略的部分,通常集中在三类来源。第一类是数据本身不规整,例如同一页在两次抓取里标题不一致,或字段里混入换行。第二类是页面状态不确定,例如页面返回正常但正文区域是空的。第三类是判断依赖上下文,例如某条描述在栏目页合适、在详情页却重复。
你可以拿一个具体页面做对象:打开你保存的抓取结果,逐列检查哪些行是你手动改过的。手动改过的行就是例外候选。把每处改动记成一句话,例如“标题字段为空时,改用正文首段”。这句话已经包含条件和动作,可以直接进入下一步拆解。
动作与结果:如果你跳过这一步直接写脚本,脚本会按正常样本运行,异常样本被静默跳过;你下一步看到的统计就会偏乐观,误以为规则已经覆盖全部页面。
四段式的写法如下,用你自己的字段名替换:
title 为空,或 title 长度超过你设定的上限。例外要单独成行,不要塞进正常分支的注释里。注释不会被执行,也不会出现在日志中。假设你有一条规则是“标题超过30个字符就截断到第一个分隔符”,例外可能是“标题中没有分隔符”。这条例外应该写成独立条件,动作是“不截断,标记为待复核”。
这里要提醒一点:截断长度、分隔符集合这类阈值是你自己定的,不是百度公布的规则。写脚本时把它们放在配置区,方便后续调整,而不是散落在代码各处。
例外写没写全,不能只看脚本跑通。你可以构造一小批对照样本,让不同原因各自可区分:
跑完后检查日志,看每类样本是否落到预期分支。如果异常样本和正常样本落在同一分支,说明判定条件写得太宽。如果某类样本没有出现在日志里,说明它被前面的条件提前拦截了。
动作与结果:根据日志调整条件顺序,把更具体的例外放在前面。调整后重新跑同一批样本,观察分支归属是否变化;这一步决定你能否信任后续的全量处理结果。
你调整例外分支后,页面表现可能变化,也可能不变。比较时不要只看一次改动的前后差异。搜索需求本身会随时间和季节波动,抓取时间不同也会带来数据采集差异,这些都可能让同一份页面呈现不同结果。合理的做法是保留改动前的抓取快照和改动后的快照,在同一批页面上比较,并记录两次抓取的时间间隔。
如果改动后某些页面仍未被处理,先确认它们是否命中了某个例外分支,而不是直接归因于脚本无效。一次改动前后比较只能说明这一批样本的差异,不能单独证明处理方式正确。
最后一步是把四段式清单存成独立文件,和脚本代码分开。每次人工发现新的例外,先更新清单,再改脚本。这样你下次面对另一批页面时,可以直接复用清单,而不是重新回忆当时的判断。
假设你只有一页经验,也可以先按这个方法写成三到五条例外,跑一遍小样本,再决定是否扩展到其他页面。扩展前先确认这些例外在新页面上是否成立,条件不同就不要直接套用。