来源:
notes/documents/01_flomo_笔记全量结构化导出到本地.mdflomo 笔记全量结构化导出到本地
结论
2026-09-26 完成 flomo 采集源的首批全量导出:513 条 memo、32 个标签、约 14.7 万字、32 个附件(10.3 MB),
结构化落在 exports/flomo/,工具是零依赖的 scripts/flomo_export.py。
重跑 python3 scripts/flomo_export.py sync 即可全量刷新。
关键突破:登录链路
网页版 v.flomoapp.com 的登录请求发往 flomoapp.com/api/v1/user/web/login_by_email。
实测该路由对数据中心 IP 无条件返回 429:本机直连,以及香港、日本、新加坡、土耳其、美国五个代理出口,
配上真实 Chrome UA、有效签名、完整 device-id、无头与有头 Chromium,全部 429。
同源策略下这条请求还要走跨域预检,预检同样被 429 挡掉,所以「用浏览器登录」这条路走不通。
可用的是移动端同源路由 POST /api/v1/user/login_by_email(注意没有 /web/ 这一段):
- 该路由不返回 429,按
timestamp→api_key→sign逐项校验,报错信息明确,可以逐步试出来; sign算法就在网页 bundle 的prepareParams/_getSign里:参数按 key 排序、空值跳过、 数组展开成k[]=v,拼成k=v&…后去掉末尾&,追加固定盐dbbc3dd73364b4084c3a69346e0ce2b2取 md5;- 用浏览器真实请求体反向校验,算法输出与页面生成的签名逐位一致;
- 登录返回
access_token(Bearer 用)与api_token,账号为 PRO。
数据读取
- 接口
GET /api/v1/memo/updated/,limit上限 500; - 翻页游标
latest_updated_at必须是整型 unix 时间戳,配合latest_slug; 传字符串(如2026-09-05 23:13:13)会被忽略并从头返回,额外传tz会 500; - 字段:
content(HTML)、tags(字符串数组,多级标签用/分隔)、created_at/updated_at、source(android / wechat / web / ios / incoming_webhook)、files(图片与录音,签名 URL 数天后过期); - 513 条的时间跨度是 2024-11-17 至 2026-09-26,其中 15 条是纯图片、无正文。
落盘结构
exports/flomo/:
memos.json:全量结构化数据(纯文本 + Markdown + 标签 + 链接 + 附件索引)memos.csv:表格视图,方便导入其他工具memos/YYYY/YYYY-MM-DD_HHMM_slug.md:单条笔记,带 YAML 元信息by-tag/、by-month/:标签与月度索引attachments/:图片与录音,扩展名按文件头嗅探(微信来源的图片path没有后缀)index.md:总览,含数量、时间跨度、逐年逐月、标签词频memos-raw.json:接口原始返回,保留用于离线重跑;其中附件的签名 URL 数天后失效
边界与风险
- 附件是 OSS 签名地址,过期后需要重新拉取,本地副本不受影响;
- 访问令牌缓存在
~/.flomo-token.json(权限 600),没有写进仓库; - 本次是快照导出,不是增量同步;flomo 仍然只是采集源,没有成为本地事实源;
- 尚未接入个人助理的收件箱流程,也没有同步到飞书 Base;
- 顺带修正《flomo 整合进个人助理方案》里「公开 API 不适合稳定批量读取历史 memo」的判断: 官方移动端接口可以稳定读取全量 memo,只是网页端登录路由被风控挡住。
下一步
- 决定是否按方案笔记建立「flomo 收件箱」表,把这 513 条按处理状态投影到飞书 Base;
- 要做增量的话,以
memos.json里的updated_at为窗口起点,配一个 systemd timer; - 若之后仍需要浏览器自动化:本机已安装 Playwright + Chromium(
~/.cache/ms-playwright), 但 flomo 网页登录路由的 429 说明这类站点不适合用服务器 IP 走浏览器登录。