PR查询脚本遇到限流时怎样保护已有结果

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

PR查询脚本遇到限流时怎样保护已有结果

先给结论:限流发生时,不要立刻重跑整批任务,而是把已抓到的结果先落盘、标记完成状态,再只对失败或未开始的条目做增量续跑。这样做的原因是,限流通常只影响请求节奏,不会让已经写入本地的数据失效;真正会造成损失的是脚本在异常退出时把内存里的结果一起丢掉,或者下一次运行覆盖了旧文件。

判断该续跑还是重跑,先看两个条件

选择续跑还是重跑,取决于结果是否已经持久化,以及条目是否带有可判定的完成标记。

可区分的证据是:查看输出文件的行数与本次已处理条目数是否一致,以及文件里是否存在部分写入的残缺行。如果行数明显少于已处理数,说明写入环节有问题,而不是限流本身造成的。

限流后的第一个动作:冻结现场而不是重试

收到限流响应后,脚本应停止发起新请求,把当前批次的结果和进度状态写入一个独立文件,例如带时间戳的 progress.json,记录已完成的唯一键列表和最后成功的位置。这个动作的结果是:即使后续进程被终止,也能从断点恢复,而不必依赖内存。

接着检查限流响应的类型。如果是明确的频率限制提示,等待一段时间后降低并发数即可;如果是账号或权限层面的拒绝,继续重试不会改善,需要先处理凭据或配额问题。两种情况的下一步不同,混在一起重试会掩盖真正原因。

续跑时怎样避免覆盖和重复

续跑的实现要点是读取已有结果、构建已完成集合、只处理差集。假设一次任务计划查询 500 个条目,限流前成功写入 180 条,那么续跑应只针对剩余 320 条,而不是重新查询全部 500 条。这是假设示例,用于说明差集比较的方法,不代表任何真实项目的数量。

写入方式建议改为追加模式,并在每条记录中带上查询时间和状态字段。这样后续核对时能区分“当时查到的结果”和“本次新增的结果”,避免新旧数据混在一起无法判断来源。如果工具本身不支持增量,至少要在文件名或目录上体现批次,不要直接覆盖上一批。

哪些情况下续跑并不成立

有三种例外需要单独处理。第一,查询结果本身依赖实时状态,间隔太久后续跑得到的值已经不可比,此时应重新定义批次边界,而不是把新旧结果拼在一起。第二,限流原因是账号级封禁,续跑前必须先确认访问是否恢复,否则只是重复失败。第三,条目之间有关联依赖,比如后一条需要前一条的输出,那么跳过失败项会导致后续结果不完整,需要按依赖顺序回退到最近的完整节点。

另外,请求量或抓取量突然归零,不能单独证明限流已经解除。它也可能是网络中断、脚本提前退出或目标端返回空结果造成的。要结合响应状态、日志时间戳和已完成条目数一起判断,再决定是否继续。

把保护动作固化进脚本流程

可执行的做法是:在每次请求成功后立即追加写入并更新进度文件,而不是等整批结束再统一保存;在捕获限流异常时先落盘再退出;续跑入口默认读取进度文件,只有显式指定时才全量重跑。这样做的结果是,限流从“可能丢失全部结果的事故”变成“损失当前一条请求的可恢复中断”,下一步只需按进度补跑即可。

图1 图2

nginx