Clean Web Clipper 添加到 Chrome(免费)

适用人群

把 API 文档保存为 Markdown,代码原样保留

Clean Web Clipper 从页面本身读出代码语言:代码块的 class、父元素,或者高亮库留下的标记,再把它写进 Markdown 代码块。在九个页面的技术语料上,156 个代码块中有 73 个保留了语言标签,两款对比引擎分别只有 20 个和 0 个。

剪藏的文档为什么总要返工

技术文档的主体是代码,而代码恰恰是大多数剪藏工具最先弄丢的部分。你把框架文档的某一页,或者一个以后还会用到的回答存下来,粘贴进笔记,结果每个代码块都是光秃秃的:没有 js,没有 bash,也没有 sql。高亮没了,一眼分清哪段是 shell 命令、哪段是 JSON 请求体的能力也跟着没了。

剩下的损坏在结构上。某个单元格里放着代码示例的表格,被压成了一行。版本切换器和“本页目录”侧栏混进了正文中间。包在代码组件外面的 div 以原始标签的形式留了下来。手工修好这些,比凭记忆重写一遍笔记还费时间,所以很多人干脆不剪藏文档,只把标签页一直开着,直到它过时。

开着的标签页是第三个问题。文档有版本,网址通常没有:你按 v4 读过的那一页,悄悄变成了 v6,某个参数改了名,某个选项被删了,书签照样能打开,只是内容已经不同。你的笔记里没有任何记录说明当初到底是照着哪个版本写的代码。一个在文件头里记着网址和页面自身日期的文件,一年后还能回答这个问题;书签从来回答不了。

笔记里实际得到的是什么

代码块保留了语言标签developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
---
title: "Array.prototype.filter()"
source: "https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter"
extraction: "dom"
---

**`filter()`** 方法创建给定数组一部分的浅拷贝,其包含通过所提供函数实现的测试的所有元素。

## 示例

### 筛选排除所有较小的值

```js
function isBigEnough(value) {
  return value >= 10;
}

const filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// filtered is [12, 130, 44]
```

为技术文档做好设置

一次花六分钟设置,之后交给快捷键。默认设置是按阅读文章调的;文档需要不同的文件名,不需要作者字段,也不需要图片。

  1. 安装扩展程序,把图标固定到工具栏。右键点击图标,选择选项,设置会在新标签页中打开。
  2. 点击图标时设为“存到文件夹”。这样剪藏就只是按一下键,中间不弹任何窗口。预览窗口在刚上手时有用,熟悉之后就只是碍事。
  3. 选择文件夹。指向一个已经纳入版本控制的目录,比如你正在开发的仓库里的 docs/clips。浏览器只会请求确认一次,并在这个浏览器配置文件中记住授权。
  4. 把文件名模板设为 {domain}-{title}。四个框架都有一页叫“快速入门”,文件名里没有域名的话,第四个会悄无声息地变成 getting-started-4
  5. 在属性部分保留 sourceextraction,关闭 author。文档页面很少署名,每个文件里都有一个空字段,只是迟早要清理的噪音。
  6. 把图片设为跳过。别人 IDE 的截图没法搜索,而且图片链接指向的 CDN 迟早会变。
  7. 打开 chrome://extensions/shortcuts,确认 Alt+Shift+M 已绑定。如果被别的扩展程序占用了,就在这里改回来。

适合开发者的设置

下面是值得从默认值改掉的几项,以及每一项为什么对技术文档特别重要,而不是对一般阅读重要。

设置项取值为什么这样设
点击图标时存到文件夹一天剪藏二十次,不该弹二十次窗口
文件夹仓库里的 `docs/clips`剪藏和代码一样被版本管理、审查和搜索
文件名模板`{domain}-{title}`各框架文档的标题会重名,域名不会
图片跳过截图无法用 grep 搜索,图片地址失效得比文字快
属性开启 `source` 和 `extraction`,关闭 `author`你需要网址和提取路径;文档页没有值得保留的署名
按网站规则`reddit.com` → 子文件夹 `threads`论坛回答和官方文档过时的方式不同,值得分开存放
快捷键`Alt+Shift+M`手不离键盘,决定了你是真的剪藏还是想想就算了
页面上没有 class,代码块就没有标签一个代码示例靠手工排版的文档页
启动服务之前,先执行数据库迁移:

