豆备 DOUBAK

怎么用

四步流程:安装扩展 → 本地抓取 → 解析数据 → 静态建站或格式导出。 全流程均在本地设备运行,不经由任何远程服务器;在离线状态下亦可顺畅执行后三步。 后三个步骤在扩展界面中点击即可完成,命令行方式则专为需要自定义参数的高阶用户保留。

本页面为快速导览,而非详细技术文档: 各章节末尾均附有对应仓库 README.md 的链接, 文档内容以仓库 README 为准——包括最新参数说明、具体命令及实测数据。 本导览内容可能存在滞后,代码变更与技术细节均同步更新于各仓库文档中。

如果仅需一份基础归档,只需完成第 1 步即可:安装扩展并执行一次抓取,再导出至本地硬盘。 该档案本身完整独立,后续三个步骤无论何时处理、甚至不做,都不影响底层备份的有效性。

后三个步骤现已内置于扩展中,无需配置 Node.js 环境: 在扩展的「导出」面板中,可直接将归档转换为结构化数据、 NeoDB 导入包或完整的 Markdown 静态站点(包含离线图片), 并保存至指定的本地目录。其底层与下述三个独立仓库使用完全相同的核心逻辑——代码逐字节同步至扩展, 并通过 CI 自动化流程严格校验以确保逻辑一致——因此两种方式生成的产物完全相同。

下文主要介绍命令行工作流,适合需要自定义处理参数、集成自动化脚本或筛选部分数据的高阶用户; 若只需常规导出,了解第 1 步的操作即可满足需求。

  1. 浏览器扩展:在本地浏览器中采集豆瓣页面,将原始内容完整留存为原始档案(bundle)
  2. 数据解析器:原始档案 → 结构化数据(canonical)
  3. 静态站点生成器:结构化数据 → 可独立浏览的本地静态网站
  4. 格式导出适配器:结构化数据 → 适用于 NeoDB / Letterboxd / Goodreads 的导入数据包

第 1 步 · 抓下来

安装浏览器扩展后,使用你的个人账号与本地网络环境按需抓取。 登录凭据与会话 Cookie 全程保留在本地设备中——项目完全无服务端架构,彻底杜绝数据泄露隐患。

安装扩展可通过以下三种途径进行,建议优先选择应用商店:

  1. 浏览器商店 —— 推荐多数用户使用,一键安装且支持自动更新: Chrome 应用商店、 Microsoft Edge 加载项、 Firefox 附加组件。 两个 Chromium 商店提交的是同一份包,装哪边都一样;Edge 也仍然能从 Chrome 应用商店装。 Firefox 分发版本则是独立的安装包(两端的 manifest 规范不同),均由同一条 CI 流水线编译产出。
  2. Releases —— 若无法访问商店,可下载离线包 doubak-<版本>.zip。它跟商店发布版本由同一 CI 流水线编译产出, 二进制内容逐字节完全一致。需要注意的是,该离线包专为商店提交格式设计,无法在浏览器中直接双击安装: 需先解压,然后在 chrome://extensions(Edge 为 edge://extensions) 中开启「开发者模式」→ 点击「加载已解压的扩展程序」→ 选择解压后的目录。
  3. Actions 里的构建产物 —— 仅用于测试 main 分支上尚未正式发布的最新代码。 下载 Actions 产物需预先登录 GitHub 账号(匿名请求会返回 401 鉴权失败),因此不作为常规推荐方式。

Firefox 怎么装

常规安装直接访问 Firefox 附加组件, 与 Chromium 浏览器一样支持一键添加,要求 Firefox 140 或更高版本。

如需测试 main 分支尚未发布的改动,可手动载入开发版构建 ——流程与 Chromium 手动加载 ZIP 类似:

  1. 前往 Releases 页面下载 doubak-<版本>-firefox.zip。 请务必确认文件名带 firefox 后缀——两者的 manifest 配置存在差异,误用会导致加载直接失败, 且浏览器不会明确提示包类型不匹配。
  2. 解压下载的压缩包。
  3. 在地址栏打开 about:debugging#/runtime/this-firefox → 点击「临时载入附加组件…」→ 选择解压目录中的 manifest.json。

