限流发生后,最危险的动作不是等待,而是立刻重试并覆盖上一轮已写入的结果。保护已有结果的可行做法是:把每次脚本运行拆成“抓取—落盘—合并”三段,限流只中断抓取,不触碰已落盘的数据;等限流窗口过去后,从断点继续,而不是整批重跑。下面按一个矛盾现象、两种解释、区分证据的顺序说明。
很多脚本在请求失败时会打印空数组或写入空文件,于是日志看起来像“这一轮什么都没抓到”。但限流通常发生在请求层,返回的是状态码或错误信息,而不是数据本身为空。这两件事在日志里长得像,处理方式却完全相反:前者应当重试或等待,后者应当检查参数和解析逻辑。
一个可核对的判断方法是看同一批次里成功请求的比例。如果前几十条正常返回、后面集中失败,限流是更合理的解释;如果从第一条就失败,更可能是鉴权、参数或接口变更。这个区分决定了下一步是等待冷却,还是停下来排查调用方式。
这种情况下,已成功返回的数据已经写进文件或数据库,只是后续请求被拒绝。已有结果没有受损,受损的只是本轮覆盖范围。此时正确动作是暂停请求、记录断点位置,等冷却后再从断点续跑。
更隐蔽的情况是脚本每次启动都以“清空再写入”的方式处理输出文件。即使请求全部成功,中途异常退出也会留下一个不完整的文件。这种情况下,日志里的失败次数可能很少,但结果文件明显变小。限流只是表象,真正的问题是写入策略。
这四类证据里,文件大小和修改时间最容易核对,也最能直接影响下一步:如果确认是写入覆盖,先改写入方式再谈限流;如果确认是限流,先保护断点再谈重试节奏。
把输出改成“每轮写入独立文件,成功后再合并”,是保护已有结果成本最低的一步。假设一次任务要处理一千个条目,脚本每处理完一百个就写一个带时间戳的分片文件,合并阶段只把完整分片并入主结果。这样即使中途被限流,已完成的八百个条目仍在分片里,不会因为一次异常退出而丢失。
这个动作的结果会直接改变下一步:分片存在时,续跑只需要读取最后一个分片的位置,请求量大幅减少,也更不容易再次触发限流;分片不存在时,你只能整批重跑,重复请求反而加重限流风险。是否采用分片,取决于你的任务能否被稳定地切成有序批次——能切就切,不能切则至少要保留上一轮的完整备份。
冷却结束后不要直接全速续跑。先用少量请求确认接口恢复正常,再按原节奏推进。如果恢复后立刻又失败,说明等待时间不够或调用频率本身过高,此时应调整间隔而不是继续重试。
需要提醒的是,不同工具和接口对限流的判定方式、冷却窗口和返回信息并不一致,具体阈值和提示格式需要以你实际使用的服务文档为准,不能照搬他人的经验数字。判断已有结果是否安全的依据始终是自己的落盘记录,而不是日志里的成功计数。
把“抓取”和“写入”分开之后,限流就从一次数据事故降级为一次进度中断,这也是脚本调用场景下最值得优先落实的改动。