系列前几篇讲了 vault 的四层架构(#1)、文章怎么分类和打标签(#2)、103 个公众号怎么每天自动进知识库(#3)。这篇把整条管道串起来说说——从采集到入库的完整流程。
先放几个数字。目前 vault 里有 9000 多篇公众号文章,来自 108 个号。这些文章不是手动一篇篇下载的,也不是直接导入了事。中间有一条管线在跑——采集、清洗、去重、图片本地化、分类归档,五个环节串在一起,每天自动走一遍。
这篇就说清楚每个环节做什么。
## 采集:双通道兜底
采集层分两条路,优先级从高到低。
第一条路是 WeRSS。自己部署的 Docker 服务,订阅公众号后通过 API 拉取全文。支持 `content=true&format=markdown` 参数,直接返回正文的 Markdown 版本,几秒就能拿到一篇。
第二条路是 wechat-article-exporter。本地部署的 Node 服务(port 3002),通过公开 endpoint 下载。WeRSS 找不到的内容走这条路,主要用于历史文章或者还没缓存的新文。
两条路的关系很简单:优先走 WeRSS,拿不到就走 exporter。采集脚本写了一个按优先级 fallback 的逻辑,用户不需要感知走的是哪条路。结果一样——Markdown 格式的全文。
## 清洗:10 步去除噪音
原始文章质量参差不齐。从微信 HTML 转过来的 Markdown,带了很多不该进知识库的东西。清洗管线做 10 件事:
1. 移除 HTML 标签残留。``、`` 这些标签没完全去掉的,统一清理。
2. 去掉样式声明。`style=””`、`text-align` 等无关样式代码全部删掉。
3. 清理尾随反斜杠。有些工具转换后在行尾留下 `\`,一并处理。
4. 折叠多余空行。连续两个以上空行的,压缩成一个。
5. 移除空段落。没有内容的 `
` 直接删掉。
6. 去广告和推广段。文章尾部固定的「关注我们」「点击在看」等文字,通过正则和关键词匹配移除。
7. 统一换行符。`\r\n` 转成 Unix 风格的 `\n`。
8. 修复 markdown 标记。`**bold**` 被转成 `* bold *`(多空格)的,修正。
9. 移除 `#imgIndex` 标记。部分工具在图片位置插入的索引标记,对知识库没有用。
10. 处理异常字符。零宽空格、不间断空格这些不可见字符也清理掉。
10 步做完,一篇公众号文章就变成了干净的 Markdown。
## 去重:双重校验
同一篇文章可能通过不同渠道进来。WeRSS 拉了一篇,wechat-exporter 又拉了一篇。或者同一个号在 IMA 和 Obsidian 两边都导了一次。
去重分两层。
第一层是 URL 去重。每篇文章的原文 URL(`mp.weixin.qq.com/s/xxx`)作为主键。采集脚本维护一个已导入 URL 的缓存,新文章进来先查这个缓存,匹配上了就跳过。
第二层是 MD5 内容去重。有时候同一条内容通过不同 URL 分发(转载),URL 不同但正文一样。对正文做 MD5 哈希,匹配已导入的哈希列表,重复的就不进 vault。
两层去重跑下来,重复率大概在 3%。主要来自同一个号的多渠道采集和跨号转载。
## 图片本地化
微信公众号的图片链接(`mmbiz.qpic.cn`)默认会过期,或者被防盗链限制。这是知识库最头疼的问题之一。
解决方案是下载到本地。采集脚本在导入文章时做以下操作:
1. 扫描正文中的图片链接。正则匹配所有 `mmbiz.qpic.cn` 和 `mmbizcdn.qpic.cn` 网址。
2. 下载到本地 `assets` 目录。按公众号名分目录存放,文件名用图片 URL 的 MD5 加扩展名。
3. 替换正文中的图片 URL。原文里的 `` 变成 ``。
4. 完整性校验。下载后检查文件大小,小于 100 字节的视为下载失败,重新下载。
图片本地化之后,知识库脱离了对微信 CDN 的依赖。在 Obsidian 里看图片,不需要联网。
## 分类归档:零人工判断
这一步在上一篇(#2)已经详细讲过。简单说一下在整个管线里的位置:
文章经过采集、清洗、去重、图片本地化之后,用脚本自动写入 `公众号文章/` 目录。按公众号名建文件夹,文件名统一 `YYYY-MM-DD_公众号名_标题.md`,自动打好 `#来源/公众号` 和 `#公众号/公众号名` 两个标签。
整个环节不需要人参与。
## 整条管线怎么跑
每天凌晨 4 点,Hermes 的 cron 任务触发采集脚本。流程如下:
1. 查询 WeRSS 已订阅的公众号列表
2. 逐个公众号查询最新文章列表
3. 每篇新文章先走 WeRSS 全文下载,失败则 fallback 到 wechat-exporter
4. 对下载的 Markdown 执行清洗流程(10 步)
5. 执行 URL 和 MD5 双重去重校验
6. 下载并本地化正文中的图片
7. 生成带 frontmatter 的 Markdown 文件
8. 写入 `公众号文章/` 对应目录
9. 更新采集清单
整条管线跑完 108 个号的新文章,大概 15-20 分钟。
## 系列总结
这个系列写了四篇:从 vault 的四层架构到分类管理,从自动采集到整条管线串联。四篇合起来是一个人用 Obsidian 管公众号知识库的完整思路。
核心就几个点:结构简单(四层够用)、自动化优先(能不手动就不手动)、标签不做主观判断(只表来源)。
如果觉得有用,也可以看看之前发的 Hermes 生态系列。那套系列讲的是工具侧——怎么用 Hermes 搭 AI 助手、怎么用飞书 bot 管笔记和运维。知识库系列讲的是方法侧——工具搭好之后,往里面存什么、怎么存。两条线合起来,就是从零到一的完整闭环。