结论先说:限流发生时,最该保护的不是“继续跑完”的进度,而是已经拿到的那部分结果和它的可追溯性。正确动作是立即停止重试、把已落盘数据封存成带时间戳的快照,再单独记录被限流截断的位置,之后才决定是换时段续跑还是缩小任务范围。下面用一个假设情境把决策过程走一遍。
脚本报错时,很多人第一反应是网络抖动或工具故障,但限流、鉴权失效、参数错误给出的信号并不相同。把返回信息归类,才能选对处理方式。
这三类现象可能同时出现,所以不要凭单次报错下判断。可行的做法是保留最近若干条原始返回,按时间排列,看失败是“成簇出现”还是“跟某个输入绑定”。成簇且随时间缓解,更接近限流;跟输入绑定,先查参数。
假设你有一个脚本,用某个seo关键词工具按分页方式拉取一批词的指标,每页请求之间间隔很短。跑到第若干页时开始连续报错,此时本地已经存了前面若干页的数据,但脚本设计成“全部成功才写文件”,于是内存里那份数据随着进程退出一起丢了。
这个假设里真正的问题不是限流本身,而是写入时机。如果每页成功就追加落盘,限流只会让你少拿后面几页,不会让你失去前面几页。所以保护已有结果的第一原则是:把“结果持久化”从任务结尾提前到每个最小成功单元之后。
具体动作:把逐页结果写入一个带时间戳的中间文件,例如 result_20250101T101500.jsonl,每行一条记录,写完即刷新。这样即使进程被限流打断,你手上仍有一份完整可读的部分结果。这个动作的直接结果是:后续续跑时你可以选择“跳过已完成的页码”,而不是从头再来,从而减少再次触发限流的概率。
这四步里,第2步和第3步最容易被跳过,但它们决定了你后面是“有据可查地续跑”还是“凭感觉重来”。
封存快照之后,你有两个成立的选择,条件不同:
判断依据不是“哪个快”,而是“合并后能不能解释每一行数据来自哪次请求”。如果解释不了,重跑反而更省事。这里要注意一个反常现象:请求量突然归零,并不等于限流已经解除,也不等于任务已经完成。它可能是脚本提前退出、可能是鉴权过期、也可能是工具侧返回了空结果集。把这三种解释分开验证,再决定下一步。
第一,把请求节奏做成可配置的,而不是写死在代码里。这样遇到限流时,你能调大间隔后小范围试跑,用少量请求确认是否恢复,而不是直接全量重来。
第二,给每次运行建一个独立的输出目录,目录名含时间戳和任务标识。这样“已有结果”永远是只读的历史,新结果不会覆盖旧结果,对比两次采集的差异也变得直接。
这两处改动都不依赖具体工具的功能,属于脚本侧的控制。至于某个具体工具是否提供官方批量接口、配额说明或断点续传能力,需要以该工具的当前文档为准,不能凭印象假设。