限流不是“任务失败”,而是接口在告诉你当前节奏不可持续。此时最重要的动作是立刻停止重试、冻结已有输出,而不是换代理或加并发把数据抢回来。只要已有结果被完整落盘、并标记清楚覆盖范围,后续无论是等窗口恢复还是改用分批调用,都不会让前面的工作白费。
两种情况的处理方向相反,判断依据来自响应本身,而不是猜测。
区分方法很简单:暂停脚本,用单次、低频的请求试探一次。如果立刻成功,偏向节奏问题;如果仍然被拒且提示与额度相关,偏向配额问题。这个判断直接决定下一步是“等待后继续”还是“缩减任务范围”。
如果确认只是节奏问题,核心原则是断点续跑,而不是从头重跑。
这里的关键动作是先落盘、后标记。如果先写标记再写数据,中途中断就会产生“标记说完成了、实际没有数据”的空洞,后续续跑会直接跳过这段,形成难以发现的缺口。
一个假设例子:脚本需要处理1000条记录,处理到第320条时被限流。若已落盘并记录起点为321,恢复后从321继续,前320条无需重跑;若没有记录起点,只能全部重来,不仅浪费额度,还可能再次触发限流。
如果判断为配额耗尽或权限受限,等待没有意义,此时要做的不是抢救全部数据,而是按价值排序,保住仍然有用的部分。
这个取舍的后果很实际:保留一份标注清晰的半成品,后续可以增量补齐;保留一份没有范围说明的混合数据,后续任何对比都可能得出错误结论。
无论哪种条件,都建议在输出目录里固定保留三类文件:
records.jsonl:逐行追加的原始结果,每行一条,写入即持久化。checkpoint.txt:记录最后成功处理的标识和对应时间。coverage.md:说明本次覆盖了哪些范围、哪些范围缺失、限流发生的位置。这样做的直接结果是:下次运行脚本时,只需读取checkpoint.txt决定起点,读取coverage.md判断是否需要补跑,而不必依赖记忆或重新核对。动作本身不复杂,但它把“限流中断”从一次事故变成一次可管理的暂停。
有几种情形需要先处理,再考虑恢复调用:
这些例外的共同点是:问题不在调用节奏,而在数据或权限本身。此时保护已有结果的正确做法是冻结并标注,而不是继续推进。
最后要提醒的是,请求量归零、抓取量下降这类现象,不能单独证明限流处理已经正确,它也可能来自任务自然结束、目标范围缩小或接口返回结构变化。判断是否真的恢复,仍然要回到单次低频试探和覆盖范围核对上,确认无误后再决定是否扩大调用规模。