自助建站推广工具脚本调用遇到限流时怎样保护已有结果

📍 WDQWDWQD987AAAAA:216.73.216.11
📱 Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
🔗 /32cfad7a46f4.html
📄

自助建站推广工具脚本调用遇到限流时怎样保护已有结果

限流本身通常只是暂停,真正造成损失的是调用方在收到限流信号后继续重试或清空本地状态,把已经拿到的结果覆盖掉。保护已有结果的关键动作是:把每次成功返回的数据先落盘并标记批次,限流期间只做退避等待,不重新发起全量请求。

先分清是配额限流还是并发限流

脚本被限流时,常出现两种相反现象:一种是请求全部失败但偶发成功,另一种是前几十次正常、之后连续报错。前者更像并发或频率限制,后者更可能触发了按时间窗口计算的配额。两者的处理顺序不同。

如果是并发限制,降低同时运行的请求数通常就能恢复;如果是配额限制,继续调低并发也无效,必须等到窗口重置。判断依据是响应头或错误信息里是否出现剩余次数、重置时间这类字段,以及把并发降到很低后是否仍然失败。

限流时最容易破坏已有结果的两个动作

第一个动作是清空数据表后重新跑全量。很多脚本为了“保证一致”会先删除旧记录再写入,一旦中途被限流,旧记录已经没了,新记录只写了一半。第二个动作是无差别重试,把已经成功写入的记录再写一遍,造成重复或覆盖掉后续修正过的字段。

这两个动作的后果不一样。清空重跑损失的是历史结果,无差别重试损失的是数据准确性。前者更难恢复,因为原始返回可能已经无法再取到。

把结果先落盘再处理,限流只影响进度不影响存量

可行的做法是让抓取和处理分成两步:抓取脚本只负责把原始响应按批次写入本地文件或临时表,文件名带上时间戳和批次号;处理脚本再从这些批次里读取、去重、合并。这样即使抓取被限流中断,已落盘的批次仍然完整可用。

具体动作可以这样设计:每次请求成功后,立即把响应写入一个以批次号命名的文件,写入完成后再更新一个进度记录,记录最后成功的批次号。下次启动时先读进度记录,从下一个批次继续,而不是从头开始。

这个动作带来的直接结果是:限流只会让总耗时变长,不会让已经拿到的数据消失。下一步就可以根据进度记录判断是继续等待还是缩小请求范围。

退避等待要记录,不能靠循环硬扛

遇到限流后继续以固定间隔重试,往往会让限制时间延长,因为对方看到的是持续的请求压力。更稳妥的方式是读取响应中给出的重置时间,或者按指数退避逐次拉长等待间隔,并把每次等待的时长和恢复时间写入日志。

日志的作用是区分两种原因:如果每次都在相近的时间点恢复,说明是定时窗口配额;如果恢复时间不规律且与并发数相关,说明更可能是并发或频率限制。这个区分会直接影响下一步是调整并发参数还是调整任务调度时间。

一个假设的对比例子

假设某个脚本需要处理 200 个页面,每页一次请求。方案 A 是边请求边写入正式表,失败就整批回滚;方案 B 是先写入带批次号的临时文件,全部完成后再合并。

如果第 120 页触发限流,方案 A 回滚后前 119 页的结果也没了,重新跑还要再消耗一次配额;方案 B 的前 119 页文件仍在,恢复后从第 120 页继续。两种方案的总请求数差距会随着限流次数增加而扩大。这里的数字只是用来说明比较方法,不代表任何实际配额。

限流恢复后先核对再继续

恢复后不要立刻继续全速请求。先取一条已知成功的记录,核对字段是否完整、编码是否正确、时间戳是否落在预期范围内。这一步能发现落盘过程中被截断或编码错误的情况。

核对通过后再从进度记录指向的批次继续,并把本次限流的起止时间、恢复后的首批请求结果记录下来。这些记录在下次调整并发数或调度时间时,比单次成功与否更有参考价值。如果核对不通过,说明问题不在限流,而在写入逻辑本身,需要先修复写入再恢复抓取。

图1 图2

nginx