站内精选

一句话结论

让 AI 按契约、主干、重试、日志、定时五步生成脚本,配 cron 每天自动拉数,失败会自己退避重试。

这篇解决什么问题

每天要从第三方平台导一份增量数据到自己库里,接口偶尔超时、偶尔限流,手工导表既占时间又容易漏天。

适用:手里有接口文档和 token,能在一台常驻机器上跑 Python。不适用:对方只给网页后台不给接口,或者数据要求分钟级实时。

开始前要准备什么

  • 一台常驻 Linux 机器或云主机,1 核 1G 够用,能访问外网
  • Python 3.9 以上,只装 requests,其余用标准库
  • 第三方平台的 API 文档,认证、分页、错误码三段最关键
  • AI 工具:DeepSeek 网页版日常够用,有免费额度;改代码我用 Cursor
  • 预计耗时:从零到跑通通常 1~2 小时,熟接口的话 40 分钟上下

具体怎么做

第 1 步 · 把接口文档压成一页契约

别急着让它写代码。先把文档里认证、分页、错误码三段贴进去,要一份摘要,后面每一步都拿它当上下文。这一步偷懒,后面字段名会来回改。

你是接口集成工程师。下面是一家第三方数据平台的 API 文档片段(化名:云雀广告平台)。请提炼一份“接口契约摘要”,供后续写拉取脚本用,包含:1. 认证方式、token 有效期、刷新方式;2. 主查询接口路径、必填参数、分页参数名与单页上限;3. 返回体里数据数组的字段名、时间字段格式与时区;4. 限流规则(QPS、每日调用上限)和超限时的返回码;5. 你判断文档没写清、需要我确认的 3 个点。输出用 Markdown 表格加简短说明,不要写代码。文档片段如下:【把认证、分页、错误码三段贴在这里】

预期产出:一页契约摘要,后面所有提示词都基于它。

第 2 步 · 让 AI 写出能跑通的主干

第一版只要跑通,不要重试也不要日志。代码越短越好审,我通常盯着它把分页循环和 upsert 那两段看清楚再继续。

基于上面的接口契约摘要,用 Python 写一个拉取脚本,要求:1. 单文件,依赖只有 requests 和标准库,存储用 SQLite;2. 拆成 build_session()、fetch_page(cursor)、normalize(record)、upsert(rows) 四个函数;3. 支持游标分页,循环到 has_more 为 false 结束,单次运行最多 200 页后主动停止并记录;4. 每条记录按 (platform_id, stat_date) 唯一键 upsert,重复跑不产生重复行;5. 所有时间统一转成 Asia/Shanghai 的 date 字符串;6. token、接口域名、表名从环境变量读取,不写死在代码里;7. 在需要加重试的位置留 TODO 注释,这一步先不实现。只输出代码,不要解释。

预期产出:一个几百行的单文件脚本,本地手动跑一次能入库。

第 3 步 · 补重试,先分清哪些错该重试

重试的价值全在分类上。超时、连接重置、429、5xx 值得等一等;401、403、422 重试一万次也没用,只会把 token 刷爆。

在刚才的脚本上增加重试层,规则如下:1. 只对以下情况重试:连接超时、读超时、ConnectionError、HTTP 429、HTTP 500/502/503/504;2. 不重试:400、401、403、404、422,直接抛出并记录原因;3. 退避策略用指数退避,base 2 秒,最多 5 次,每次乘 2,并叠加 0~1 秒随机抖动;4. 响应头带 Retry-After 时优先按它等待,上限 120 秒;5. token 过期(401 且错误码为 token_expired)先刷新 token 再重试一次,不计入重试次数;6. 每次重试写一条 WARNING 日志,包含第几次、等待秒数、原始错误类型;7. 分页循环里某一页重试 5 次仍失败时,不中断整批,记录该页游标后退出,返回已入库行数。输出改动后的完整文件。

预期产出:脚本能扛住偶发 5xx 和限流,不再一遇错就整批归零。

第 4 步 · 加日志和断点,让失败可追溯

