豆瓣自己报的数量,不能用来证明抓全了
同一次抓取里,电影的计数是准的,游戏的计数少了 5 个——而且缺口在列表中间。
原本的设计里有两道安全网:一道是对账——豆瓣说有 1157 个, 我抓到 1157 个,那就抓全了;另一道是连续性证明—— 从最新一条一路走到最旧一条,中间每一步都接得上。
拿一份 782 MB 的真实档案验证时,第一道网塌了。
数据
同一次抓取、同一个时刻:
| 列表 | 豆瓣声称 | 实际渲染出 | 差 |
|---|---|---|---|
| 电影 / 看过 | 1157 | 1157 | 0 |
| 游戏 / 玩过 | 293 | 288 | −5 |
更要命的是缺口的位置:不在末尾,在列表中间。 第 7、14、17 页各自只渲染出 14、14、13 个条目,而每页的槽位是 15 个。 换四次抓取重来,结果可复现,而且缺口数量随时间在增长。
为什么这直接毁掉了对账
最合理的解释是:豆瓣的计数有时候在审查层之前算,有时候在之后算。 于是同一份档案里,一个类别的计数可信,另一个类别的计数不可信—— 而你没有办法在不知道答案的前提下,判断哪个可信。
这就让「声称数 == 抓到数 ⇒ 抓全了」这条推理彻底不成立。它甚至比没有还糟: 对上了会给人一个虚假的安心,对不上又不能说明是自己漏抓了。
于是只剩一道网,而且要铺满
结论是:不做对账,只做连续性证明,并且每一条路线都要有。 连续性证明不依赖豆瓣说了什么,它只依赖抓取自己走过的路—— 从哪条开始、走到哪条为止、中间有没有断。这个性质是自足的。
声称数量还是照样记进档案,因为它事后不可重建,而且 「声称 > 抓到」本身就是豆瓣在藏东西的证据, 对档案的使用者是有价值的信息。但它只是记录,不参与任何结论。
所以档案格式 bundle/v1 里刻意没有
completeness 和 reconciled 这两个字段。
一个不存在的字段没法被误用——三年后某个下游工具不会读到
completeness: true 然后据此做决定,因为根本没有这个东西可读。
顺带一提
这也是为什么覆盖率页上写的是「从 X 回溯到 Y,无缺口」而不是「已完整备份」。 前者是我们真的知道的事,后者不是。