首页/数据/数据工程与 ETL 速查/API 增量拉取与分页
管道基础52 条

API 增量拉取与分页

第三方 API 采集要处理三件事:增量参数(时间戳或游标)、分页方式(page/offset 或 cursor)、失败重试与限流退避。

API 拉取型管道的三个难点

从第三方 API 采集数据时,真正的难点不在解析 JSON,而在三件事:怎么确定「新数据」的边界、怎么翻页取全、出错后怎么续上。增量参数决定从哪条开始拉,分页方式决定一次能取多少,重试与退避决定失败的批次能不能自动补回来。三者任一做错,表现通常都是「任务显示成功,但数据缺了一段」。

基本信息

增量方式updated_after 时间戳、since_id、cursor 游标
分页方式offset/page 或 next_cursor,后者对数据变化更稳
可靠性把请求游标落盘,失败从游标续拉
限流应对识别 429 与 Retry-After,做指数退避

典型使用场景

  • 电商平台订单与退款接口按小时增量同步到明细层
  • CRM、客服系统接口定期拉取客户与工单变更
  • 广告投放平台报表接口按天拉取消耗数据,用于成本分摊
  • SaaS 工具开放 API 拉取用户行为日志,补充埋点数据
  • 对账场景拉取支付渠道流水,要求严格不重不漏

时间戳增量 + 游标续拉

时间戳增量 + 游标续拉
STATE=/data/etl/state/orders.cursor           # 保存上次拉取到的游标
TOKEN=$(cat /etc/dataops/api_token)           # 令牌放权限受限文件,不要写进命令行
SINCE=$(cat $STATE 2>/dev/null || date -d '1 day ago' -Iseconds)  # 首次运行回溯一天
NEXT=""
while :; do
  RESP=$(curl -s -H "Authorization: Bearer $TOKEN" \
    "https://api.example.com/v1/orders?updated_after=$SINCE&cursor=$NEXT&limit=200")
  echo "$RESP" | jq -r '.data[] | [.id,.updated_at,.amount] | @tsv' >> /data/etl/orders.tsv
  NEXT=$(echo "$RESP" | jq -r '.next_cursor // empty')   # 取下一页游标
  [ -z "$NEXT" ] && break                                # 没有下一页就结束本轮
  echo "$NEXT" > $STATE                                  # 每页落一次状态,断点可续
done

增量与分页方式对比

方式行为优点坑点
offset/page按页码偏移翻页实现简单期间有增删会漏取或重复
cursor 游标按服务端游标翻页数据变化时依然稳定游标有效期短,需及时使用
时间戳区间按 updated_after 拉取天然可续跑同秒边界数据可能漏或跳
本地全量差分拉全量后本地比对口径最准量大且慢,容易触发限流
要真正做到不重不漏,靠的是主键去重加上取数窗口重叠:每次从上次水位往前回溯几分钟重叠区间,再配合目标表 upsert,比追求精确的分区边界更可靠,也能兜住源端补数。
令牌放环境变量文件并限制权限,不要直接写在命令行参数里——shell 历史、进程列表和日志都会留下明文凭证。

易错点

  • 只按 updated_at 增量而不做重叠窗口,边界秒级数据会永久丢失
  • 忽略分页游标有效期,慢速翻页到后面时接口已换批,中间出现整页缺失
  • 对 429 只做立即重试不做退避,把限流升级为封禁,整条链路停摆
  • 拉取水位只存在内存里,进程重启后从头开始,产生大量重复与对账差异

数据来源与参考

  • 行业通用 API 分页与增量拉取模式
  • RFC 8288 Web Linking 中游标分页相关约定
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