先保住已经落盘的结果,再决定要不要继续请求。最稳妥的顺序是:限流出现后立刻停止新请求,把内存里尚未写盘的数据先落盘,然后根据“限流是临时的还是配额性的”选择等待重试或降级改用人工分批查询。不要一边报错一边继续打请求,那只会让已有结果也拿不回来。
同样是返回限流信号,处理方式完全不同。你可以从三个可观察的证据区分:
要注意,请求量突然归零或报错率突然升高,并不能单独证明是限流。网络中断、脚本异常退出、凭证过期都会产生类似现象。先做一次单条请求验证,再下结论。
如果单条验证能通过,说明限制大概率是临时的。此时的动作顺序是:
这个动作的结果是:即使后续重试全部失败,你也只损失了尚未取回的部分,已取回的结果完整可用。断点记录让你下次可以从失败处继续,而不必从头再跑一遍。
适用条件:已有结果尚未落盘、任务总量不大、可以接受等待。代价是整体耗时变长,需要脚本支持断点续跑。
如果等待后仍然失败,或者报错指向配额耗尽,继续重试就是浪费。此时应该降级:
假设一个场景:你需要核对两百个页面的标题与描述,脚本跑到第八十条时被限流,且等待后仍不通。此时把前八十条结果连同抓取时间一起存档,剩余一百二十条按页面重要性拆成三批,每天跑一批。这样做的结果是,你当天就能基于八十条样本做初步判断,而不必等全部跑完。
适用条件:配额恢复周期长、任务可以分批、结果允许存在时间差。代价是数据不再同一时点,比较时需要留意时间戳差异。
第一,写入与请求分离。让脚本先把响应写入临时文件,再统一入库,避免请求中断导致数据丢失在半途。
第二,保留原始响应。除了结构化字段,把原始返回内容一并存下,后续解析规则变化时还能重新处理,不必再次请求。
第三,记录失败清单。把失败的查询词、失败时间和错误类型单独记一份,这份清单既是重试依据,也是判断限流性质的证据。
一个可用的最小写法是让脚本在捕获异常后先执行落盘函数,再决定是否退出循环:
try: fetch() except RateLimit: save_partial(); log_failure(); break
这样即使限流反复出现,你手里始终有一份可用的结果,而不是只剩一个报错日志。
如果失败伴随鉴权错误、凭证过期提示,或同一凭证在多个脚本中同时使用,应先排查凭证和并发,而不是加大等待。另外,当已有结果本身已经足够支撑当前判断时,继续补齐剩余数据的收益有限,直接使用现有样本并标注覆盖范围,往往比冒险重跑更划算。
具体工具的重试策略、配额规则和错误码含义会随版本变化,使用前需要以你所用版本的说明为准。