先给有条件的结论:如果脚本在触发限流前已经把每批结果原子化落盘,并且记录下“哪些关键词已完成、哪些只拿到一半”,那么限流只影响进度,不影响已有数据;反之,如果结果先攒在内存里、最后统一写入,限流一来,最坏情况是这一轮全部作废。下面把判断条件、失效反例和一个可执行的下一步动作讲清楚。
限流本身只是服务端在告诉你“请求太密”,它并不破坏你本地已经写好的文件。真正决定损失大小的是写入时机。可以把脚本设计成两种模式来对比:
判断该用哪种,看两个条件:单次任务耗时是否长到“重跑成本高”,以及限流是否频繁到“中断几乎是常态”。两个都成立时,逐条落盘几乎是必选项。只有一个成立时,可以折中为每 N 条落盘一次,N 取一个你能接受的最大重跑量。
光落盘还不够,还要能区分状态。多个角色对同一批数据有不同理解时,分歧往往来自这里:有人看到文件里有某个关键词,就认为它已经查完;有人知道它其实只写入了一半字段。把状态显式写进结果,分歧就能转成可核对的项目。
一个简单做法是给每条记录加两个字段:status(例如 done、partial、failed)和 fetched_at。重新启动脚本时,先读取已有文件,跳过 status 为 done 的关键词,只补 partial 和 failed 的。这样限流恢复后不会重复消耗配额,也不会把半条数据当成完整结果使用。
假设一批 200 个关键词,脚本在第 137 个触发限流。逐条落盘且带状态时,前 136 个是 done,第 137 个是 partial;重跑只需处理 64 个。若采用末尾写入,200 个全部要重来。这个对比只说明写入策略对重跑量的影响,不代表任何工具的实际性能。
上面的结论在一种情况下不成立:结果之间存在相互依赖。比如脚本要根据前一批返回的某个标识去构造下一批请求,或者最终结果需要跨关键词做去重、合并、排序。这时逐条落盘的片段虽然保住了,但缺少后续依赖,可能无法直接拼成可用结果。
遇到这种依赖,逐条落盘只能保住“原料”,还要额外保存请求参数和中间标识,才能在恢复后继续拼接。如果连这些中间状态都没记,那么已有结果的价值会大幅下降——文件在,但用不上。判断方法很简单:问一句“只给我这些片段,不做任何新请求,我能不能还原出可用结果”。不能,就说明保护措施不完整。
不要等到真被限流才验证。选一个规模很小的关键词子集,故意在脚本运行到一半时终止进程,然后重新启动,观察三件事:已完成的关键词是否被跳过、partial 记录是否被正确补全、最终结果是否和一次性跑完一致。
演练结果会直接决定下一步动作:如果重跑后结果一致,说明落盘和状态机制可用,可以放量;如果出现重复、缺字段或状态判断错误,应先修正写入逻辑,再扩大任务规模。限流是外部条件,你控制不了它何时出现,但可以控制它出现时自己损失多少。