提示:「临时载入」仅在当前浏览器会话生效,重启 Firefox 后需重新载入。 但已下载归档数据不受影响——数据安全存放在浏览器的本地存储空间内,不受扩展卸载或重启影响, 下次载入后仍可无缝继续增量抓取。

需要说明的是,Firefox 目前尚未开放网页端直接写入本地文件夹的文件系统接口(File System Access API), 因此在 Firefox 中导出得到的是一个 ZIP 压缩包,而非直接生成的文件夹。 解压后的文件内容与 Chrome 导出结果逐字节完全相同——ZIP 仅为传输封装,不影响数据格式规范; 后续重新导入豆备或交给解析器处理时,直接使用解压出的目录即可。 其局限在于该流程无法实时回读校验写入状态,且不支持断点续传:若导出途中意外中断需重新执行。

首次运行建议执行全量抓取:遍历采集所有支持的数据类型。 所需时间取决于账号数据规模,过程支持随时中断,后续可继续增量采集。 如果希望快速试运行,建议优先单独抓取广播数据——广播属于时效性最高且不可逆的内容: 发布后即定型且无法二次编辑,一旦线上被删除便无迹可寻, 无法再从其他关联页面找回原始记录。

抓取完成后在扩展面板中执行导出,生成的文件夹即为你的原始档案(bundle)。

即便抓取中途暂停,也可以安全导出:中途停止生成的档案虽然缺少最终收尾阶段生成的 manifest.json, 但已抓取的索引与页面数据均完好保留,解析器依然能够正常解析; 导出的目录后续也可按照下文「备份与恢复」指引重新导入扩展继续采集。 因此中途停止的备份档案切勿轻易删除,详细说明请参阅首页的「为何中途暂停不等于失败」。

后续维护建议使用增量抓取:扩展采集至上次同步的位置即会自动停止, 已固化的广播、作品详情页及静态图片均会自动跳过——其判断核心是 「上游数据是否具备可变性」,而非单纯记录是否曾被下载。 因此增量采集耗时极短,适合高频定期运行。鉴于日记与长评在线上允许再次编辑, 若需要同步最新修改,可勾选「增量抓取,并重新抓取可以编辑的内容」选项。

每次导出都会生成独立的时间截面档案,请注意不要覆盖历史备份目录—— 解析器支持输入包含历次档案的完整总目录,保留各时期的多份档案更有助于还原数据的完整演变轨迹。

备份与恢复

导出至本地硬盘后,扩展内部存储的临时副本即可按需清理。 为了确保备份的可逆性与可维护性,扩展档案页面提供了「导入档案…」功能: 直接选择 doubak-bundle-… 目录或其上层父目录即可 (系统会自动向下检索三层目录,即便包含按月归档或多层嵌套解压路径均能准确识别)。

重新导入的核心价值在于维持增量采集的连续性:若缺少历史档案作为增量比对基准, 下次采集将被迫重新执行耗时漫长的全量抓取,重复请求数千个作品详情页面。

生成的档案本质上是标准的文件目录,里面是 WARC 分段文件、索引清单及 manifest.json。因此备份方式非常自由且通用—— 无论是存入移动硬盘、个人网盘、同步至 NAS,还是纳入常规文件备份工具, 操作方式与普通文件夹无异。换台设备想继续增量采集, 把文件夹复制到新设备并在扩展中点击「导入档案…」即可。

云盘同步若更改了文件夹名称,不会影响识别: 档案的元数据记录在 manifest.json 与索引文件内部, 并不依赖外层文件夹名称——诸如 xxx (1) 或 备份/2026-08/ 等目录名均能被正常识别。 唯一的要求是保持文件夹内部文件的完整性:WARC 分段文件、索引清单与 manifest.json 之间存在严格的校验关联, 若缺少文件或混入其他档案的文件,导入程序将拒绝执行并明确提示存在异常的具体文件路径。

