乐于分享
好东西不私藏

飞书云文档很好,但你的知识最好能被带走

飞书云文档很好,但你的知识最好能被带走

我想把飞书知识库导出来,不是因为飞书不好用。

恰恰相反,飞书云文档在协作场景里很好用。

能多人编辑,能评论,能挂表格,能放附件,能做知识空间。对团队来说,它是一个很顺手的在线工作台。

但问题也出在这里。

当我想搭建自己的个人知识库时,我发现云端文档有很多限制。

它适合协作,不一定适合长期沉淀。

它适合在线查看,不一定适合本地加工。

它容易把内容放进去,不一定容易把内容完整带出来。

我想做的不是简单备份。

我想把过去散落在飞书知识库里的内容,变成可以被我自己重新组织、检索、标注、二次加工的本地资料。

说得更直白一点:

我想把它变成我个人知识库的一部分。

这时候,问题就出现了。

飞书里一篇文档,两篇文档,手动复制当然没问题。

但当知识库里有几十篇、上百篇文档,还有表格、附件、旧版文档、新版文档时,手工导出就变成了一件很低效的事。

你要一个个打开。

一个个导出。

一个个改文件名。

一个个检查有没有漏掉表格和附件。

更麻烦的是,有些文档可以打开,却不一定能顺利导出;有些文档看起来是文字,里面其实嵌了表格;有些内容能在线搜索,但离开飞书以后就很难重新组织。

这就是我真正不舒服的地方。

知识明明是自己长期积累的,却被困在一个在线入口里。

能看,能搜,能协作。

但不够自由。

如果我要用 Obsidian 管理它,用本地文件夹整理它,用 AI 工具读取它,用 RAG 做检索增强,用 Codex 帮我批量处理它,云端知识库就开始显得不够开放。

所以我最后想解决的,不只是下载飞书文档。

而是把飞书里的内容,从一个云端入口,变成我自己可控的知识资产。

这篇文章就写一下,我是怎么把飞书知识库批量下载到本地的。

它不是一篇特别硬核的开发教程,更像是一次踩坑复盘:哪些地方必须配置,哪些地方最容易误判,以及为什么我越来越觉得,重要知识最好不要只存在云端入口里。

云文档不是普通文件夹

很多人一开始会有一个直觉:

既然我能打开飞书知识库,那把它下载下来应该也不难。

实际操作之后会发现,事情没这么简单。

飞书知识库里有知识空间,有节点,有云文档,有表格,有普通附件,还有各种权限关系。

你本人能打开,只说明你的账号有权限。

脚本能不能打开,取决于飞书自建应用有没有权限。

你在线能查看,只说明页面可以访问。

能不能批量导出,还要看 API、文档类型和导出权限。

所以批量下载飞书知识库,第一步不是急着写脚本,而是先把权限链路打通。

下载只是表层动作。

授权才是入口。

先让飞书知道谁在下载

要批量处理飞书知识库,首先要去飞书开放平台创建一个自建应用。

入口是:

https://open.feishu.cn/?lang=zh-CN

进入「我的应用」,创建一个「企业自建应用」。

名字可以随便取,比如:

Codex 文件助手

创建完成后,在应用后台找到「凭证与基础信息」。

这里会有两个东西:

App IDApp Secret

可以把它理解成这个应用的身份和钥匙。

App Secret 不要发给别人,也不要放到公开仓库里。

后面本地脚本会通过一个 .env 文件读取它,不需要把它写进代码。

创建应用以后,还要添加「机器人」能力。

然后进入「权限管理」,把云文档、知识库、表格、文件下载相关权限加上。

不同飞书后台里权限名称可能会有一点变化,但大方向就是这些:

读取云文档编辑云文档读取电子表格导出云文档下载云空间文件读取知识库节点

看到和这些词相关的权限,就重点看:

云文档知识库DriveDocsSheets导出下载

配置完权限以后,去「版本管理与发布」发布应用。

如果企业需要管理员审批,就等审批通过。

没有发布,权限只停留在后台配置里,还没有真正生效。

让知识库放行这个应用

这里是第二个容易踩坑的地方。

开放平台里给了权限,只说明这个应用具备某些能力。

目标知识库愿不愿意让它访问,还需要单独配置。

我用的是比较简单的方式:通过群来授权。

先在飞书里新建一个群,比如:

Codex 知识库授权群

然后进入群设置:

群机器人 -> 添加机器人

搜索刚创建的自建应用机器人,把它加进群里。

接着打开目标飞书知识库,进入:

知识空间设置 / 知识库设置 -> 权限设置

把刚才这个群添加进去。

如果只是下载,给阅读权限通常够。

如果后面还要写回或批量修改,再给更高权限。

这一步的本质,是让知识库把这个应用当成一个被允许访问的成员。

如果少了这一步,后面很容易遇到这样的错误:

permission denied: wiki space permission denied

这类报错通常不是代码坏了。

多数时候,只是知识库还没放行。

本地只需要保存一个 env 文件

权限打通以后,就要让本地脚本知道 App ID 和 App Secret。

不要把密钥写进脚本。

在本地创建一个文件,比如:

C:\Users\你的用户名\Desktop\feishu_connector.env

内容是:

FEISHU_APP_ID=你的AppIDFEISHU_APP_SECRET=你的AppSecret

后面运行命令时,用 --env 参数指向这个文件。

比如:

--env "C:\Users\你的用户名\Desktop\feishu_connector.env"

