限流发生时,最危险的不是拿不到新数据,而是已经完成的部分被失败重试覆盖或整批作废。保护已有结果的核心动作是让每次调用先落盘、再合并,把“本次是否成功”与“已有结果是否保留”彻底分开。
同样表现为调用失败,原因可能完全不同,处理方式也不同:
区分方法很简单:记录每次调用的时间、请求标识、返回状态和响应体摘要。如果同一请求在间隔后能成功,偏向前两种;如果持续被拒且响应内容异常,偏向第三种。这个判断直接决定下一步是等待重试还是暂停整批任务。
假设你写了一个脚本,用某类网站健康检查工具逐个检查 200 个页面,检查到第 137 个时接口开始返回限流提示。此时前 136 个结果还在内存里,尚未写入任何文件。
如果脚本的逻辑是“全部成功才统一保存”,那么这次运行等于白做;如果逻辑是“捕获异常后从第 1 个重新开始”,那么重跑会再次撞上限流,且前面的结果被重复覆盖。两种常见写法都会让已有结果处于风险中。
更稳的做法是改成逐条追加:每完成一个页面,就把结果以固定格式写入本地文件,并记录该页面的唯一标识。限流发生后,脚本只需要读取已完成的标识集合,从第 137 个继续,而不是从头再来。这里的关键假设是页面标识稳定可复现;如果标识每次生成都不同,续跑就会重复或漏检,需要先固定标识规则。
保护结果不只是“写文件”,而是让文件能被下一次运行正确读取。建议满足三点:
可以用一个简单结构说明,例如每行一条 JSON,包含页面标识、检查项和结果状态。读取时按标识建索引,新结果与旧结果按时间取较新的一条。这样即使中途被限流,文件本身仍是完整可用的。
重试不是越快越好。可参考的做法是:第一次等待较短时间,若仍失败则成倍拉长间隔,并设置最大重试次数;超过上限就把剩余任务标记为待处理,而不是无限循环。
这里有个容易忽略的取舍:等待时间拉长会降低单次运行完成率,但能减少被进一步限制的概率。如果任务不紧急,分批在不同时间段执行通常比一次长时间重试更稳。反之,如果限流只是偶发且响应明确,适度重试的代价更低。判断依据是重试后的成功率和失败模式是否变化,而不是重试次数本身。
请求量下降、抓取量归零或某次运行没有报错,都不足以说明限流已被妥善处理。请求量下降也可能只是因为脚本提前退出;没有报错也可能是因为异常被吞掉、结果根本没写入。
更可靠的核对方式是:检查已完成记录数是否等于预期处理数、续跑后是否出现重复标识、以及失败任务的清单是否被单独保留。只有这些证据同时成立,才能说明已有结果被真正保护住了。具体到你所用的工具,其限流提示文案、重试建议和配额规则需要以实际返回和官方说明为准,不要凭记忆推断。