有道云笔记批量导出工具|图形界面一键导出,支持 Markdown、富文本格式完整保留、图片 base64 内嵌,免 Python 环境,Windows/macOS/Linux 通用,可迁移 Obsidian/Notion/语雀等。
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 5 天前 | ||
| 14 天前 | ||
| 9 天前 | ||
| 14 天前 | ||
| 16 天前 | ||
| 13 天前 | ||
| 9 天前 | ||
| 1 个月前 | ||
| 16 天前 | ||
| 1 个月前 | ||
| 9 天前 | ||
| 13 天前 | ||
| 16 天前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 16 天前 | ||
| 14 天前 | ||
| 14 天前 |
有道云笔记批量导出工具 · 图形界面版
youdaonote-export-multiplatform —— 一键把有道云笔记完整导出为本地 Markdown:图片自动内嵌为 base64、富文本格式原样保留,导出的文件完全自包含,可直接导入 ima / 语雀 / Notion / Obsidian 等知识库。
和命令行脚本最大的区别:内置图形界面。 不用敲命令、不用手动按 F12 抓 Cookie、不用装 Python —— 下载 → 登录 → 导出,三步搞定。
为什么选它
| 能力 | 传统命令行导出脚本 | 本工具 |
|---|---|---|
| 使用方式 | 纯命令行,需手工编辑配置文件 | ✅ 图形界面,点选即可 |
| 获取 Cookie | 手动 F12 复制,步骤繁琐易失效 | ✅ 自动拉起浏览器登录,扫码 / 账号密码 |
| 登录态 | 每次手动粘贴 | ✅ 自动保存,后续免密登录 |
| 富文本格式 | 常丢失(加粗、颜色、表格、代码块乱掉) | ✅ 内嵌 HTML 完整保留 |
| 图片 | 常需自建 / 配置图床 | ✅ 默认 base64 内嵌,单文件自包含 |
| 运行环境 | 必须装 Python 与一堆依赖 | ✅ 打包为可执行文件,免环境 |
| 多账号 | 不支持 | ✅ 账号一致性校验,防串号 |
| 平台 | 通常仅 Windows | ✅ Windows / macOS / Linux |

