限流发生时,最危险的不是拿不到新数据,而是让失败重试覆盖掉已经抓到的旧结果。先做本地落盘和断点记录,再决定继续等还是换调用方式;只把已经完整返回并校验过的条目写入结果文件,未完成的部分单独留在待办队列里。
同样是返回错误,背后可能是两种完全不同的限制。第一种是短时频率限制:请求间隔过密,稍等后同一接口仍可能恢复。第二种是配额或权限限制:当天额度耗尽、令牌无权访问该资源,继续重试只会持续失败。
区分方法很简单:记录每次请求的时间、状态码或错误文本,然后拉长间隔做一次探测。如果拉长到明显更慢后仍然失败,且错误信息指向配额或权限,就按配额限制处理;如果拉长间隔后能成功,说明只是频率问题,可以继续,但必须降速。
这个判断直接影响下一步:频率限制适合排队重试,配额限制适合停跑并保留进度,等额度恢复或改用别的授权方式。把两种限制混在一起,最常见的后果是脚本空转一整晚,还把失败标记写进了结果文件。
如果每条记录都有稳定标识(比如 URL、ID 或查询词加参数组合),优先选择“边跑边落盘”。每处理完一条就追加写入,并在单独的进度文件里记录最后完成的位置。
具体动作:把结果写入按批次命名的文件,例如 result_001.jsonl,同时维护一个 cursor.txt 记录已完成的标识。重跑时先读取进度文件,跳过已完成的条目。这样即使中途被限流打断,已有结果也不会被重试覆盖,恢复后从断点继续即可。
这个动作的结果是:失败范围被限制在未完成的条目上,已得数据保持可复用。下一步可以只针对待办队列做慢速重试,而不必整批重跑。
如果结果之间相互依赖,比如需要全量对比才能判断差异,单条落盘的价值有限。此时优先选择“先暂存原始响应,再统一解析”。把每次成功返回的原始内容原样写入暂存区,不急着做清洗和合并。
具体动作:为每个请求保存原始响应和请求参数,命名带时间戳;解析阶段只读取暂存区里标记为完整的文件。被限流中断的请求不写暂存,或写入时明确标记为不完整。
这个动作的结果是:即使解析逻辑后续调整,原始数据仍在,不需要重新调用接口。下一步可以在额度恢复后补齐缺失请求,再一次性解析。
限流下的重试容易犯两个错:一是无上限重试,二是把错误响应当成有效结果写入。更稳妥的做法是给重试设上限,并区分可重试与不可重试的错误。
假设一个脚本计划处理 500 个查询,跑到第 180 个时开始持续返回频率限制错误。如果没有断点记录,重跑会从第 1 个开始,重复消耗额度;如果有进度文件和去重标识,重跑从第 181 个开始,前 180 条结果不受影响。这个对比说明的是记录方式的差别,不代表任何具体工具的额度或速度。
如果接口每次返回的内容本身就会变化,比如带实时排序或个性化推荐,按标识去重可能把旧结果误当成已完成。这时应按“时间窗口”而不是“条目标识”记录进度,并明确结果对应的采集时间。
另外,如果限流来自账号权限而非调用频率,继续优化脚本没有意义,需要先确认授权范围是否覆盖目标资源。具体工具的错误码含义、配额规则和恢复时间,各平台并不一致,需要以实际返回信息和官方说明为准。
最后,把限流当作数据波动的解释也要谨慎:请求量下降、返回变少,可能来自限流,也可能来自查询条件变化、数据源更新节奏不同或过滤规则生效。只有排除这些因素后,才能把原因归到限流上。保护已有结果的核心不是猜原因,而是让每次失败都不破坏已经确认可用的部分。