核心做法是把“已确认的结果”和“未检查的结果”分开保存:每检查完一个链接就立即落盘,限流发生后不再重跑已完成的条目,只对未完成部分做断点续检。下面用一个假设情境说明这个决策过程。
假设你有一个约 200 条外链的清单,用脚本逐条调用某个友链检查工具的接口,判断对方页面是否仍然存在你的链接。脚本跑到第 70 条左右开始收到 429 或超时,之后连续失败。此时你面对的不是“工具坏了”,而是“已经确认的 70 条要不要保住、剩下的 130 条怎么继续”。
关键判断是:限流只影响请求节奏,不影响已经返回并写入本地的数据。所以保护已有结果的本质是保护本地文件,而不是保护工具端的状态。
最容易被忽略的动作是“先攒在内存里,最后统一写文件”。一旦脚本被限流中断或进程被杀,内存里的结果全部丢失,你只能从头再来,而重跑又会再次触发限流,形成循环。
可执行的改法是改成逐条追加写入,例如用 jsonl 格式,每检查完一条就追加一行:
这样做的直接结果是:限流中断后,你手里有一份可读的、部分完成的结果文件,而不是一个空文件加一段报错日志。
有了落盘文件,续检逻辑就能成立。启动时先读取已有结果,把已确认的条目从待检队列中剔除,只处理剩余部分。这里有两个取舍需要明确:
如果限流是因为请求间隔太短,续检时应主动放慢节奏,例如加入固定等待或指数退避。这一步的效果是让剩余请求更可能通过,而不是继续撞墙。
缺少完整数据时,仍可执行的最小动作是:统计已完成部分中“异常链接”的数量和占比,并列出具体清单。这能支撑一个有限结论——已检查范围内的问题分布。不能推出的是:整体异常率、剩余链接的健康状况、以及“限流说明对方站点有问题”。
限流的合理解释至少包括:调用频率超过工具方限制、同一出口 IP 被多人共用、对方站点临时拒绝、网络抖动。这些原因彼此不同,仅凭限流现象无法断定是哪一种。同理,某次请求返回失败不能单独证明链接已失效,需要后续用正常节奏复核。
续检完成后,把结果文件按状态分组:确认失效的进入替换或删除流程,无法判断的进入人工复核队列,正常的归档留痕。这个动作的价值在于,它让限流中断从“一次失败”变成“一次可恢复的部分完成”,后续每一步都有明确输入。
至于具体工具的限流阈值、重试策略和接口行为,不同工具差异较大,需要以你实际使用的工具文档为准,不要照搬其他工具的数值。