用 Notion API 做完整备份:分页、关联截断和文件链接过期这几个坑

举报
yd_286747025 发表于 2026/11/08 18:06:54 2026/11/08
【摘要】 Notion 里的东西越攒越多,我一直担心哪天账号或服务出问题,数据就没了。于是写了个脚本,通过官方 API 把页面、数据库、附件全部导出成 Markdown 加原始 JSON。过程中踩了几个很容易让备份“看起来成功、实际缺数据”的坑,记录一下。 一、准备在 Notion 的「我的集成」里新建一个内部集成,拿到密钥(只放环境变量,别写进代码),然后在需要备份的页面上点「连接」,把集成加进去。...

Notion 里的东西越攒越多,我一直担心哪天账号或服务出问题,数据就没了。于是写了个脚本,通过官方 API 把页面、数据库、附件全部导出成 Markdown 加原始 JSON。过程中踩了几个很容易让备份“看起来成功、实际缺数据”的坑,记录一下。

一、准备

在 Notion 的「我的集成」里新建一个内部集成,拿到密钥(只放环境变量,别写进代码),然后在需要备份的页面上点「连接」,把集成加进去。没有加连接的页面,API 是看不到的。

export NOTION_TOKEN=你的密钥

二、先搞清楚备份要拿什么

  1. 页面和数据库行:用 search 接口遍历。
  2. 页面正文:块(block)是树状的,需要递归取子块。
  3. 附件和图片:Notion 返回的是带签名的临时链接。
  4. 关联(relation)属性:指向其他页面。

三、坑 1:所有列表接口都要分页

search、查询数据库、取子块,每次最多返回 100 条,结果里有 has_more 和 next_cursor。只取第一页是最常见的漏数据原因。

def fetch_all(call, **kw):
    out, cursor = [], None
    while True:
        r = call(start_cursor=cursor, page_size=100, **kw) if cursor else call(page_size=100, **kw)
        out += r["results"]
        if not r.get("has_more"):
            return out
        cursor = r["next_cursor"]

四、坑 2:关联属性超过 25 个会被截断

这个最隐蔽。页面对象里的 relation 属性,最多只直接给 25 个关联,多了会带一个 has_more 标记。要拿全,需要单独调用“获取页面属性”的接口,用属性 id 分页取:

GET /v1/pages/{page_id}/properties/{property_id}

我的数据里有些行关联了几十个页面,一开始导出的条数对不上,就是卡在这里。同理,rollup、people 等属性也可能有类似限制,统一走属性接口最稳。

五、坑 3:文件链接一小时左右就过期

API 给的文件地址带签名,过一段时间就失效。如果先把整个工作区的结构抓完再回头下载附件,后面的文件会 403。我的做法是:每取到一个页面的块,就立刻把里面的文件下载到本地,再把 Markdown 里的链接改成相对路径。

六、坑 4:别吞掉错误

请求超时、限流(429)、权限不足,都会让某些页面取不到。我加了三件事:每个请求设置超时;遇到 429 按 Retry-After 等待后重试;失败的页面写进一个错误清单,最后在报告里列出来,而不是默默跳过。

七、验证

备份完成后做对账:

  1. 用 API 统计的页面数、块数、文件数,和本地落盘的数量逐项比对;
  2. 随机抽几个页面,对比 Notion 里的显示;
  3. 保留一份原始 JSON,Markdown 转换有损时还能回头查。

我最后一次完整跑下来,页面、块、附件三项数量都能一一对上。

八、小结

备份最怕的是“以为备好了”。分页、关联截断、链接过期、静默错误,这四点处理好,结果才可信。另外要注意,评论需要在集成里单独勾选读取评论的权限,否则评论不会出现在备份里。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。