运行日志是这东西能不能长期无人值守的分水岭。我踩过的坑是日志只 print 到 stdout,cron 一重定向,几百次运行混在一个文件里,出事根本翻不出来。

补充日志与断点机制:1. 用标准库 logging,同时输出到控制台和 logs/fetch_YYYYMMDD.log,按天切分;2. 格式为“时间 ISO8601 | 级别 | 模块 | 消息”,关键事件单独打一行 INFO,方便 grep;3. 必须记录的事件:开始运行、token 刷新、每页拉取行数、每次重试、入库行数、结束状态、总耗时;4. 新建 run_log 表,每次运行写一行:run_id、开始时间、结束时间、状态(success/partial/failed)、拉取行数、入库行数、已成功拉取到的游标;5. 每次启动先读 run_log,若上次状态是 partial,从记录的游标继续;6. 退出码约定:全部成功 0,部分成功 2,失败 1。输出改动后的完整文件,另附一段用假数据写的示例日志片段。

预期产出:可运行脚本加一份能直接看出哪一页挂了的日志。

第 5 步 · 交给定时任务,再留一个自检

定时本身不难,难的是“没跑成功得有人知道”。这一步我一般要两份东西:跑起来的配置,和发现异常的检查脚本。

给我三样东西:1. 一份 crontab 配置,每天 06:30 执行,工作目录 /opt/fetcher,输出重定向到 logs/cron.log,用 flock 避免上一次没跑完就重叠执行;2. 一个 check.py 自检脚本,读 run_log 表,若最近一次状态不是 success,或距上次成功超过 26 小时,就打印告警信息并以退出码 1 结束,方便接监控;3. 一份等价的 systemd timer 写法作为备选。输出三个代码块,不要解释。

预期产出:定时任务加自检脚本,异常能在当天被发现,而不是下个月对账时。

实测记录

环节 实际情况
从贴文档到脚本首次跑通 约 40 分钟,中途改了两次字段名
补重试和日志 约 25 分钟,大部分时间花在想清楚哪些错不该重试
单日增量拉取耗时 通常 3~6 分钟,看当天页数
被替代的手工操作 每天早上手工导表,约 15 分钟
返工 第一版没管 429,被限流两天后重写了退避

最容易错的 3 个地方

  1. 所有异常都重试:401 和 422 重试只会加速失败,要先按错误类型分流
  2. 退避没有抖动:几个任务同时撞上限流窗口,加个随机秒数就错开了
  3. 只留日志不留游标:跑到第 180 页挂了,第二天又得从头拉一遍

第三条尤其常见。很多人以为日志写全了就万事大吉,其实日志只能告诉你“出事了”,游标才能告诉你“从哪接着来”。

还有个隐蔽的坑:重试成功后忘了清掉上一次的错误状态,run_log 里会留下 partial,自检脚本天天告警,久了就没人看告警了。

可复用的东西

五段提示词按顺序连起来就是一条流水线:契约摘要、主干脚本、重试层、日志与断点、定时与自检。每段的输出都要贴回下一段当输入,别跳步,跳了字段名必错。

我把它们存成一个 prompts.md 放在项目根目录,下次接新接口,只改第一段的文档片段和域名就能整套复用。

这类活儿真正花时间的不是写代码,是把“哪些错该重试、失败了从哪继续”想明白。你手上那个接口,错误码文档写全了吗?

常见问题解答

接口返回 200 但数据是空的,脚本要不要重试?

不用。这多半是参数写错或权限不足,重试只是重复空跑。让脚本把该页参数和返回体前 200 字符记进日志,人工看一眼更快。

加了重试会不会导致数据重复入库?

看写入方式。按唯一键 upsert,重复拉同一页只是覆盖同一行;如果逻辑是先删后插,重试窗口里就可能出现短暂空档。

脚本放在自己电脑上跑行不行?

短期可以,长期不行。休眠、断网、换网络都会让任务漏跑,而且漏了没人知道。放到常驻机器上再接个自检,整条链路才算闭合。

小程序阅读免费
微信扫码进入小程序,按岗位找 AI 实操步骤
微信扫码进小程序
按岗位找 AI 实操步骤 · 提示词可收藏

发表回复

后才能评论