归档数据完整包含了你的豆瓣个人资产——短评、日记正文、私密豆列及本人上传的图片均原样留存。 在上传至第三方公有云盘前,请务必审慎评估云端存储服务的隐私安全性。 这也是豆备坚持不设远程服务器的核心初衷:数据始终属于用户, 存储位置与访问控制亦完全由个人自主决定。

导出若意外中断,只需重新执行并选择同一目标文件夹,程序会自动比对并仅补充缺失的部分。 此处无需额外的进度记录文件——目标目录中的现有文件本身即充当断点状态,每个文件的写入均具备原子性保证 (不会残留损坏的不完整文件,因此通过文件存在性校验即可准确判断恢复点)。

导入过程绝不覆盖本地已存在的任何有效数据,并严格遵循「预先全量扫描、列举变更明细、用户确认后写入」的机制。 针对无需导入的数据,界面会明确展示具体原因(已存在、数据补齐、重复记录、ID冲突、属于其他账号或格式不可用), 而非以笼统的「跳过」一笔带过。

权威文档请参考: doubak-extension / README.md —— 涵盖详细安装指引、数据采集范围、增量抓取跳过规则及中断恢复机制。

扩展里的「导出」页:第 2–4 步一次做完

抓取完成后进入扩展的「导出」面板,三个独立入口对应不同的导出目标。 无需提前创建文件夹——点击「导出…」时只需指定任意目标目录(例如系统的「下载」文件夹), 三种导出格式会自动在其中创建对应的独立子目录,彼此互不冲突:

doubak-neodb/       neodb-ndjson-import.zip ← 用于上传导入,附带说明文档
doubak-canonical/   五个 .ndjson 结构化数据文件 + README.txt
doubak-markdown/    content/(每个页面独立 .md)与 static/(静态图片及搜索索引)

三种格式均源自相同的底层解析流程,单次专注于一种输出。解析得到的中间数据均在内存中处理而不产生临时冗余落盘—— 作为可随时重新计算的派生数据,避免产生多个可能不一致的状态副本。 全流程在本地内存完成,完全不产生外部网络请求。

扩展导出功能与下文介绍的命令行工具完全基于同一套核心代码实现: 解析引擎、导出适配器与站点生成器中的纯函数逻辑逐字节同步至扩展工程中, 两端仓库通过自动化 CI 机制严格防范逻辑漂移。在对同一账号档案的实测验证中: 标记、条目、广播、日记与豆列等共计 9,322 条记录两端产出完全一致、各字段值精确匹配, 生成的 3,131 个 Markdown 页面文件名与内容亦分毫不差。

后续章节将展开介绍命令行方案。若只需界面操作,阅读至此即可正常使用—— 后续内容适合需要定制参数、集成脚本流水线或筛选部分数据的开发者参阅。

第 2 步 · 解析

将包含多份原始档案(bundle)的根目录作为输入传递给解析器,它将生成标准的 结构化数据(canonical)——即明文可读、易于使用 grep 等工具检索的 NDJSON 格式。 该解析步骤为无副作用的纯函数计算,全程离线:同样的原始输入必然产出确定性的输出, 随时可以清空并重新生成。

node bin/parse.js <装着一堆原始档案的目录> [输出目录] [--ignore-warnings] [--no-verify]

直接指定档案所在的父目录即可,无需手动挑选或整理文件, 程序会自动递归检索子目录——无论是解压产生的嵌套文件夹、 按年月分类的目录,还是多次导出的归档存放在一起,均无需手动展平。 即使多份档案的文件散落在同一个文件夹中(如默认下载目录), 也能被精准辨识并分份解析。 无论是经历过多次采集、设备迁移,还是存在彼此断裂的历史备份链路,直接传入即可: 解析器会自动完成合并计算并生成全集数据,避免因手动筛选而遗漏记录。

