如果脚本已经拿到部分结果,限流发生时最重要的不是继续重试,而是先把内存里未落盘的数据写入本地,再决定是否恢复调用。这个结论有一个前提:你已经知道哪些结果属于完整批次、哪些只是半成品。如果脚本把每次响应直接拼进一个总列表,却没有任何批次标识,那么先落盘也可能把重复或残缺记录一起保存,后续清洗成本反而更高。
限流通常表现为请求被拒绝、响应变慢或返回错误码。此时脚本内存里可能有三类数据:已经成功解析并校验过的记录、只收到部分字段的响应、以及只发出去但没拿到返回的请求。保护已有结果的第一步,是让这三类数据分开存放,而不是混在一个列表里。
一个可执行的最小动作是:在每次请求成功后,立即把原始响应和解析后的记录追加写入本地文件,并带上批次号、时间戳和请求参数。这样即使进程随后被限流中断,也能知道哪些记录来自哪一批、对应什么查询条件。这个动作的结果会直接影响下一步:如果落盘文件里能按批次还原,就可以只补缺失批次;如果无法还原,就只能重新跑一遍,已有结果等于没有保护住。
很多脚本遇到限流会进入重试循环,等待几秒后再发请求。问题在于,重试期间内存中的结果仍然没有持久化,一旦进程被终止、机器重启或触发更严格的限制,已经拿到的数据会一起丢失。更稳妥的顺序是:先落盘,再判断是否值得重试。
可以按以下顺序处理:
这个顺序的关键在于,保存动作不依赖工具是否恢复可用。即使之后不再调用该工具,已有结果仍然可用。
如果你没有权限查看工具的完整配额说明,也不知道限流阈值,仍然可以做一件事:把每次调用的请求参数、返回状态和响应体写入本地日志,并在日志中标记“成功解析”“部分解析”“请求失败”。这不需要额外权限,只需要脚本自身能写文件。
做完这一步后,你能得到的是:哪些查询条件已经成功返回、哪些条件反复失败、失败集中在什么时间或什么参数上。你不能由此推出工具的限流规则、配额上限或恢复时间,因为这些信息需要以工具方的实际说明为准。日志只能帮你判断下一步该补哪些批次,不能替代对工具当前限制条件的核对。
假设脚本要查询 200 个词,每 20 个词组成一批,共 10 批。跑到第 6 批时开始被限流。如果脚本每批成功后就把该批结果写入独立文件,那么恢复时只需要确认第 6 到第 10 批中哪些已经完整落盘,再从未完成的那一批继续。如果脚本把所有结果只放在内存里,限流后进程退出,前 5 批也需要重新请求。
这个例子的数字只是用来说明比较方法,不代表任何工具的实际配额或恢复表现。它真正说明的是:落盘粒度越接近批次,恢复时越不需要重跑全部内容;落盘粒度太粗,保护效果就会下降。
先落盘并非总是有效。一个反例是:脚本把每次响应追加到同一个文件,但没有写入请求参数和批次标识,也没有区分完整响应和错误响应。限流发生后,文件里可能混有重复记录、空响应和上一次运行的旧数据。此时即使数据还在,也无法判断哪些该保留、哪些该丢弃,恢复调用时仍然要重新核对。
因此,落盘时必须同时保存可区分来源的信息,例如请求参数、批次号、响应状态和写入时间。缺少这些字段时,文件只能算缓存,不能算可恢复的结果集。
限流发生后,不要立刻改脚本继续跑。先根据落盘文件生成一份恢复清单:已完整批次、部分批次、未开始批次。然后只对未完成部分安排后续调用,并给每次调用之间留出足够间隔。如果工具方对调用频率有明确说明,以该说明为准;如果没有,先用更保守的批量测试一次,观察返回状态后再决定是否扩大。
这样做的结果是,已有结果被固定下来,后续调用只补缺口,不会因为一次限流把之前的工作全部作废。至于限流何时解除、继续调用是否一定成功,仍取决于工具方的实际限制条件,不能仅凭本地日志下结论。