直接把脚本改成“失败就重试”通常是最差的做法:限流期间的重试会继续消耗配额,还可能让已经拿到的数据被半途覆盖。更稳妥的方向是把任务拆成“可重放的请求层”和“已确认的结果层”,限流只影响前者,后者用落盘和校验点保护起来。下面按你手上的一份任务清单或结果文件,逐步说明怎么改。
限流发生时最怕的不是没拿到新数据,而是把已经拿到的部分写坏。你需要给结果文件定义两种状态:已确认和待补。已确认指该条记录的关键字段完整、来源请求返回成功、且已通过一次基本校验;待补指请求被限流、超时或返回内容不完整。
假设你有一份按 URL 逐条查询排名的任务清单,脚本每拿到一条就追加写入结果文件。如果直接以“覆盖整个文件”的方式写回,限流中断后整个文件可能只剩前几条,这就是典型的已有结果被破坏。改成按行追加、每行带状态标记后,中断只会留下未完成的行,不会动到已完成的行。
判断标准可以很具体:一条记录至少要有查询对象标识、请求时间、返回状态、核心数值字段。缺任何一项就标为待补,而不是猜测填充。
限流和普通报错的处置方式不同。普通报错往往说明请求本身有问题,重试无意义;限流说明请求没错,只是当前节奏不被接受。脚本里应当把这两类分开处理。
这样做的实际结果:下一次运行可以从记录的中断位置继续,而不是从头再跑一遍,既省配额,也不会重复覆盖已有结果。
长脚本最容易在限流时丢失进度。解决办法是设置校验点:每处理完固定数量(比如 20 或 50 条,按你的配额和单次耗时定)就写入一次进度文件,内容包括已完成的批次编号、最后一条的标识、以及结果文件的当前行数。
恢复时先读进度文件,校验结果文件的实际行数是否与记录一致。如果一致,从下一个批次继续;如果不一致(比如上次写入被中断),则从最后一个校验点之后的行开始逐条核对,把不完整的行标为待补后重跑。这一步是保护已有结果的关键,因为它是唯一能发现“写了一半”的机制。
注意校验点本身也要原子写入:先写临时文件,再重命名替换,避免校验点文件自己写坏。
限流窗口内,继续发请求、换 IP 轮询、把并发调高,都属于把风险转嫁给结果完整性。更合理的动作是:
假设你的任务清单有 500 条,跑到第 180 条被限流。此时正确的结果是:结果文件保留 179 条已确认记录加 1 条待补,进度文件指向第 180 条,备份文件存在。下一次运行从第 180 条开始,而不是从第 1 条重跑。这样,已有结果既没丢,也没被重复请求污染。
如果限流是账号级封禁而非临时节流,靠校验点只能保住已有结果,无法继续补数据,此时需要先确认限制的性质再决定是否换用其他合规途径。另外,如果结果本身依赖实时性(比如排名位置随时间明显变化),隔天再补的数据和已确认数据可能不在同一时间口径上,这时应在结果中记录采集时间,并在分析时按时间段分开看待,而不是直接混在一起比较。
还有一点:请求量、抓取量归零或骤降,不能单独证明限流已解除,也可能是脚本提前退出、参数写错或目标页面结构变化。恢复运行前先用少量条目试跑,确认返回正常再放量。