能保住已有结果的前提是:把“已成功返回的数据”和“本次请求的状态”分开存储,限流发生时只中断增量抓取,不覆盖或清空已经落盘的成功记录。这个结论在单账号、单接口、样本量较小的场景下通常成立;一旦你为了提速改成多线程并发、多账号轮换或跨多个查询接口混跑,同一套保护逻辑就可能失效,因为限流信号不再对应单一数据源,失败批次和成功批次会互相污染。
脚本调用排名工具时,最常见的误判是把限流返回当成“该词没有排名”。两者在数据上的表现可能很像:字段为空、列表长度为 0、排名位置缺失。但后续动作完全不同——空结果可以写入正常记录,限流则必须挂起并等待重试。
可区分的证据通常有三类:
假设你一次提交 200 个词,前 150 个正常返回,后 50 个全部返回空。如果这 50 个恰好是同一批并发请求,优先按限流处理;如果它们分散在不同批次、不同时间点,才考虑真实空结果。这个判断直接决定下一步是重试还是落库。
保护已有结果的核心不是重试逻辑,而是写入顺序。可行的做法是:每拿到一条成功响应就立即追加写入,而不是等整批跑完再统一写。这样即使后续批次被限流中断,前面已经拿到的数据仍然完整。
具体动作可以拆成三步:
这个动作的结果是:限流只会让“未完成的部分”延后,不会让“已完成的部分”回退。下一步你就能安全地降低并发、增加间隔,只补跑失败键。
上面这套逻辑有一个明确的失效边界。如果你为了绕开限流,改用多个账号或多个出口轮换请求,那么同一个关键词可能在不同账号下返回不同结果,或者同一账号的部分请求被限流、部分正常。
此时“成功即落盘”会带来一个新问题:你无法判断某条成功记录来自哪个口径,也无法判断它是稳定结果还是轮换过程中的偶然返回。限流信号被分散到多个来源后,状态表里的失败键和结果表里的成功键可能指向不同的账号环境,重跑时补出来的数据与已有数据不可比。
所以,多账号轮换适合“只求拿到一次结果”的场景,不适合“需要持续对比、需要结果可复现”的场景。如果你确实要轮换,至少要记录每条结果对应的账号或出口标识,并在分析时把它们分开看,而不是混在一张表里。
当限流解除、你准备补跑失败键时,先做一次小批量验证,而不是直接恢复原来的并发量。取 5 到 10 个之前失败的键,用降低后的并发和间隔跑一轮,确认返回结构正常、状态码正常,再逐步放量。
如果小批量仍然失败,说明限流没有真正解除,或者你的请求特征仍被判定为异常。这时应继续等待,而不是加大重试频率——高频重试往往会让限流窗口延长。
补跑完成后,再用结果表和状态表做一次对账:成功键数量是否等于预期总数,失败键是否只剩真实无结果的项。对账通过,才说明已有结果被完整保护,可以进入下一步分析;对账不通过,则要先查清缺失的键属于哪一类失败,再决定是否重跑。