
Karakeep 与 SingleFile 扩展集成指南一键保存浏览器所见页面为本地书签归档【免费下载链接】hoarderA self-hostable bookmark-everything app (links, notes and images) with AI-based automatic tagging and full text search项目地址: https://gitcode.com/GitHub_Trending/ho/hoarder本篇技术指南讲解如何将自托管书签应用 Karakeep本仓库即其开源实现仓库根目录见 README.md接入 SingleFile 扩展作者为 gildas-lormeau实现所见即所得的页面保存在浏览器里直接点击扩展图标把当前页面含样式、图片、Cookie 会话态完整打成 HTML 归档上传到 Karakeep。读完本文你将掌握 SingleFile 扩展的 REST Form API 接入配置、?ifexists重复书签处理策略、以及用 CLI 批量导入既有 SingleFile 归档的完整流程。为什么需要 SingleFile 集成Karakeep 自身具备爬虫crawler能力但某些页面并不适合服务端爬取需要登录态才能访问的页面、带烦人 Cookie 弹窗的站点、以及明确拒绝被爬虫抓取的网站。SingleFile 的核心理念是在浏览器端完成页面快照——它在你登录的会话里读取渲染完成的 DOM把样式、图片、字体等全部内联进单个 HTML 文件。Karakeep 将这种归档称为precrawledArchive预爬取归档作为书签的一个资产asset保存从而绕过爬虫的所有限制。官方扩展现已内置客户端爬取实验特性底层同样由 SingleFile 驱动如果只需要保存自己浏览器会话里的页面可以不必单独安装 SingleFile 扩展但若想复用 SingleFile 扩展自身丰富的高级选项本文的 REST Form API 方式依然是最灵活的选择。扩展端配置步骤在浏览器中安装 SingleFile 扩展 后按以下步骤将其指向你的 Karakeep 实例打开 SingleFile 扩展的设置页面选择Destinations目标选项选择upload to a REST Form API上传到 REST 表单 API在 URL 字段填入上传地址https://YOUR_SERVER_ADDRESS/api/v1/bookmarks/singlefile把YOUR_SERVER_ADDRESS替换为你的 Karakeep 服务地址在authorization token授权令牌字段粘贴一个 API Key——可以在 Karakeep 设置页面中生成设置data field name数据字段名为file设置URL field nameURL 字段名为url可选在 URL 末尾追加?ifexistsMODE其中MODE取skip、overwrite、overwrite-recrawl、append、append-recrawl之一用于控制同一 URL 已存在书签时的处理方式详见下文重复书签处理策略。配置完成后打开任意网页点击 SingleFile 扩展图标即可。上传完成前扩展不会显示任何进度条——由于归档文件通常较大可能需要 30 秒以上才会在 Karakeep 中出现新书签请耐心等待。上传端点与鉴权说明源码视角从源码可以看到POST /api/v1/bookmarks/singlefile由 packages/api/routes/bookmarks.ts 实现它依次做了四件事通过rejectMutationInReadOnlyMode拒绝只读模式下的写入通过apiKeyScopeMiddleware(assets, readwrite)与apiKeyScopeMiddleware(bookmarks, readwrite)双重中间件要求 API Key 同时具备资产与书签的读写权限这也是扩展端 authorization token 必须使用 API Key 的原因用 zod 校验查询参数ifexists枚举值即上述五种模式缺省为skip以及表单字段url字符串与file文件对象先调用uploadAsset把 HTML 文件存为资产再以type: BookmarkTypes.LINK、precrawledArchiveId指向该资产、source: singlefile创建书签——source字段会被记录便于后续区分书签来源。用 CLI 导入既有 SingleFile 归档如果你本地已经积累了大量 SingleFile 导出的 HTML 归档无需逐个通过扩展上传Karakeep 的命令行工具提供了批量导入命令。导入时需要同时传入归档文件路径和原始页面 URLkarakeep bookmarks import-singlefile page.html --url https://example.com/page使用--if-exists MODE控制同一 URL 已存在书签时的处理方式支持的 MODE 与?ifexists完全一致见下节。从 apps/cli/src/commands/bookmarks.ts 的实现可以看到该命令内部构造FormData把文件作为text/html类型的 Blob 追加到file字段、URL 追加到url字段然后以Bearer API Key请求头 POST 到${serverAddr}/api/v1/bookmarks/singlefile端点并把--if-exists写入ifexists查询参数——也就是说CLI 导入与扩展上传走的是同一条服务端链路行为完全一致。若服务端返回非 2xxCLI 会输出失败原因并设置非零退出码适合写进脚本批量处理。重复书签处理策略ifexists当上传的 URL 与库中已有书签重复时通过ifexists参数URL 上的查询参数或 CLI 的--if-exists选项控制行为模式行为skip默认书签已存在则跳过不创建新记录overwrite用新归档替换已有的最近一次预爬取归档只保留最新一份overwrite-recrawl替换归档并排队触发一次重新爬取以更新正文内容append把新归档追加为书签的额外版本与旧归档共存append-recrawl追加新归档并排队触发一次重新爬取使用示例https://YOUR_SERVER_ADDRESS/api/v1/bookmarks/singlefile?ifexistsoverwrite对应 CLI 写法karakeep bookmarks import-singlefile page.html --url https://example.com/page --if-exists overwrite-recrawl在 packages/api/routes/bookmarks.ts 中createBookmark返回的alreadyExists标志驱动后续分流overwrite系列会从书签现有资产中筛选出最后一个assetType precrawledArchive的资产并调用replaceAsset完成替换若不存在则直接attachAssetappend系列则直接attachAsset追加新归档两种带-recrawl后缀的模式都会额外调用recrawlBookmark让爬虫基于新归档重新提取正文与元数据。选择建议只想保留最新快照选overwrite希望归档随页面演变留痕则选append需要同步更新正文、摘要等派生内容时再带上-recrawl。推荐配置调优SingleFile 扩展端为了获得更好的保存效果建议在 SingleFile 扩展中开启以下选项Stylesheets compress CSS content压缩 CSS 内容开启Stylesheets group duplicate stylesheets together合并重复样式表开启HTML content remove frames移除框架开启。这些设置能显著减小归档体积、去除冗余样式从而加快上传速度并降低存储占用。Karakeep 服务端SingleFile 归档通常体积较大几 MB 到几十 MB而 Karakeep 默认只允许上传不超过MAX_ASSET_SIZE_MB默认50MB的资产。建议将其调高例如100。该变量在 packages/shared/config.ts 中定义z.coerce.number().default(50)在 Docker 部署时通过环境变量注入即可例如在 docker-compose 中为 web 服务添加environment: - MAX_ASSET_SIZE_MB100更完整的变量说明见 docs/docs/03-configuration/01-environment-variables.md。需要提醒的是超出该上限的上传会被服务端拒绝因此请结合你的归档实际大小合理设置。已知限制目前 SingleFile 上传的归档不支持生成截图截图需要爬虫在无头浏览器中渲染页面而 SingleFile 只是上传静态 HTML官方文档声明这一限制将在未来版本中解除。此外上传过程没有进度反馈、大归档耗时较长属于预期行为。如果页面对实时性要求不高、仅需长期存档这种方式是最省事、最可靠的保存路径。【免费下载链接】hoarderA self-hostable bookmark-everything app (links, notes and images) with AI-based automatic tagging and full text search项目地址: https://gitcode.com/GitHub_Trending/ho/hoarder创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考