限流发生时,最危险的动作不是停下来,而是让脚本带着空响应继续覆盖原文件。保护已有结果的核心做法是:把每次调用视为一次独立写入,先落地原始响应,再解析成结构化数据,最后才更新汇总表;任何一步失败都不触碰已成功批次。下面用一个假设情境把决策过程串起来。
假设你用一个自写脚本对一批种子词做百度相关词查询,前期用二十个词试跑,每次都稳定返回,解析也正常。你把种子扩到两千个,跑到第三百多个时开始出现返回变慢、部分请求被拒绝的情况。此时脚本如果按“先请求、拿到结果、写整张表”的顺序执行,一旦中途被限流,已经拿到的三百多条结果可能因为最后一次写文件失败而全部丢失。
这个情境说明一个边界:小样本能跑通,不代表规模化后仍能照搬同一套流程。样本阶段考验的是解析逻辑,规模阶段考验的是失败隔离和写入顺序。
保护结果的第一道动作,是把每次请求的原始返回按批次单独保存,而不是边请求边写进统一结果表。可以按种子词或时间片命名文件,例如 raw_0001.json。这样做的影响是:即使后续解析脚本报错,原始数据仍在,你可以重放解析而不必重新请求,也就避免了在限流窗口里继续加压。
判断这一步是否做到位,看一个证据:把解析脚本故意改错一行,重新运行,原始文件是否完好、能否只靠它恢复结构化结果。如果能,说明请求与解析已经解耦;如果不能,说明解析和请求还绑在一起,限流时依然会丢数据。
限流下的返回往往不是干净的成功或失败,还夹杂超时、空结果、部分字段缺失。建议给每个种子词维护一个状态字段,至少区分三类:已完成且有可解析内容、请求已发出但结果未确认、尚未请求。只有第一类才允许写入汇总表。
这样做的结果是,补跑时你只需要针对“未确认”和“尚未请求”两类,而不是整批重来,既减少请求量,也避免重复覆盖已完成的数据。
遇到限流,有两种成立条件不同的选择。若限流是短时突发,降低并发、拉长请求间隔通常能恢复;若同一批种子在降速后仍持续被拒绝,说明当前调用方式已经不适合这个规模,需要改为分批、分时段执行,或减少单次请求覆盖的范围。判断依据不是“等一会儿再试”这一条,而是降速后连续若干轮的未确认比例是否下降。如果没有下降,继续等只是在消耗时间。
这里要说明一个容易误判的现象:某轮请求量归零,可能是限流,也可能是脚本提前退出、种子列表读空、或解析异常中断。不能只凭“没有新数据”就断定是限流,需要结合日志里最后一个成功批次和错误类型来判断。
当原始响应和状态表都稳定后,再生成汇总结果。汇总阶段只读不写原始文件,输出到新文件而不是覆盖旧文件。一个实际动作是:每次汇总都生成带批次标识的新文件,保留上一版。这样即使汇总逻辑改动引入错误,你仍能回到上一版对比差异。差异本身也是证据:如果两次汇总结果不一致,先查解析规则是否变化,而不是直接认定数据源变了。
对于具体工具或接口的限流阈值、配额和重试规则,不同实现差异较大,需要以你实际使用的工具文档为准,本文不假定任何特定品牌的现行功能。
把上述顺序写成固定步骤:请求并保存原始响应、更新状态、只对未完成项补跑、最后汇总到新文件。假设某次扩容后未确认比例明显上升,你先降速观察两轮,若仍未改善就改为分批执行,并把已完成批次冻结。这个流程的价值不在于一次跑完,而在于任何一轮中断都不会让前面已经拿到的结果作废。