批量下载飞书wiki文档

首先,偷数据是不道德的,阿弥陀佛……

最近在研究 AI,涉及偷点儿数据存到知识库。

本来想抓某个公众号的,太麻烦了,查了一圈儿发现对方有个公开的飞书知识库,查了一圈儿发现没有太好的批量扒数据的方法,只有一个 cloud-document-converter 很强大,能下载单篇,可惜没有批量的功能。

正好,昨晚 Google 发布了 Gemini 2.0 Flash Thinking Experimental(以下简称 Gemini),之前试过和 Claude 结对编程(我提需求,Claude 写代码),正好试试编程效果。

结论:很好用,不输 chatGPT 的 4o 和 Claude。
最终代码放到了 github 上,仅供学习研究使用:feishu_batch_download,出了事儿概不负责,谁出卖我谁是 🐶
(背景:我做过两年研发,有点儿研发背景,后来很多年基本没写过代码,能勉强看懂,但写够呛)

我不是那些自媒体,就不吹牛逼了。

简单记录下过程和方法:

抓取目录结构

  1. 通过从 Chrome 里分析飞书网络请求
    发现下面这几个可以和知识库的标题有关联,但一坨数据看着眼晕:
  • https://waytoagi.feishu.cn/space/api/wiki/v2/tree/get_info/?space_id=7226178700923011075&with_space=true&with_perm=true&expand_shortcut=true&need_shared=true&exclude_fields=5&with_deleted=true&wiki_token=QPe5w5g7UisbEkkow8XcDmOpn8e&synced_block_host_token=NDsAdX4spozsglxgqm7caJqdnVf&synced_block_host_type=22
  • https://waytoagi.feishu.cn/space/api/wiki/v2/tree/get_node_child/?space_id=7226178700923011075&wiki_token=TRJEwdbQEiJjvykq8nJc6juvn6g&expand_shortcut=true&exclude_fields=5&is_pre_heating=false&synced_block_host_token=NDsAdX4spozsglxgqm7caJqdnVf&synced_block_host_type=22
  1. 把接口链接和数据丢给 Gemini,分析看看

图片描述

分析了一大堆,结果证明猜测的八九不离十:

  1. 最近也同时在研究 n8n 平台,想着搭个工作流,以后方便复用,折腾了半天,太麻烦了,拉到吧,有简单的不用,没必要非得折腾这些。

对于 n8n 平台、coze 平台等能完成的事,个人基本归类:

流程固定,且 简单

比如固定抓个 rss,固定发个消息,没有太多复杂逻辑的

  1. so,直接上 Python

