豆备 DOUBAK
← 开发日志

抓完之后,先让你看见自己的东西

扩展 1.2.0:档案页多了「查看内容」,把存下来的页面就地解析成条目。抽取器是从解析器仓库整份抄过来的——那 220 行适配代码买的是「只有一份实现」。

在这之前,抓完一趟你手上是一堆 WARC。要看清里面到底是什么,得装 Node、 clone 两个仓库、跑两条命令——对多数人来说,那就是这条链路的终点。

面板里本来有「翻看捕获」,但它看的是生的那一面:网址、判定、 字节数、原始 HTML。它能证明字节在,证明不了那些字节是你的东西。 1.2.0 在旁边加了熟的那一面——广播、标记、日记影评、豆列, 解析成条目显示出来,你写的那几句话单独一块。

刻意不做成第二个站点。 站点生成器已经是那个东西——有封面、 有固定链接、有搜索。这里是抽查,回答一个问题: 抓到的确实是我的东西吗。

抄一份抽取器,而不是另写一份

把 HTML 变成条目这件事,解析器已经做过一遍,而且是对着真实字节一处处量出来的。 在扩展里另写一份浅的,结果是能力更弱、而且会漂—— 两份实现对同一段 HTML 得出不同结论,只是早晚的事。

这不是假想。" 曾经明晃晃地印在样张站上:当时有四份 各自演化的 HTML 实体解码表,其中一份干脆没有。合成一份之后, 未解码的实体从 196 个降到 1 个,而那 1 个是对的。

所以走的是既定那条路:解析器的五个纯函数文件逐字节抄进扩展仓库, 一个脚本负责同步,--check 由测试和 CI 调用,漂了就红。 CI 会把解析器仓库一起检出——本地缺仓库时那条检查是「带原因跳过」, 而跳过在 CI 里等于没测。

为此写了多少新代码?数了一下(去掉注释和空行):

抄过来的抽取器      401 行
适配到界面上        221 行  ← 55%
同步脚本             63 行
测试                377 行

那 221 行里,真正在做「把解析结果变成界面要的形状」的只有 68 行: 四类各一小段,intent 怎么匹配、调哪个抽取器、标题和正文各取哪个字段。 用 220 行接线,换掉 401 行会漂的重复实现。

然后发现同一条规则本来就有两份

写适配层的时候撞上了豆列:一份豆列每页 25 条,实测有 4 页的, 所以「一份豆列」跨着好几次捕获。谁来拼、按什么次序拼,是一条规则。

而我在面板里又写了一遍——解析器里已经有一份。两份实现对同一份豆列 可以给出不同的条目次序,而次序错了看起来完全正常: 还是那些作品,还是那些评语。用户排过的清单,把第 2 页排到第 1 页前面就是改了内容。

改法是把那条规则提成 mergeDoulistPages,放在产生这些页面的 抽取器旁边,扩展那边原样拿过去。分组不进去: 两个调用方的分组键不一样(解析器按「哪份档案里的哪份豆列」,面板按豆列), 而会悄悄出错的是次序,不是分组。

三处「看起来是空的」,其实是我在过滤

这一页做出来之后,最先冒出来的都不是崩溃,是看起来正常的空白

没写评语的豆列,整份显示成两个数字。 我当初只列了带评语的条目,因为「评语才是用户写的」。 但一份 59 条、一条评语都没有的收藏夹,在页面上就只剩标题和「59 个条目 · 0 条评语」—— 看着像没解析出来,可样张站那边明明把条目都渲染了。 实测 6 份豆列里有 3 份没有任何评语。 前提本来就错了:选了哪些,本身就是你编的。

广播那一列全是「想看 / 想看 / 想看」。 作品名一直都抽出来了,只是没被用上——于是那一列除了顺序之外什么都没说, 而人要认的恰恰是想看的是哪一部。标题换成作品名,动作退到第二行。

「豆列(18 页)」被读成 18 条豆列。 那个数是页数——真实档案里 173 页广播装着好几千条。 页数是索引里现成有的,条数非解析不可知,所以两个数各归各位、各带各的说法: 按钮上是「173 页」,清单顶上是「解析了前 30 页(共 173 页),列出 812 条」。

另外几处界面上的账

35 张消息卡一点颜色都没有。 面板里并存着两套语气词 (card errcard tone-error),而样式表里只有后一套有规则。 于是「有 8 条在豆瓣上已经没有了」——正是靠颜色区分轻重的那一句—— 跟一句普通说明长得一模一样。 两套词并存时这件事看不出来:每一处单独看都像写对了, 只有把类名和样式表放在一起数才数得出来。

档案清单不再钉在视口上自己滚。 它原来是 sticky 加 70vh 内滚,最坏的一处是:70vh 之外的行看不见,而它们没有任何迹象说自己存在。 「正在抓的那一份沉到十七行底下」那次,用户看到的是「清单没刷新」—— 清单其实是新的,只是顺序把它藏了。

抓不下来的那几十条折起来了,条数留在折叠标题上。 但「豆瓣上已经没有了」的那几条分成单独一块—— 它们少、且真的没有别处可查,与「判不出来」不是一回事: 后者的数量由出错的程度决定,一条路线的规则对不上,几十条一起进来。

装的时候记得

Releases 上那份 zip 是应用商店的提交格式, Chrome 不能直接装 zip——要先解压,再「加载已解压的扩展程序」。 从商店装的话不用管这些,但商店里的版本要等审核。

← 更新:走的时候不用求谁 更早:验一验,能不能读将来的档案 →