爬虫最难受的失败是“没报错,但数据坏了”:页面改版之后提取器照常返回,只是价格全空了,或者变成了分。这篇模拟一个逐步改版的站点,看哪些检查能发现哪些改版。
版本 异常 每页商品数 名称空 价格空 评分空 价格中位数 结构相似度 v0 基线 0 30.0 0% 0% 0% 1558 1.00 v1 良性变化 0 25.8 0% 0% 0% 1582 0.88 v2 价格类名改了 0 30.0 0% 100% 0% — 0.87 v3 外层容器和类名变了 0 0.0 100% 100% 100% — 0.81 v4 价格格式变了 0 30.0 0% 0% 0% 1558 1.00 v5 价格单位变成分 0 30.0 0% 0% 0% 155772 1.00 v6 灰度 0 30.0 0% 25% 0% 1547 0.97 v7 名称移进了链接 0 30.0 100% 0% 0% 1558 1.00
XPath 取不到元素时返回空列表而不是报错,所以改版之后爬虫照常运行、照常写库。8 个版本里没有一个抛异常,只看异常等于没有监控。
版本 只看有没有抛异常 商品数是否骤降 字段空值率是否超过 价格中位数是否偏离 页面结构相似度是否 实际是否真的坏了 v0 基线 · · · · · 好 v1 良性变化 · · · · 报警 好 v2 价格类名改了 · · 报警 报警 报警 坏 v3 外层容器和类名变了 · 报警 报警 报警 报警 坏 v4 价格格式变了 · · · · · 好(宽松解析照样取对) v5 价格单位变成分 · · · 报警 · 坏(价格 ×100) v6 灰度 · · 报警 · · 部分页面坏 v7 名称移进了链接 · · 报警 · · 坏 检查项依次为:只看有没有抛异常;商品数是否骤降;字段空值率是否超过 10%;价格中位数是否偏离基线 3 倍;页面结构相似度是否低于 0.9
字段空值率发现类名改了、容器变了、名称位置变了、灰度;价格中位数发现价格单位变成了分(这种“有值但错了”空值率发现不了);商品数骤降只发现整个容器变了的情形;页面结构相似度能提前发现结构变化,但会把加广告这种良性变化也当成改版(1 个误报)。
只看有没有抛异常:命中 0 / 5,误报 0,漏报 5 商品数是否骤降:命中 1 / 5,误报 0,漏报 4 字段空值率是否超过 10%:命中 4 / 5,误报 0,漏报 1 价格中位数是否偏离基线 3 倍:命中 3 / 5,误报 0,漏报 2 页面结构相似度是否低于 0.9:命中 2 / 5,误报 1,漏报 3 组合(后四项任一报警):命中 5 / 5,误报 1,漏报 0
5 个有问题的版本被后四项检查的组合全部发现,代价是 1 个误报(良性变化 v1)。阈值是我手工定的(50%、10%、3 倍、0.9),没有调优。
40 个页面里,价格提取失败比例的分布:最小 0%、中位 0%、最大 100%;整体平均 22%;超过 10% 的页面有 9 个
新版页面成片地出现在部分页面上,整体平均失败率 22% 看起来不高,但个别页面是 100%。监控要同时看分布(最大值、超过阈值的页面数),不要只看均值。