脚本读取 App ID 和 App Secret 的环节,就发生在这里。

它不会去猜你的密码文件在哪里。

它只认命令里 --env 后面指定的这个文件。

如果你另外用一个 txt 文件记录 App Secret,那只是方便自己复制,不建议直接让脚本读取那个文件。

真正给脚本用的,应该是这种标准格式的 env 文件。

先测试,再下载

每次处理一个新知识库,我建议先跑读取测试。

不要一上来就全量下载。

测试命令长这样:

node "脚本路径\feishu_wiki_download.mjs" --env "env文件路径" --spaceUrl "飞书知识库链接" --mode list --limit 10

我自己的命令大概是这种形式:

node "C:\Users\你的用户名\Documents\Codex\feishu_connector\feishu_wiki_download.mjs" --env "C:\Users\你的用户名\Desktop\feishu_connector.env" --spaceUrl "飞书知识库链接" --mode list --limit 10

如果成功,会看到类似这样的结果:

{"spaceId""7631588336204942287","count"10,"summary": {"docx"10  }}

看到这个结果,基本说明几件事已经打通:

App ID / App Secret 正确应用已经发布知识库已经授权本地脚本能访问飞书 API

如果这里失败,先别急着下载。

先看错误。

如果是 permission denied,大概率是知识库权限没加。

如果是 request trigger frequency limit,就是飞书限流,等一会儿再跑。

做自动化时,小范围验证会省掉很多后面的麻烦。

正式下载只需要一条命令

测试通过后,再跑正式下载命令:

node "脚本路径\feishu_wiki_download.mjs" --env "env文件路径" --spaceUrl "飞书知识库链接" --output "本地下载目录" --mode download --skipExisting

举个例子:

node "C:\Users\你的用户名\Documents\Codex\feishu_connector\feishu_wiki_download.mjs" --env "C:\Users\你的用户名\Desktop\feishu_connector.env" --spaceUrl "https://my.feishu.cn/wiki/space/xxxx" --output "C:\Users\你的用户名\Desktop\飞书云文档" --mode download --skipExisting

几个参数的作用:

--env           指定 App ID 和 App Secret 所在的 env 文件--spaceUrl      指定飞书知识库链接--output        指定下载到本地哪个目录--mode download 执行下载--skipExisting  跳过已经存在的文件

--skipExisting 很有用。

飞书 API 有时候会限流。

如果中途有几个文件失败,可以等一会儿重跑同一条命令。

加上 --skipExisting 后,已经成功下载的文件不会重复下载,只会继续补没下完的部分。

这会少很多重复文件,也少很多焦虑。

下载后会得到什么

我现在的处理策略是:

飞书文档 -> 尽量保存为 Markdown飞书表格 -> 导出为 Excel普通文件 -> 按原文件下载

为什么文档不强行导出成 Word 或 PDF?

因为实际测试下来,有些飞书文档的导出任务会失败。

尤其是旧版文档、复杂文档,或者里面有表格、特殊块的时候。

如果一直卡在原生导出上,可能一个文件都下不来。

所以我更倾向于先用 Markdown 兜底,而且 Markdown 天生就是为大模型而生的。

普通段落、标题、列表会转成 Markdown。

文档里的表格,也尽量转成 Markdown 表格。

它不一定能完整还原飞书里的排版、图片和特殊组件。

但它能让核心内容先落到本地。

这里有一个取舍:

自动化批量下载,优先解决内容迁移,再考虑排版还原。

如果非常在意排版,少数重要文档可以单独手动导出。

但如果目标是备份、检索、迁移、喂给 AI,Markdown 反而更适合。

日志很重要

下载完成后,本地目录里会生成一个日志文件:

feishu_wiki_download_manifest.json

这个文件会记录每个节点的处理情况:

成功还是失败文档标题节点类型飞书 token本地保存路径错误原因

批量处理文件时,失败并不可怕。

真正麻烦的是不知道哪里失败了。

有日志,失败就是一个待处理清单。

没日志,失败就是一团雾。

如果某几个文件报错,可以打开日志看原因,然后决定是重跑、手动处理,还是暂时跳过。

我踩过的几个坑

第一个坑,是账号权限和应用权限要分开看。

你能打开知识库,只说明你的账号有权限。

脚本用的是飞书自建应用的身份。

所以应用也要被授权。

第二个坑,是在线查看和批量导出之间还有一段距离。

有些文档可以在线查看,但导出任务会失败。

这时候就需要 Markdown 兜底。

第三个坑,是飞书文档不一定是纯文本。

里面可能有表格、图片、任务列表、引用块和复杂组件。

脚本不能只抓一段纯文本,至少要能处理常见块结构。

第四个坑,是 API 会限流。

看到这个错误:

99991400 request trigger frequency limit

别急。

等一会儿,重跑,加 --skipExisting

很多自动化任务,稳定比速度更重要。

这件事最后提醒了我什么

做完这套流程以后,我反而觉得,批量下载只是表层收益。

更大的提醒是:

很多人的知识,都被放在各种在线入口里。

飞书、Notion、语雀、网盘、各种 SaaS。

这些工具当然方便。

我也会继续用。

但方便解决的是使用问题,拥有解决的是迁移问题。

如果一份资料只能在某个平台里打开,不能导出,不能迁移,不能重新组织,那它对你的长期价值就会打折。

重要资料最好有本地副本。

这不是不信任平台。

这是给自己的知识系统留一条退路。

云文档很好。

但真正属于你的知识,最好能被你带走。