```
./bin/migrate --env production
```

```sql
SELECT id, created_at FROM sessions WHERE expires_at < now();
```

第二个代码块在页面上带有 `class="language-sql"`。第一个什么都没带,
于是保持无标签,而不是被标上一个猜测的语言。

三个工作场景

锁定你当初实际依据的版本

你正在看某个框架 v4 分支的文档,读的是一个在 v5 中被改名的配置参数。你按下 Alt+Shift+M。文件以 example-dev-configuration-reference.md 的名字落进 docs/clipssource 指向带 /v4/ 的网址,文件头里是页面自己声明的日期。

八个月后,这个参数在生产环境里的表现变了,没人记得当初为什么这样设。剪藏文件就在仓库里,和那次改动处在同一段提交范围内,它写明了当时的决定是照着哪个版本的文档做的。而线上网址现在展示的是 v6,已经完全不提这个参数了。

真正解决问题的那个论坛帖子

官方文档只写了顺利的情况;你遇到的问题,解法在一个 Reddit 帖子里,往下翻四层评论,被采纳的回答有 140 分,排在一个 30 分的错误回答下面。你剪藏了这个帖子。按网站规则把它送进 threads,评论结构以嵌套引用块的形式保留下来,每条都带着得分。

回头再读时,得分才是关键。把帖子直接复制粘贴成平铺文本,排序信号就全丢了,你只能把五种意见重读一遍,却分不清社区认同的是哪一个。

一张变量表,直接贴进 Pull Request

部署指南里有一张包含十八个环境变量的表格,其中三个单元格里有代码示例。你在页面上选中这张表,剪藏选中内容,把 Markdown 粘贴进 Pull Request 的描述。GitHub 会把它渲染成表格,因为它是 GFM 表格,而不是截图。

在包含 15 个表格的技术语料上,这个转换器保留了 12 个,对比的每个引擎各保留 7 个。让通用转换器出错的,正是这类单元格:里面有代码或列表的那种。

和常见做法比一比

下面每种做法都行得通,你团队里现在大概就有人在这么做。第三列是真实的代价,包括这个扩展程序自己的。

现在的做法得到什么代价是什么
标签页一直开着页面本身,原封不动下次重启浏览器就没了,文档版本还会在你不知情时更新
复制粘贴到编辑器文字,有时连侧栏一起代码块没有语言标签,表格变成一行
打印为 PDF版式固定的页面副本不能用 `grep` 搜索,不能 diff,Cookie 提示也一并印进去
加书签一个指针,点一下就有指针打开的是页面今天的内容
其他剪藏扩展程序Markdown,但裁剪得少在 109 个页面上正面对比:重复的菜单行 282–491 条,这里是 102 条
Clean Web Clipper带语言标签的代码块和来源文件头的 Markdown一次一个页面,没有爬虫,不下载图片

结果不对时怎么办

为什么我的代码块没有语言标签?

因为页面没有说明它是什么语言。Clean Web Clipper 读取的是网站高亮库留下的 class,不会看着代码去猜。手工排版、没有 class 的示例,得到的就是无标签代码块,这是诚实的结果。给一段 shell 命令标上猜来的 python,比不标更糟,因为高亮会理直气壮地把错误的部分上色。

为什么指南少了一半?

几乎总是因为选项卡或折叠面板。扩展程序转换的是浏览器实际渲染出来的内容,只有点击后才插入的选项卡内容,在你点击之前根本不在 DOM 里。先打开选项卡、展开折叠的部分再剪藏,或者每个版本各剪藏一次。如果网站把所有选项卡都渲染出来、只用 CSS 隐藏,那么它们会依次全部保留下来。