在执行解析前,程序会预先执行完整的数据校验:针对每个分段文件与单条捕获记录, 对照档案清单中记录的哈希摘要逐一核验,未通过校验的异常记录不会并入最终的结构化数据中。 该校验默认开启,以确保产出数据的真实有效性。 在包含 20,000 余条捕获记录、体量约 619 MB 的真实档案测试中,完整校验仅增加约 8 秒耗时; 如确有性能要求,可通过添加 --no-verify 参数跳过校验(潜在风险为可能包含损坏的捕获数据)。 若仅需单独执行数据一致性校验而不生成解析结果,可运行: node bin/verify.js <目标目录>。

解析过程中唯一会主动拦截的异常是:目标目录中混入了属于不同用户的多份档案。 不同账号的数据一旦混入同一份结构化数据将难以再进行拆分, 而在日常使用中(例如将不同账号的备份解压至同一下载目录)极易发生此类混淆。 若确认多个档案确属同一用户的多个不同账号且需合并,可附加 --ignore-warnings 参数继续执行; 该参数仅忽略中断拦截,控制台依然会完整打印相关的警告提示。

权威文档请参考: doubak-data-parser / README.md —— 详细阐述数据合并的两大不变量,以及为何建议由解析器全量处理原始档案。

第 3 步 · 生成自己的网站

将结构化数据与原始档案中的本地图片结合,可转换为标准的 Markdown + YAML Front Matter 格式, 进而交由主流静态网站生成器进行渲染构建。最终展示形态可参考直观的 官方演示样张站。

npm run md     # 仅导出 Markdown + 图片资源(适配任意静态站生成器)
npm run site   # 进一步构建为完整 HTML 页面
npm run deploy # 部署至 Git 仓库根目录,支持一键发布至 GitHub Pages

通用的 Markdown 文件才是核心数据产物,HTML 仅是其中的一种展示形式。 若希望迁移至 Astro、Eleventy 或 Jekyll 等其他静态生成框架,仅需执行 npm run md 导出标准 Markdown, 生成内容中不包含任何 Hugo 专有的私有语法或依赖。

演示样张站的页脚相较于默认导出多了「本站源码」链接,这是因为其构建时传入了 --source-repo=<仓库地址> 参数——该链接指向托管静态站源码的仓库本身, 由于各用户的托管路径各异,该配置默认不启用。若你将个人站点开源在公开仓库中,可在此填入相应的项目地址。

在正式公开发布至互联网前,请务必审阅内容: 广播与日记正文中可能提及他人的真实姓名或互动评论, npm run deploy 部署脚本在执行前会列出公开内容的变更预览,以便进行最终确认。

权威文档请参考: doubak-site-generator / README.md —— 包含 Hugo 依赖安装、切换第三方生成器以及部署至 GitHub Pages 的完整指引。

第 4 步 · 导出到别处

运行单条命令即可生成适配主流平台的数据导入包,全流程离线执行—— 是否上传及何时上传,均由用户自行掌控,不影响本地档案的安全性。

node bin/export.js <canonical 目录> [输出目录]

NeoDB 的数据支持最为全面,且默认包含其他平台不具备的标记状态历史轨迹。 豆瓣官方页面通常仅保留最新的一条当前状态(如「看过」), 但广播流在发布后即永久固化,因此「想看 → 在看 → 看过」的每个流转节点及其历史评分均得以完整保留, 并精确记录各阶段的发生时间与当时给出的星级评价——豆瓣自身仅记录最新一次评分。 若不需要导出历史流转轨迹,可添加 --no-shelf-history 参数。

上传入口为 NeoDB 界面中的「设置 → 数据 → 导入 NeoDB 备份」, 而非包含「豆瓣」字样的专属导入项——后者专用于接收豆伴(Doufen)导出的 .xlsx 文件,上传此 ZIP 压缩包会导致格式校验失败。 该命名差异的原因在于:豆备直接原生生成符合 NeoDB 官方规范的备份归档, 因此直接使用其原生导入通道即可,无需 NeoDB 为豆备提供额外的定制适配。