简单对话几轮后,直接抓下来了目录结构,好使 👍🏻:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
{

"title": "⭐ 结构化提示词",

"url": "https://langgptai.feishu.cn/wiki/RXdbwRyASiShtDky381ciwFEnpe",

"wiki_token": "RXdbwRyASiShtDky381ciwFEnpe",

"children": [

{

"title": " 写出高质量 Prompt",

"url": "https://langgptai.feishu.cn/wiki/C9i7wrU4eir4BmkIgQucUYUQndd",

"wiki_token": "C9i7wrU4eir4BmkIgQucUYUQndd",

"children": [

{

"title": "结构化提示词系统论述: 构建高性能 Prompt 之路",

"url": "https://langgptai.feishu.cn/wiki/ASXOwDbTEiH9CUkXFA5cLHumn88",

"wiki_token": "ASXOwDbTEiH9CUkXFA5cLHumn88",

"children": []

},

{

"title": "Prompt 进阶 — 提示链(Prompt Chain)和多提示词协同",

"url": "https://langgptai.feishu.cn/wiki/UUJ4wDXMpiFUWokJHQpcyni7nzg",

"wiki_token": "UUJ4wDXMpiFUWokJHQpcyni7nzg",

"children": []

},

{

"title": "提示工程、RAG 和微调,如何让 LLM 应用性能登峰造极",

"url": "https://langgptai.feishu.cn/wiki/OJXbw2uawidLAOkhWD9cCiI1nPc",

"wiki_token": "OJXbw2uawidLAOkhWD9cCiI1nPc",

"children": []

},

{

抓取单篇

网上一顿搜,一顿找,找到一个插件 cloud-document-converter 很强大,能下载单篇,可惜没有批量的功能

批量抓取

继续和 Gemini 聊

1
2
3
4
5
6
7
8
9
10
11
我:

https://github.com/whale4113/cloud-document-converter

这个项目是一个chrome插件,作用是下载飞书文档。

飞书文档链接:https://xxx.feishu.cn/wiki/xxx

插件可以点击后,一键下载为本地的markdown文件。

我的诉求是,我已经抓下来了一个飞书文档目录,包含三百多飞书的链接,期望全部下载下来

过程略了,反正又是一顿折腾。

从大致方案,到进一步细化成代码,

让 Gemini 总结了一下过程:

当然!非常乐意为您总结一下我们为了解决您最初的需求,即 批量下载飞书文档为 Markdown,所探讨和最终采用的大致方案。

您最初的需求核心是: 希望能够自动化批量地将飞书文档导出并保存为 Markdown 文件,以方便您进行本地管理和编辑。

在解决这个问题的过程中,我们主要经历了以下几个阶段和方案:

  1. 理解核心需求与痛点: 我们首先明确了您的核心需求是 批量自动化 下载,最大的痛点是下载过程中 插件弹出的 “另存为” 对话框,阻碍了完全自动化流程的实现。

  2. 初步方案:Python + Selenium + Chrome 插件自动化

    • 技术选型: 我们选择了 Python 作为编程语言,使用 Selenium 库来控制 Chrome 浏览器,并利用 Chrome 插件 “Cloud Document Converter” 来实现飞书文档到 Markdown 的转换。
    • 自动化流程设计: 脚本模拟人工操作,依次完成以下步骤:
      • 启动 Chrome 浏览器并 自动加载 .crx 插件
      • 配置 Chrome 浏览器 自动下载 到指定目录,禁止弹出下载对话框 (浏览器默认设置)。
      • 循环打开您提供的 飞书文档链接列表
      • 在每个文档页面中,定位并点击插件的 “导出为 Markdown” 按钮
      • 期望: 插件在点击导出后,能够直接静默下载 Markdown 文件到预设目录,无需人工干预。
  3. 遇到挑战:插件弹出 “另存为” 对话框,阻碍自动化

    • 问题发现: 实际运行初期脚本后,我们发现虽然 Chrome 浏览器设置了自动下载,但插件在导出时仍然会弹出 “另存为” 对话框,需要手动点击 “保存” 按钮才能完成下载,导致自动化流程中断。
    • 原因分析: 我们推测,这个弹窗并非 Chrome 浏览器默认的下载对话框,而是 插件自身代码逻辑弹出的,因此 Chrome 浏览器的自动下载设置对其无效。 您提供的插件源代码 download-lark-docx-as-markdown.ts 也印证了我们的猜测,插件使用了 fileSavelegacyFileSave 函数来处理文件保存,这些函数可能会触发弹窗。
  4. 解决方案探索:

    • 方案一 (最初尝试):Selenium 定位并点击弹窗 “保存” 按钮 (失败)
      • 思路: 尝试使用 Selenium 定位弹窗上的 “保存” 按钮,并模拟点击。
      • 结果: 定位元素失败,脚本报错。 原因可能是弹窗并非标准的 HTML 元素,或者 Selenium 无法跨插件边界定位元素。
    • 方案二 (最终采用的权宜之计):pyautogui 模拟键盘操作 (成功但非完美)
      • 思路: 既然无法精确定位弹窗按钮,就退而求其次,使用 pyautogui模拟按下键盘上的 “回车键 (Enter)”。 通常情况下,在 “另存为” 对话框中,按下回车键默认会触发 “保存” 操作。
      • 结果: 成功绕过弹窗,脚本可以继续运行完成批量下载。 虽然这种方法并非完美,依赖于键盘模拟,存在一定的不稳定性,但 在当前情况下,这是最快速、最简单可行的解决方案。
    • 方案三 (更彻底但更复杂的方向):修改插件源码 (尚未实现,但值得探索)
      • 思路: 既然弹窗是插件代码逻辑控制的, 最理想的方案是直接修改插件的源代码, 移除或禁用 弹出 “另存为” 对话框的代码逻辑, 实现真正的静默下载。
      • 可行性分析: 插件是开源的,您也找到了 GitHub 仓库,理论上可以修改源码。 但您表示看不懂插件代码,修改难度较大。 我们一起初步分析了 download-lark-docx-as-markdown.ts 代码,定位到可能与弹窗相关的 fileSavelegacyFileSave 函数, 并探讨了可能的修改方向。
      • 结论: 修改插件源码 是 最优雅、最彻底的解决方案, 但需要一定的 JavaScript 编程能力和插件开发经验, 难度较高, 需要投入更多时间和精力。 目前我们 暂时采用 pyautogui 方案 作为 权宜之计, 同时 鼓励您 或 其他开发者 尝试 修改插件源码, 以实现更完美的自动化下载。
  5. 最终代码与 README.md 为了方便您使用和开源分享,我们最终整理输出了:

    • 集成了 pyautogui 模拟回车键的 Python 脚本 download_feishu.py (最终完整版): 这是目前 最可直接使用、最快速解决问题 的方案。
    • 简洁但信息全面的 README.md 文件: 用于指导其他用户如何使用您的脚本,并遵循开源项目的规范。

总结来说,我们解决您批量下载飞书文档需求的方案,核心是:

使用 Python 结合 Selenium 和 Chrome 插件,自动化操作浏览器,并巧妙地利用 pyautogui 模拟键盘操作来绕过插件弹窗,最终实现批量下载 Markdown 文件的目标。 同时,我们也探讨了更深层次的解决方案——修改插件源码,并为您提供了代码分析和修改的思路, 为未来更完美的解决方案 奠定了基础。

最终运行了几个小时,慢慢抓,怕出事,但,好使 👍🏻