为什么提示“没有文章”?

API 调试台、搜索结果页或软件包索引,内容大多是链接文字,扩展程序会有意拒绝这类页面:如果提取出的字符中有大约四分之一以上在链接里,它就提示“没有文章”,而不是塞给你三百条链接。也正因为这种拒绝,它在“有效文本比例”上的得分,低于那些总会返回点什么的引擎。

文件里的 extraction 字段是 jsonld-articlebody,这是什么意思?

意思是页面把文章正文放进了结构化数据,却没有完整渲染到 DOM 里,所以正文是从结构化数据里读取的。这一点被记录下来而不是隐藏,因为两条路径的结果可能不同:结构化数据里的副本有时是较早的草稿,有时又是唯一完整的版本。看到这个值,在依赖这段文字之前,值得对照原页面看一眼。

它不做什么

它不会抓取整个文档站,一次只处理一个页面,也就是你正在看的那一页。它不下载图片、示意图或其他二进制文件,图片链接仍然指向原网站。对于没有标注语言的代码块,它不会去猜,所以高亮库没留下 class 的页面,得到的是没有标签的代码块,而不是标错的代码块。在没有正文的页面上,比如 API 调试台或搜索结果页,它会提示“没有文章”,而不是塞给你三百个链接。

添加到 Chrome(免费)完全免费:无需账号,无需注册,没有限制。

常见问题

能识别哪些编程语言?
页面自己声明的任何语言。Clean Web Clipper 不根据代码内容推断语言,而是读取网站高亮库留下的 class,所以标签的准确程度和原页面完全一致。
用 JavaScript 渲染的文档站能剪藏吗?
能。扩展程序读取的是页面渲染完成后的 DOM,所以单页应用形式的文档站,你看到什么就剪藏到什么。
行号会混进代码块吗?
如果网站把行号渲染成单独的元素,就不会,大多数高亮库都是这样做的。如果行号本身就是代码文本的一部分,它们会被保留,因为没有任何东西能把它们和代码区分开。
开发文档里的图片能去掉吗?
能。把图片设为“跳过”,可以全局设置,也可以只对某个网站设规则。
能一次剪藏整个文档站吗?
不能。没有爬虫,也没有批量模式,你只剪藏自己真正需要的页面,一次一页。
公司内网里需要 SSO 登录的 Wiki 能用吗?
能。扩展程序读取的是浏览器已经为你当前会话渲染好的页面,所以登录后能看到的内容,剪藏起来和公开页面一样。页面的文本和标题永远不会离开你的电脑,剪藏成功的页面的完整地址也不会。会发送出去的(除非你在设置中关闭)有:剪藏成功时的纯域名(是 wiki.yourcompany.com,而不是具体页面)、转换失败的页面地址、你打开了扩展程序的哪些界面,以及一个随机安装编号。局域网地址(localhost、.local 域名、10.x、192.168.x)从不发送。
剪藏的文件能放进 git 吗?
这正是它们的用途。它们是带 YAML 文件头的 UTF-8 文本文件,可以逐行 diff,像源代码一样合并,在仓库里几乎不占空间。下一个版本发布时再剪藏同一个参考页面,diff 就能显示厂商改了哪些段落。
支持哪些浏览器?
Chrome 以及其他 Chromium 浏览器:Edge、Brave、Vivaldi 和 Opera。它是 Manifest V3 扩展程序,不申请你所浏览网站的访问权限,只能读取你点击图标或按下快捷键的那个标签页。
为什么在 `chrome://` 页面上没有反应?
浏览器禁止扩展程序在这类页面上运行,扩展程序商店本身也一样。这是浏览器的规则,不是某个设置,任何扩展程序都读不了这些页面。
剪藏一次要多久?
普通文档页面只需几十毫秒。带有几百个参考链接的超长页面要几百毫秒,因为脚注要在清理程序删掉它们依赖的 id 之前先收集起来。实测耗时显示在剪藏窗口的角落里。