完整档案导入 NeoDB 后的实际呈现效果可公开查阅: neodb.social/users/immewx。

鉴于 Letterboxd 仅支持电影类目、Goodreads 仅支持图书类目,导出过程中哪些内容成功迁移、哪些条目因平台限制被舍弃, 生成日志中均会逐项清晰列出。底层逻辑上不可混淆:豆备本地档案始终保留无损的全量超集, 而第三方导出仅属于向下兼容的有损格式适配。

各大第三方平台在导入批量数据后通常难以提供一键撤销功能。 建议首次导入时先使用 --sample=20 参数导出包含 20 条记录的样本包进行测试,确认无误后再执行全量导入。

NeoDB 若遇到兼容问题,可降级使用 CSV

默认导出采用 NeoDB 官方推荐的 NDJSON 归档格式。 若因平台接口变动导致无法识别格式或特定类型条目解析异常, 还可降级使用历史更久的 CSV 兼容方案:

node bin/export.js <canonical 目录> [输出目录] --target=neodb_csv

该命令将生成 neodb-import.zip。上传位置保持一致—— 依然在「导入 NeoDB 备份」页面提交,后台会根据 ZIP 内的文件特征自动识别数据类型。 上传后「检测到的格式」一栏应正确显示为 CSV (若提示「未知格式」,通常表示选取了错误的文件,页面将无法继续提交)。

通过 CSV 模式完整导入真实档案的展示案例可参考: neodb.social/users/doubak ——其与上述 immewx 账号基于同一份原始数据分别走 NDJSON 与 CSV 路径生成,可以直接对照参考两者的呈现差异。

使用 CSV 模式的取舍权衡:在数据结构上,CSV 无法表达豆列集合、 独立日记以及状态历史轨迹。但在以下两项细节上 CSV 具有独特优势:一是导入界面仅在解析 CSV 时提供公开/私密等可见性选择项 (NDJSON 模式下界面会隐藏该选项并默认设为公开,若需设定其他可见性需通过 --visibility=1 或 2 预先写入数据文件); 二是图书类目支持 ISBN 辅助匹配——NDJSON 仅依赖条目 URL 精确匹配, 对于豆瓣上页面已被下架的图书,CSV 借助 ISBN 仍能顺利找回关联条目。

权威文档请参考: doubak-export-adapters / README.md —— 详细汇总各平台字段支持范围、条目匹配策略及降级格式的差异说明。 首次尝试前建议阅读 docs/manual-testing.md 了解手动测试指南。

档案里到底是什么

系统涉及的两种核心格式,在生命周期与设计目标上截然相反。原始档案(bundle)由浏览器扩展直接生成, 代表不可逆的历史采集快照——过去的状态无法在未来凭空复现——因此采集完成即进行数据固化与校验保护; 而结构化数据(canonical)由解析器根据原始档案提炼生成,可随时按最新的解析算法重新计算并覆盖, 维护成本极低。

注:原始档案亦可通过转换历史工具生成。 导入适配器 能够将其他抓取工具保存的历史备份转录为标准原始档案格式,并无缝接入后续的处理流水线—— 目前已支持 2020 年命令行版本 its-my-data/doubak 的历史数据。 若未持有过往的老旧备份,可直接忽略此项说明。

两种格式均基于国际标准 WARC 与通用的 NDJSON 规范设计,绝不使用任何私有二进制结构。 其设计基准非常明确:确保数十年后,任何人在无需本项目专属软件的情况下,仅凭 jq 等通用工具即可完全读取和还原数据。

权威文档请参考: doubak-data-specs / bundle/v1/SPEC.md —— 包含完整格式规范定义、校验器实现及一致性测试用例。

出了问题

各子项目均开放 GitHub Issue 进行问题追踪。提交反馈时,请完整附上终端输出的执行报告日志—— 其中包含的统计指标与精确错误堆栈对于定位根因至关重要。 完整仓库列表请参见 github.com/Doubak。