下载与安装(推荐普通用户)
到 Releases 下载对应平台的现成程序,无需安装 Python 环境:
| 平台 | 文件 | 使用方式 |
|---|---|---|
| Windows | YoudaoNoteExporter-Windows.exe |
双击运行 |
| macOS | YoudaoNoteExporter-macOS.zip |
解压后把 YoudaoNoteExporter.app 拖入「应用程序」 |
| Linux | YoudaoNoteExporter-Linux |
chmod +x 后运行 |
三步上手:
- 登录 —— 打开程序点「登录」,在弹出的浏览器里完成有道云笔记登录,Cookie 自动抓取(首次运行会自动下载匹配的浏览器驱动,默认已开启 npmmirror 加速下载,请保持联网)。
- 选笔记 —— 在目录树里勾选要导出的笔记 / 文件夹(可全选)。
- 导出 —— 选择本地保存目录,点击导出,完成后到该目录查看
.md文件。
Releases 中的安装包由仓库内
.github/workflows/build.yml自动构建:推送一个v*标签(例如v1.0.0),三平台产物会自动上传到 Release。
想从源码运行、参与开发或自行打包?见下方 快速开始(源码 / 开发模式) 与 打包为桌面应用。
更新日志
Caution
近期重大更新。
- 项目名称变更:项目名称正式改为 youdaonote-export-multiplatform(原 youdaonote-to-md),后续文档与发布统一使用新名称。
- 新增图形界面(UI):基于 flet 框架新增了可视化界面,现在用户可以直接通过图形化界面完成登录、选择笔记与导出操作,无需手工编辑配置文件。具体介绍详见「图形界面(GUI)」小节。
- 新增打包功能:支持将源码打包成独立可执行文件,方便分发;支持 Windows / macOS / Linux 三个平台。其中 Windows/Linux平台已测试通过,Mac平台待测,也欢迎用户自行测试并反馈。具体打包方式详见「打包为桌面应用(Windows / macOS / Linux)」小节。
- 重构代码结构:拆分了原有大文件,并增加了开发模式下的 log 功能。
功能特性
核心功能
- 图形化界面和命令行两套操作方式
- 按原目录结构批量导出所有有道云笔记到本地
- 笔记格式自动转换:XML / JSON / HTML → Markdown
- 增量导出:仅下载新增或修改的笔记,跳过未更新的文件
图片处理
- base64 内嵌模式(默认):图片以
data:image/png;base64,...格式嵌入 Markdown,无需外部图片文件 - 本地文件模式:图片下载到
images/目录,Markdown 中使用相对路径引用 - 有道云笔记图片链接自动下载并替换
file:///本地绝对路径引用自动清理- 图片文件名特殊字符自动清理(
(){}[]$~@%等),防止 Markdown 链接截断 - 可选上传图片到 SM.MS 图床
- 支持原笔记中富文本格式的导出:富文本格式以内嵌HTML标签的方式直接加入到导出的Markdown文件中,目前在edge浏览器插件Markdown Viewer Enhanced、语雀和Typroa上测试通过。
兼容性
- 兼容 Python 3.9+(已在 3.13 上验证通过)
- 兼容 Windows / macOS / Linux
- 修复 Windows 下
os.rename目标已存在导致.note残留的问题
前置条件
从源码运行或自行打包,本机需要先具备 Python 3.9+ 与 pip。 普通用户直接下载 Releases 里的现成程序即可,无需任何环境。
1. 安装 Python 3.9+
| 平台 | 安装命令 |
|---|---|
| Windows | 到 python.org 下载安装包,安装时务必勾选 Add python.exe to PATH(否则命令行找不到 python / pip) |
| macOS | brew install python(Homebrew)或 python.org 官方安装包 |
| Linux(Debian / Ubuntu) | sudo apt install python3 python3-venv |
| Linux(Fedora) | sudo dnf install python3 python3-pip |
| Linux(Arch) | sudo pacman -S python |
提示:Debian/Ubuntu 需带
python3-venv才能创建虚拟环境,详见下方「创建虚拟环境」。
安装后验证:
python3 --version # Windows 上为 python --version,应输出 3.9+
2. 安装 pip
Python 3.4+ 的官方安装包已自带 pip;若因精简安装或发行版拆分导致 pip 命令不可用,按平台补装:
# Windows:Python 自带 pip,缺失时用 ensurepip 修复
python -m ensurepip --upgrade
# macOS(Homebrew 的 python 自带 pip;缺失时)
python3 -m ensurepip --upgrade
# Linux
# Debian / Ubuntu:
sudo apt install python3-pip
# Fedora:
sudo dnf install python3-pip
# Arch(python 包已含 pip;缺失时):
sudo pacman -S python-pip
验证 pip 可用:
pip3 --version # Windows 上为 pip --version
创建虚拟环境
后续统一用虚拟环境隔离依赖,避免污染系统 Python。请在项目源码根目录(即包含 requirements.txt 的那一层)下创建并激活 venv:
# 先进入源码根目录
cd youdaonote-export-multiplatform
# Windows
python -m venv venv
venv\Scripts\activate
# macOS / Linux
python3 -m venv venv
source venv/bin/activate
激活成功后,命令行提示符前会出现 (venv),表示后续 pip 安装都只作用于该环境。
Ubuntu / Debian 创建虚拟环境报错
ensurepip is not available? 执行python3 -m venv venv若提示 "The virtual environment was not created successfully because ensurepip is not available",是因为 Debian/Ubuntu 把venv拆成了独立包,最小化安装没带python3-venv。解决办法就是补装它:sudo apt install python3-venv装好后重新
python3 -m venv venv即可。macOS 是否有同样问题? 一般没有。Homebrew 的
python(brew install python) 与 python.org 官方安装包都自带ensurepip和venv,python3 -m venv venv开箱即用。 只有用了被裁剪过的 Python 才可能缺ensurepip,此时用python3 -m ensurepip --upgrade即可修复(见上方「安装 pip」)。
快速开始(源码 / 开发模式)
1. 安装依赖
需要 Python 3.9+(推荐 3.11+)。已按上方「创建虚拟环境」创建并激活 venv 后,安装依赖:
# Windows(已激活 venv)
pip install -r requirements.txt
# macOS / Linux(已激活 venv)
pip3 install -r requirements.txt
依赖列表(requirements.txt):
| 依赖 | 版本要求 | 用途 |
|---|---|---|
| flet | ==1.0.4 | 图形界面(GUI)核心库;其自带的 flet 命令即打包用的 CLI |
| flet-desktop | ==1.0.4 | 桌面客户端(flet 核心包不含)。flet run 与 flet pack 都需要 |
| selenium | >=4.11 | 网页登录抓取 Cookie(GUI 登录页使用) |
| requests | >=2.32.0 | HTTP 请求(兼容 Python 3.13) |
| markdownify | ==0.5.1 | HTML 转 Markdown |
| Brotli | >=1.1.0 | 解压响应(兼容 Python 3.13) |
| win32-setctime | ==1.1.0 | Windows 下设置文件创建时间 |
2. 获取有道云笔记 Cookie
由于有道云笔记登录升级了图形验证码,脚本使用 Cookie 登录。
- 在浏览器中登录 有道云笔记
- 按
F12打开开发者工具 → Network 面板 - 找到任意请求,复制 Cookie 中的以下三个值:
YNOTE_CSTKYNOTE_LOGINYNOTE_SESS
也可安装浏览器插件 Cookie-copy 快速复制。
3. 配置 cookies.json
将获取的 Cookie 填入 cookies.json:
{
"cookies": [
["YNOTE_CSTK", "你的CSTK值", ".note.youdao.com", "/"],
["YNOTE_LOGIN", "你的LOGIN值", ".note.youdao.com", "/"],
["YNOTE_SESS", "你的SESS值", ".note.youdao.com", "/"]
]
}
4. 配置 config.json
{
"local_dir": "",
"ydnote_dir": "",
"smms_secret_token": "",
"is_relative_path": true,
"is_base64_image": true
}
配置项说明:
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
local_dir |
string | 本地存放导出文件的绝对路径,留空则导出到脚本目录下的 youdaonote/ |
"" |
ydnote_dir |
string | 指定导出的有道云笔记目录,留空则导出所有笔记。支持多级路径,用 / 分隔(也兼容 \),如 工作/2026/项目A |
"" |
smms_secret_token |
string | SM.MS 图床 Token,留空则不上传 | "" |
is_relative_path |
bool | 附件是否使用相对路径(base64 模式下图片不受影响) | true |
is_base64_image |
bool | 是否将图片以 base64 内嵌到 Markdown 中 | true |
5. 运行导出
# 激活虚拟环境后
python pull.py # Windows
python3 pull.py # macOS / Linux
导出完成后,所有笔记保存在 youdaonote/ 目录下(或你指定的 local_dir)。
6. 增量导出
再次运行同一命令即可。脚本根据笔记修改时间判断是否需要更新,仅下载新增或修改的笔记,不会覆盖本地已修改的文件。
7. 查看云端笔记列表(可选)
导出前想先确认云端有哪些笔记,或导出后想核对是否有遗漏,可以只拉取元信息、不下载笔记内容:
python tools/list_notes.py # 打印整棵目录树
python tools/list_notes.py 工作/2026 # 只看指定子目录(支持多级,兼容 \ 分隔)
python tools/list_notes.py --flat # 额外输出「id / 名称 / 创建时间 / 修改时间」扁平清单
- 只读操作,不会写入
youdaonote/ - 也是快速验证 Cookie 是否有效的手段:若提示
AUTHENTICATION_FAILURE,说明 Cookie 已过期,需重新获取 - 注意
get_dir_info_by_id的len=1000是写死的,单个文件夹条目超过 1000 条会被截断(脚本未做分页)
图形界面(GUI)
除命令行 pull.py 外,项目还提供了基于 flet 的图形界面(ui/main.py)。
无需手工编辑 cookies.json 与 config.json,按界面引导即可完成导出。
1. 开发模式下启动界面
在项目根目录执行:
flet run ui/main.py
无需 Flutter SDK,flet 自带预编译桌面客户端;首次运行会准备客户端(一次性操作)。 若要分发给别人使用,请用
build.py打包,详见「打包为桌面应用(Windows / macOS / Linux)」。
2. 三种登录方式
登录页只需填写有道云笔记邮箱账号(不支持手机号),程序会自动判断走哪条路径:
| 场景 | 行为 |
|---|---|
| 首次登录 / Cookie 已过期 | 本地没有该账号记录,或已保存的 Cookie 失效 → 自动转入网页登录 |
| 非首次登录 | 本地已存有有效 Cookie → 直接登录成功,无需任何额外操作 |
| 从 cookies.json 导入 | 点击「或从 cookies.json 导入」,选择命令行同样使用的 cookies.json 复用凭据 |
3. 首次登录:自动装驱动并打开浏览器
首次登录(或 Cookie 已过期)时,程序会自动完成以下动作:
- 检测浏览器:自动探测系统中已安装的 Microsoft Edge / Google Chrome / Firefox
- 下载驱动:自动下载与该浏览器版本匹配的驱动程序(默认走 npmmirror 镜像加速),
缓存到
~/.cache/selenium,只下载一次,之后复用 - 打开网页:调用该浏览器打开有道云笔记网页版(
https://note.youdao.com/web/), 供你手动完成登录
你在浏览器中登录成功后,程序会自动提取 YNOTE_CSTK / YNOTE_LOGIN / YNOTE_SESS 三个 Cookie
并关闭浏览器,无需手动复制任何内容。
若三种浏览器都没安装,会提示失败;此时可改用「从 cookies.json 导入」。 驱动下载与镜像加速详见「浏览器驱动与下载加速」。
4. 登录态自动保存,后续免密登录
首次登录成功后,Cookie 会按浏览器实际登录的账号写入本地数据库 accounts.db(SQLite,
位于可执行文件所在目录,详见「运行打包后的程序」)。
以后再使用时,只需输入正确的云笔记邮箱账号,即可自动登录,不必重复网页登录。
accounts.db保存的是真实登录凭据,请勿外传;仓库中已被.gitignore排除。
5. 账号一致性校验(防止越权查看)
登录时会通过接口读取 Cookie 对应的真实账号,与你输入的邮箱账号比对,不一致则阻止登录:
- 从 cookies.json 导入时:若两者不一致,直接阻止导入,并提示 「你输入的账号「X」与该 cookies 对应的账号「Y」不一致」
- 网页登录时:按浏览器中实际登录的账号保存,而不是你输入的账号, 从源头上避免账号错位
这一校验可避免利用他人 Cookie 查看他人云笔记的情况发生。
6. 笔记目录树与导出目录选择
登录后展示云端笔记的目录树:
- 可勾选单篇笔记,也可勾选整个文件夹(其下所有笔记都会被导出)
- 支持展开 / 收起,按需选择要导出的内容
- 点击「选择目录」可自由指定导出保存位置(不使用默认目录,完全由你决定)
7. 增量导出
与命令行一致,GUI 同样支持增量导出:只处理未导出过或内容已更新的笔记, 未发生变化的笔记自动跳过,显著节省时间。
8. 实时进度与统计
导出过程中实时显示:
- 进度条,以及「(已完成/总数) 当前笔记名」
- 逐条日志,用
导出:/更新:/跳过:区分每条笔记的处理结果 - 可随时点击「取消导出」中断(导出中关闭窗口也会触发取消)
- 完成后给出统计:新增 X,更新 Y,跳过 Z,失败 N,并列出失败笔记的明细
导出模式对比
base64 内嵌模式(推荐,默认启用)
图片直接以 data:image/png;base64,... 格式嵌入 Markdown 文本中。
适用场景:导入 ima、Notion 等云端知识库
优点:
- 每个 Markdown 文件完全自包含,不依赖外部图片文件
- 导入云端知识库后图片正常显示
- 不生成
images/目录,目录结构更简洁
缺点:
- 文件体积增大约 33%(base64 编码开销)
- 含大量图片的单个 Markdown 文件可能较大
本地文件模式(is_base64_image: false)
图片下载到各目录下的 images/ 文件夹,Markdown 中使用相对路径引用。
适用场景:使用 Typora、VS Code 等本地编辑器查看
优点:
- 文件体积小
- 本地编辑器预览正常
缺点:
- 导入云端知识库时图片无法显示(图片不会上传)
项目结构
youdaonote-export-multiplatform/
├── pull.py # 命令行主脚本入口
├── build.py # 打包脚本(flet pack / PyInstaller → 各平台桌面可执行程序)
├── config.json # 导出配置(含 Token,已被 .gitignore 排除)
├── config.example.json # 配置样例模板
├── cookies.json # 有道云笔记 Cookie(敏感信息,已被 .gitignore 排除)
├── accounts.db # GUI 账户 Cookie 本地库(SQLite,敏感信息,已被 .gitignore 排除)
├── requirements.txt # Python 运行时依赖(需 Python >= 3.9)
├── requirements-build.txt # 打包专用依赖(= requirements.txt + 锁定版 PyInstaller)
├── LICENSE # MIT 许可证
├── .gitignore # 排除 Cookie / 账户库 / 配置 / 导出目录 / 日志 / 打包产物等
├── .gitattributes # Git 换行符与文件属性配置
├── .github/ # GitHub Actions 工作流(三平台自动打包)
│ └── workflows/
│ └── build.yml # 推 tag / 手动触发:出 Windows / macOS / Linux 安装包并挂到 Release
├── README.md # 项目说明
├── YoudaoNoteExporter.spec # PyInstaller 打包配置(自动生成,已被 .gitignore 排除)
├── ui/ # 图形界面(flet),入口 ui/main.py
│ ├── main.py # GUI 入口:窗口配置与页面路由(login → tree → export)
│ ├── login_view.py # 登录页:cookies.json 导入 + Selenium 网页登录(含驱动镜像加速)
│ ├── tree_view.py # 云端笔记目录树:勾选要导出的笔记 / 文件夹
│ ├── export_view.py # 导出页:选择目标目录、进度显示、取消导出
│ └── db.py # 账户 Cookie 本地持久化(SQLite accounts.db)
├── core/ # 核心模块
│ ├── api.py # 有道云笔记 API 封装(登录、获取目录、下载文件)
│ ├── exporter.py # 导出引擎:登录 / 目录树 / 导出 / 进度回调(CLI 与 GUI 共用)
│ ├── covert/ # 笔记格式转换包(XML/JSON/HTML → Markdown)
│ │ ├── __init__.py # 门面:导出 YoudaoNoteConvert / XmlElementConvert / JsonConvert
│ │ ├── convert.py # 三个转换入口(HTML / XML / JSON → Markdown)
│ │ ├── xml_convert.py # XML 格式 note 的标签转换规则
│ │ ├── json_convert.py # JSON 格式 note 的字段转换规则(含白板扩展类型)
│ │ ├── indent.py # 缩进还原(原生缩进字段 + 启发式层级恢复)
│ │ ├── postprocess.py # Markdown 生成后的统一后处理链
│ │ ├── style.py # 共享样式工具(span 扁平化、颜色规范化)
│ │ └── util.py # 公共常量与小工具
│ ├── image.py # 图片/附件处理(base64 内嵌、本地下载、文件名清理)
│ ├── whiteboard_render.py # 白板渲染(excalidraw / drawio-ynote / mindmap → SVG)
│ ├── common.py # 通用工具函数(项目根目录定位)
│ └── log.py # 日志配置(输出到文件和终端)
├── tools/ # 维护工具
│ ├── install-linux.sh # Linux 安装脚本(可执行文件 / .desktop / 图标 → 标准位置)
| ├── install-release.sh # Linux下Release发行包的一键安装脚本
│ ├── list_notes.py # 列出云端笔记目录树(只读元信息,不下载内容)
│ ├── make_baseline.py # golden 基线工具(校验转换输出是否变化)
│ ├── dump_login_headers.py # 登录请求头抓取(排查用)
│ ├── probe_user_endpoints.py # 用户信息接口探测(排查用)
│ └── baseline/ # 基线输出(自动生成,已被 .gitignore 排除)
├── test/ # 测试脚本与样本
│ ├── test.py # 单元测试
│ ├── test_whiteboard_render.py # 白板渲染测试(72 项)
│ ├── test_whiteboard_covert.py # 白板转换测试(42 项)
│ ├── test_whiteboard_regression.py # 回归测试:白板接入不影响既有转换流程
│ ├── probe_whiteboard_render.py # 白板渲染探测脚本
│ ├── test.note # XML 格式笔记样本(合成数据)
│ ├── test.json # JSON 格式笔记样本(合成数据)
│ ├── test-convert.json # JSON 转换样本(合成数据)
│ ├── Zygote进程的作用.note # 白板端到端样本(资源 URL 已脱敏为 example.com)
│ └── whiteboard_samples/ # 白板二进制资源样本
├── other/ # 打包图标资源(icon.ico / icon.icns / icon.png 及 Linux 用的 icons/hicolor 多尺寸图标树)
├── logs/ # 运行日志(自动生成)
└── youdaonote/ # 导出目录(自动生成,已被 .gitignore 排除)
说明:
- 项目有两套入口:命令行
pull.py(见「快速开始」)与图形界面ui/main.py(flet)。 开发时直接运行 GUI:在项目根目录执行flet run ui/main.py(无需 Flutter SDK,flet 自带预编译桌面客户端); 分发给用户则用build.py打包,详见「打包为桌面应用(Windows / macOS / Linux)」。 core/covert/由原先 2900+ 行的单文件covert.py拆分而来,__init__.py作为稳定门面, 保持from core.covert import YoudaoNoteConvert等既有导入方式不变。- 改动转换逻辑后,可用 golden 基线校验输出是否变化(当前覆盖 4 个样本,含 XML / JSON 路径):
python tools/make_baseline.py # 重新采集基线(改动前执行)
python tools/make_baseline.py --compare # 与基线逐字节比对(改动后执行)
导出后目录结构示例
youdaonote/
├── 笔记文件夹1/
│ ├── 笔记A.md # base64 图片内嵌在文件中
│ ├── 笔记B.md
│ └── 子文件夹/
│ └── 笔记C.md
├── 笔记文件夹2/
│ ├── 笔记D.md
│ └── attachments/ # 附件目录(仅当笔记包含附件时生成)
│ └── document.pdf
└── 根目录笔记.md
打包为桌面应用(Windows / macOS / Linux)
除命令行 pull.py 外,项目还提供了基于 flet 的图形界面(ui/main.py)。
用 build.py(封装 flet pack,底层是 PyInstaller)可将其打包成各平台的独立可执行程序,
目标机器无需安装 Python。
安装打包依赖
Python 与 pip 的安装见上方「前置条件」;虚拟环境的创建与激活见上方「创建虚拟环境」, 无需重建——
requirements-build.txt已内含requirements.txt,在同一个已激活的 venv 里 直接补装打包依赖即可:
# Windows(已激活 venv)
pip install -r requirements-build.txt
# macOS / Linux(已激活 venv)
pip3 install -r requirements-build.txt
PyInstaller 是构建期依赖,因此放在单独的
requirements-build.txt,不污染运行时依赖: 只想运行源码 / GUI 的用户装requirements.txt即可。 未安装时flet pack会报Please install PyInstaller module to use flet pack command。 Windows 下 PyInstaller 会自动带上pefile、pywin32-ctypes,macOS 带macholib, 无需额外处理;启用自定义图标时flet pack会用到其中的pefile。
必须在目标平台本机打包:Windows 打 exe、macOS 打
.app、Linux 打可执行文件。build.py已内置--collect-data selenium,会把对应平台的selenium-manager二进制一并打进包; 跨平台打包可能导致该二进制缺少可执行权限,进而使浏览器驱动下载失败。
通用打包命令
python build.py # 打包为单文件可执行程序(默认)
python build.py --onedir # 单目录模式(仅 Windows 有效,便于排查依赖问题)
python build.py --distpath out # 指定产物输出目录(默认 ./dist)
产物默认输出到 dist/:
| 平台 | 产物 |
|---|---|
| Windows | dist/YoudaoNoteExporter.exe |
| macOS | dist/YoudaoNoteExporter.app |
| Linux | dist/YoudaoNoteExporter(可执行文件) |
Windows
- 安装 Python 3.9+(安装时勾选 "Add python.exe to PATH")
- 按上文创建虚拟环境并安装依赖
- 执行打包:
python build.py - 双击
dist\YoudaoNoteExporter.exe运行 - 自定义程序图标:把图标放到
other\icon.ico后重新打包 (build.py检测到文件存在才会自动带上,否则使用默认图标)
首次运行需联网下载浏览器驱动,见下方「浏览器驱动与下载加速」。 若被杀毒软件误报,可改用
python build.py --onedir生成单目录版本并加入白名单。
macOS
- 安装 Python 3.9+(
brew install python或官网安装包) - 创建虚拟环境并安装依赖
- 执行打包:
python3 build.py,产物为dist/YoudaoNoteExporter.app - 自定义程序图标:放到
other/icon.icns后重新打包 - Apple Silicon(M1/M2/M3)请在 arm64 环境的 Python 下打包,否则产物会以 Rosetta 转译运行
关于 macOS 未签名 / 未公证
本项目的打包产物未做代码签名,也未提交 Apple 公证(Notarization)。完整签名需要付费的
Apple Developer 账号(codesign --sign + notarytool submit),因此当前分发的 .app 在
首次打开时会被 Gatekeeper 拦截。两种解除方式:
方式一:右键打开(适合本地打包产物)
- 在「访达(Finder)」里找到
YoudaoNoteExporter.app,不要双击,而是右键(或按住 Control 单击) - 在弹出菜单中选择「打开」
- 系统会弹出「无法验证开发者」的警告,点击「打开」即可
- 之后该 app 已被记录为可信,后续双击即可正常启动
若右键菜单没有「打开」项,也可走系统设置:苹果菜单 →「系统设置 → 隐私与安全性」, 在「安全性」区域会出现本次拦截记录,点击「仍要打开」。
方式二:移除 quarantine 属性(适合从 Release 下载的压缩包)
从浏览器下载并解压的 .app 会被打上 quarantine 标记(com.apple.quarantine),
右键打开也常被拦。在终端执行以下命令清除该标记即可正常打开:
# 解压后进入 app 所在目录
xattr -cr YoudaoNoteExporter.app
# 若仍提示已损坏,可再显式删除 quarantine 属性:
sudo xattr -rd com.apple.quarantine YoudaoNoteExporter.app
说明:以上只是解除系统拦截,并不改变"未签名"的本质。若要彻底免提示,需自行用 Apple Developer 证书签名并公证(不在本项目的自动构建范围内)。
Linux
- 安装 Python 3.9+ 与 venv 模块(Debian/Ubuntu:
sudo apt install python3 python3-venv) - 创建虚拟环境并安装依赖
- 执行打包:
python3 build.py,产物为dist/YoudaoNoteExporter - 赋予可执行权限并运行:
chmod +x dist/YoudaoNoteExporter
./dist/YoudaoNoteExporter
- 自定义图标:Linux 只识别
.png,放到other/icon.png后重新打包。 打包时build.py会在dist/下自动生成YoudaoNoteExporter.desktop启动器 (含图标、分类等元数据),已随产物交付;把它和可执行文件放在同一目录, 即可在桌面环境添加到启动器 / 程序菜单。
在 Linux 上安装(图标与启动器)
只构建、不安装的话,图标不会显示——这是 Linux 图标机制与 Windows/macOS 的根本差异:
| 差异点 | Windows / macOS | Linux |
|---|---|---|
| 图标存放 | 嵌进 exe / .app |
不嵌进可执行文件,单独放在 hicolor 主题目录 |
.desktop 的 Icon= |
— | 写的是图标名,桌面环境只从主题目录按尺寸查取 |
.desktop 生效位置 |
— | 只扫描 applications/ 目录,放在程序旁边不会被扫到 |
所以 dist/ 里的产物直接双击能跑,但图标是占位图、也不会出现在应用菜单。
要让图标正常显示并出现在菜单,需要把三者分别装到标准位置。
方式一:用安装脚本(推荐)
python3 build.py # 先构建
bash tools/install-linux.sh # 默认取 ./dist,装到 ~/.local(无需 root)
脚本会把三样东西装到正确位置:可执行文件 → ~/.local/bin/、
.desktop → ~/.local/share/applications/、图标 → ~/.local/share/icons/hicolor/,
并刷新图标缓存与 desktop 数据库。之后即可在应用菜单看到带图标的 YoudaoNoteExporter。
# 其它用法
sudo PREFIX=/usr/local bash tools/install-linux.sh # 系统级安装(所有用户)
bash tools/install-linux.sh /path/to/dist # 指定产物目录
bash tools/install-linux.sh --uninstall # 卸载
方式二:从 Release 产物一键安装(推荐手动安装)
从 Release 下载以下 4 个文件,放到同一个目录,然后在该目录执行安装脚本:
YoudaoNoteExporter-Linux(可执行程序)YoudaoNoteExporter.desktop(启动器)icons-hicolor.tar.gz(hicolor 多尺寸图标树)install.sh(官方安装脚本,本身也是 Release 产物)
bash install.sh
脚本会自动完成:把可执行文件装到 ~/.local/bin/、把图标装进 hicolor 主题
(经 xdg-icon-resource,自动建 index.theme 并刷新缓存)、把启动器装到
~/.local/share/applications/ 并把 Exec / Icon 改写为本机绝对路径、最后刷新启动器数据库。
安装完成后若应用菜单未立即出现,注销重新登录即可。
说明:
- 脚本默认按当前用户安装(路径在
~/.local)。install.sh与上面三件套一起作为 Release 产物发布;它和tools/install-linux.sh(从本地dist/构建产物安装)用途不同。- 系统级(所有用户)安装请手动修改
install.sh脚本,把路径换到/usr/local并加sudo。
图标源文件与生成脚本见
other/:other/icon.png(1024 源图)、other/icons/hicolor/(各尺寸)、other/make_icon.py(重新生成)。
关于 Dock 图标
装好上面的启动器后,应用菜单里的图标会正常显示。但运行中的窗口要在 Dock / 任务栏 也显示图标,靠的是
.desktop的StartupWMClass与窗口真实身份匹配;同时.desktop的Icon=必须能按图标名查到已安装图标——若只拷了.desktop却没把图标装进 hicolor 主题 (缺index.theme/ 缓存未刷新),Dock 仍会回退成默认图标,请用「方式二」的xdg-icon-resource方式安装。注意:flet 的预编译桌面客户端把应用 ID 固化为
com.appveyor.flet,GTK 据此派生 X11 的WM_CLASS与 Wayland 的app_id;实测设置FLET_APP_ID环境变量并不能 改变它(客户端在内部覆盖了prgname)。因此build.py里StartupWMClass直接写这个 真实值(常量WM_CLASS),Dock / 任务栏才能把窗口关联到本条目、显示正确图标。核对实际值:
# X11 会话 xprop -name "YoudaoNoteExporter" WM_CLASS # Wayland 会话(xprop 对 Wayland 窗口无效,改用这个) ./YoudaoNoteExporter 2>&1 | head # 看 GLib 告警前缀 **(xxx:PID): WARNING **若 flet 将来改变了这个固化值,构建时覆盖即可,无需改代码:
YOUDAO_WM_CLASS=<新值> python3 build.py另外:GNOME 本来就不在标题栏显示应用图标(只显示窗口标题文字),这是设计如此; KDE / XFCE / MATE 才会在标题栏显示图标。
Linux 运行时依赖(GTK3 等系统库)
flet 桌面版基于 Flutter,运行需要 GTK3 等系统库(由操作系统提供,不打包进二进制)。 这些库在已安装桌面环境的 Linux 上通常已自带(GNOME / XFCE / Cinnamon / MATE 等都依赖 GTK3), 一般无需额外操作。仅当在无桌面的精简系统上运行时,才需要手动补齐:
发行版 安装命令 Debian / Ubuntu / Mint sudo apt install -y libgtk-3-0 libgthread-3-0 libnotify4Fedora / RHEL / CentOS sudo dnf install -y gtk3 glib2 libnotifyArch / Manjaro sudo pacman -S gtk3 glib2 libnotifyopenSUSE sudo zypper install -y gtk3 glib2 libnotify说明:
- 核心三件套
gtk3 / glib2 / libnotify在所有主流桌面发行版中名字稳定、均可用。- 旧的
libgconf-2-4(GConf)已被GSettings/dconf取代,现代 flet 不再依赖; Fedora 36+、Arch 等已移除此包,故未列入上表。若启动罕见报错提示缺少libgconf, 再按对应发行版的额外源补装即可。- Alpine 及 musl 系发行版暂不兼容:flet 二进制基于 glibc 构建,musl 环境下无法运行。
- 若启动提示缺少
.so,按上表用包管理器安装对应运行时即可。
运行打包后的程序
建议先新建一个专用文件夹,把可执行文件放进去再运行,不要直接双击 dist 里的产物,
也不要把 exe 丢在桌面或 C:\Program Files\ 这类系统目录。
原因是程序会在可执行文件所在目录生成运行时数据文件:
| 文件 / 目录 | 说明 |
|---|---|
accounts.db |
SQLite 数据库,保存登录 Cookie(YNOTE_CSTK / YNOTE_LOGIN / YNOTE_SESS) |
logs/ |
运行日志(pull-年月日-时分秒.log) |
把这些文件和 exe 放在同一个独立目录里,备份、迁移、整体删除卸载都更方便。
# Windows:新建目录 → 移入 → 运行
mkdir D:\Tools\YoudaoNoteExporter
move dist\YoudaoNoteExporter.exe D:\Tools\YoudaoNoteExporter\
D:\Tools\YoudaoNoteExporter\YoudaoNoteExporter.exe
# macOS
mkdir -p ~/Applications/YoudaoNoteExporter
cp -R dist/YoudaoNoteExporter.app ~/Applications/YoudaoNoteExporter/
open ~/Applications/YoudaoNoteExporter/YoudaoNoteExporter.app
# Linux
mkdir -p ~/opt/youdaonote-export
cp dist/YoudaoNoteExporter ~/opt/youdaonote-export/
chmod +x ~/opt/youdaonote-export/YoudaoNoteExporter
~/opt/youdaonote-export/YoudaoNoteExporter
注意事项
accounts.db含真实登录凭据,请勿外传;仓库中它已被.gitignore排除。 换机器或卸载时,直接删除整个目录即可清除登录态。若 exe 所在目录不可写(例如放在
C:\Program Files\),程序会自动改用用户数据目录: Windows%APPDATA%\youdaonote-export-multiplatform、macOS~/Library/Application Support/youdaonote-export-multiplatform、 Linux~/.local/share/youdaonote-export-multiplatform。想显式指定数据目录,可设置环境变量
YOUDAONOTE_DATA_DIR(便携部署时很有用):set YOUDAONOTE_DATA_DIR=D:\Tools\YoudaoNoteExporter\data # Windows cmd $env:YOUDAONOTE_DATA_DIR="D:\Tools\YoudaoNoteExporter\data" # Windows PowerShell export YOUDAONOTE_DATA_DIR=~/opt/youdaonote-export/data # macOS / Linux首次运行会联网下载浏览器驱动并缓存到
~/.cache/selenium,详见下一节。
浏览器驱动与下载加速
GUI 登录页通过 Selenium 打开真实浏览器完成登录,因此目标机器需安装 Microsoft Edge / Google Chrome / Firefox 之一。
- 对应驱动由 Selenium Manager 首次运行时联网下载,缓存到
~/.cache/selenium,只下载一次并复用 - 默认已开启 npmmirror 镜像加速(Edge / Chrome),一般无需任何配置
- 关闭加速、回退官方源:设置环境变量
YOUDAO_DRIVER_MIRROR=off - 使用自定义镜像:
YOUDAO_DRIVER_MIRROR=<镜像根地址> - Firefox 的 geckodriver 在 npmmirror 上只有
.zip(Selenium Manager 默认请求.tar.gz), 故 Firefox 不走镜像、回退官方源 - Chrome 仅在 npmmirror 已镜像该 Chrome 版本时才走加速;若某版本缺失会下载失败,
此时可用
YOUDAO_DRIVER_MIRROR=off回退官方源
打包常见问题
-
FileNotFoundError: [Errno 2] No such file or directory: 'flet': 运行build.py时找不到 flet 命令行。flet 命令由flet包自身提供 (入口点flet = flet.cli:main),报这个错通常说明脚本不在当前 PATH:- 是否激活了安装依赖的虚拟环境:
source venv/bin/activate - 运行
build.py的python3与安装依赖的pip3是否是同一个环境 - 依赖是否装全:打包用
pip3 install -r requirements-build.txt(只运行则pip3 install -r requirements.txt) (注意 flet 1.x 的桌面客户端在独立包flet-desktop,flet run与flet pack都需要)
为降低环境差异带来的影响,
build.py已内置三级回退:PATH 上的flet→ 当前解释器环境(sys.prefix)里的flet脚本 → 直接用当前解释器执行flet.cli:main。 只有三者都不可用(即当前 python 根本没装 flet)时才会报错退出。 - 是否激活了安装依赖的虚拟环境:
-
打包后提示找不到 selenium-manager / 无法下载驱动:确认是在目标平台本机打包的;
build.py已处理该二进制的打包,跨平台打包会导致权限异常 -
杀毒软件报毒:PyInstaller 单文件模式常见误报,改用
--onedir或添加信任 -
产物体积较大:包含 Python 解释器与 flet 运行时,属正常现象
常见问题
Cookie 过期 / 登录失败
Cookie 有有效期(通常数天到数周),过期后需重新获取并更新 cookies.json。如果出现 Cookies 可能已过期 提示,请重新登录有道云笔记网页版并获取最新 Cookie。
最快的验证方式是跑一次 python tools/list_notes.py:只要能打印出目录树就说明 Cookie 有效。
需要注意,Cookie 失效时有道不会返回 401,也不会抛异常,而是返回 HTTP 500 且响应体为
{"scope":"SECURITY","error":"207","message":"Message[AUTHENTICATION_FAILURE]: User token must be authenticated."}。
因此脚本若报「获取根目录失败」或「接口返回中没有 entries 字段」,优先怀疑 Cookie 已过期。
注意:同一响应也可能由接口频控等偶发原因触发(实测中曾出现过一次失败、稍后重试即恢复正常), 所以遇到该报错建议先原样重试一次;若持续失败,再重新登录获取 Cookie。
导出中途中断
直接重新运行脚本即可。增量同步机制会跳过已下载且未更新的笔记,不会重复下载。
部分笔记转换失败
极少数旧格式笔记(2017 年以前新建的 HTML 格式)可能转换失败,脚本会跳过并继续处理后续笔记,不会中断。查看 logs/ 目录下的日志文件获取详细信息。
图片无法显示
- 导入云端知识库后图片不显示:确保
is_base64_image设置为true - 本地编辑器中图片不显示:使用
is_base64_image: false模式重新导出
Windows 下 .note 文件残留
已在重构版本中修复。如果使用旧版本遇到此问题,手动删除 .note 文件即可,.md 文件已正常生成。
工作原理
- 读取
cookies.json中的 Cookie,通过requests.Session模拟浏览器登录有道云笔记 - 调用有道云笔记 API 递归遍历目录树,获取所有笔记的文件 ID 和元信息
- 逐个下载笔记文件,根据文件内容判断格式(XML / JSON / HTML / Markdown)
- 将 XML / JSON / HTML 格式笔记转换为 Markdown
- 扫描 Markdown 中的有道云笔记图片链接,下载图片并替换:
is_base64_image=true:图片编码为 base64 data URI 内嵌is_base64_image=false:图片保存到本地images/目录,替换为相对路径
- 清理
file:///绝对路径引用,清理图片文件名特殊字符 - 设置本地文件的创建时间和修改时间为有道云笔记中的时间
技术细节
笔记类型识别
| 有道云笔记格式 | 识别方式 | 转换目标 |
|---|---|---|
.md |
文件后缀 | 无需转换 |
.note (XML) |
内容以 <?xml 开头 |
XML → Markdown |
.note (JSON) |
内容以 {" 开头 |
JSON → Markdown |
.note (HTML) |
XML 解析失败时回退 | HTML → Markdown |
| 其他 | 文件后缀 | 原样保存 |
图片文件名清理
有道云笔记中部分图片文件名包含 )、(、[、] 等特殊字符,会导致 Markdown 链接  被提前截断。_sanitize_filename() 方法将 (){}[]$~@%\^等字符替换为_`,确保链接完整性。
Windows 兼容性修复
Windows 下 os.rename() 在目标文件已存在时会抛出 FileExistsError,导致 .note 临时文件残留。修复方案:在 os.rename() 前先检查目标是否存在,若存在则先 os.remove() 再 os.rename()。
许可证
MIT License - Copyright (c) 2026 thinksmart-nicholas