返回知识中心
网络

抓取限流:429、Retry-After 与并发控制

从 HTTP 429 和 Retry-After 诊断抓取限流,区分请求频率、在途工作与重试流量,在重试放大负载之前停止授权任务。

BotBrowser Team

文档中心

想直接进入 网络 文档吗?

这篇文章属于知识中心的指南库。若你要步骤化配置、参考说明和持续更新,请直接进入对应 docs 分区。

抓取限流是服务端决策,不是浏览器容量设置。HTTP 429 表示某段时间内请求过多,但不揭示计数键,也不授权更换路由。BotBrowser 文档介绍浏览器级和上下文级代理配置,这些控制既不提高服务配额,也不保证访问。诊断应从具体响应、获准负载和派发记录出发,再分开检查请求频率、未完成工作和重试流量。

429 响应暂停派发,Retry-After 给出时间边界,队列在预算内等待或者停止。

同一任务从可用数据转为挑战时,采集中途出现 CAPTCHA 的诊断 关联最后可用响应和首个挑战,不把先后顺序认定为原因。

摘要

  • 改配置之前,保存 HTTP 429、接收时间以及存在的 Retry-After 值。
  • 除非服务文档或自有服务器记录明确说明,否则将限流计数键记为未知。
  • 并发统计未完成工作,请求频率统计单位时间的派发次数;一次导航可能产生多个请求。
  • 在自有测试环境中,首次出现 429 就停止加压。不要探测第三方服务的运行限额。
  • 同时遵守时间边界和重试预算;延后的请求可以到期结束,不必再次发送。

目录

429 响应能够确立什么

RFC 6585 第 4 节 将 429 定义为限流响应。响应可以带有 Retry-After,缺少它并不表示允许无限流量。响应正文可能解释条件,但单看状态码不能确立账号封禁、IP 信誉判定或浏览器指纹检测。应将已观察到的状态与这些可能解释分开,直到有证据支持其中某一种。 对于尚未收到任何 429 的故障,爬虫拦截分层诊断区分 DNS、TLS、HTTP 与页面数据证据。

确认收到响应的是哪条请求。顶层文档、同源数据接口和资源请求属于不同记录。文档导航成功不证明数据请求成功;数据接口被限流后,应用仍可能显示旧的页面外壳。应把响应关联到失败字段或记录,而不是根据外观给整页定性。SERP 负载要求区分导航完成与数据被接受,这一区别同样适用于限流诊断。

保存去除不必要查询秘密后的最终 URL、状态、接收时间、选定响应头和请求角色。出现重定向时,分别记录各跳状态,不要把最终 429 归给每一跳。没有响应的超时不是已观察到的 429。用其他状态返回的挑战页也需要独立分类;把两者都悄悄改称限流,会使后续比较失真。

标准确立的是 HTTP 含义,不是恢复承诺。建议的重试时刻到来,不代表容量已经预留,也不保证后一次请求成功。调度器仍需恢复权限、剩余任务预算和允许重复的操作。即使后来请求成功,也保留原始响应记录,避免最终成功计数抹掉这次事件。

从服务端证据查明计数范围

RFC 6585 有意将用户识别与请求计数方式留给服务器决定。限流器可能覆盖一个资源、更广的服务范围或已认证账号。因此,一条 429 无法区分按 IP、账号还是会话计数。MDN 的 429 参考描述状态码,不描述此次响应服务器的具体策略。

对于自有服务,检查限流器配置,并通过请求 ID 关联决策记录。记下规则标识、资源组、测量窗口以及文档确认的计数键类别。保存经过脱敏的键引用,而非原始 Cookie、凭据或账号标识。如果网关和应用都有限流,先确定由哪一个组件产生响应,再解释其策略;不要把一层的决定归给另一层。

对于第三方集成,使用其公开配额规则或授权支持回复。两者都没有说明计数范围时,写下 scope=unknown。不断换 IP、Cookie 或账号直到结果改变,会同时改变多个输入,并不能确立原始规则,还可能违反服务策略。计数范围未知是有效诊断结果,猜测身份类别并不会让记录更可靠。

将配置意图与观察结果分开。部署可能希望按浏览器上下文隔离任务,服务器却仍将流量计入同一个账号配额。代理路由不同,应用会话也可能仍然共享。这些应记录为不同事实。浏览器存储边界和网络路径本身无法证明服务器的配额分区,也无法认证其权限模型。

分别测量频率与并发

请求频率是单位时间内的派发数,例如每秒请求数;并发则是仍在途的操作数。两者都不是打开的标签页数。应统计策略对应的层级:浏览器任务、文档导航与 HTTP 请求可能有不同总数。除了文档,页面还可能请求脚本、图像和数据,所以每分钟任务数不是完整的 HTTP 请求频率记录。

举例而言,稳定负载下每秒派发 2 次、平均耗时 3 秒,大约能维持 6 条未完成请求。这只是规划近似,不是浏览器实测结果,也不是配额建议。突发流量、耗时波动和衍生请求都会破坏这种简单关系。评估自有测试环境时,应保存真实派发时间戳与在途计数,不要从配置的工作进程数反推。

inflight ≈ dispatches_per_second * mean_request_seconds

分别设置派发频率与在途上限。并发限制为 4 并不规定特定请求频率:请求很快结束时,短时间仍可能派发很多次。反过来,响应变慢时,即使派发频率很低也可能积累未完成工作。保留队列年龄、响应耗时、活动工作数、重试派发数和已接受记录,才能区分队列增长与有效吞吐。

自有测试环境中的有限阶梯

负载检查之前,与环境负责人约定允许频率、最大并发、窗口时长、资源上限和停止条件。从已声明的低负载基线开始,仅按预先批准的等级递增。首次出现 HTTP 429 时,停止新派发、取消尚未开始的工作,并记录响应。不要继续升档来寻找限流器还能承受多少额外请求。在途操作可能已经到达服务器,需要明确的取消或完成策略。

最后一个没有 429 的档位只是这次样本的观察,不是稳定服务上限,也不代表可以长期以该频率运行。限流器可能使用比采样更长的窗口,或者与其他授权客户端共享配额。仅在约定计划内重复检查,并用服务端记录解释结果。浏览器选型评分表将可持续并发视为受具体负载限制的证据,而非整个品牌通用的容量数字。

解析 Retry-After 的两种形式

HTTP Semantics 第 10.2.3 节 将 Retry-After 定义为 HTTP 日期或非负整数秒数。MDN Retry-After 参考展示了这两种形式。调度之前先解析响应头,并同时保留原文和解释,防止把间隔误当成毫秒,或把日期误当作时长。

对于 Retry-After: 120,拟采用的时间边界是接收该响应之后 120 秒。如果接收时间记为 12:00:00 GMT,算出的边界就是 12:02:00 GMT。这些是示例输入,不是捕获到的交换记录。应从接收响应时计时,而不是任务创建、浏览器启动或等待中的工作进程最终读取记录时开始。日志消费者处理延迟,不应在未说明的情况下重新启动已过去的间隔。

Retry-After: Mon, 09 Nov 2026 12:02:00 GMT 表示日期而非时长。与本机时间比较时,时钟准确性很重要。保存接收时间以及存在的服务器 Date 响应头,作为诊断输入;仅有 Date 不能证明任一时钟准确。已经过去的日期不会产生未来等待,但同样不授权立刻进入重试循环。

整个调度计算使用统一时间单位。以下字段是建议的事件记录字段,不是浏览器 API,也不是强制的响应头处理算法。headerNotBefore 表示解析出的时间边界,policyNotBefore 表示集成文档规定的更严格等待。任务截止时间决定等待是否仍有意义:

eligibleAt = max(headerNotBefore, policyNotBefore)
if eligibleAt > jobDeadline: stop

响应头缺失、格式无效或者超出支持的数值或日期范围时,保留该状态,不要默默转换为零。存在既定集成策略就按策略处理,否则停止并等待策略决定。Retry-After: 0 与缺失、无效都不同,但这几种情况均不能作为无限立即重试的理由。保守解析器还应报告不支持的形式,而非让宽松日期解析器接受任意看似日期的字符串。

共享队列与有限预算

每个工作进程各自等待,可能导致延迟结束时同时重新启动。应由一个派发器掌握已知配额范围的最早允许时间,而不是让每个浏览器同时决定恢复。范围未知时,暂停受影响集成的派发,不要虚构每个上下文独立的配额。这是约束负载的建议运行策略,不是在断言服务端采用相同内部分组。

至少保留三个独立预算:任务截止时间、最大尝试次数、剩余授权工作量。请求在时间上已经允许恢复,也可能因为截止时间已过或尝试次数耗尽而仍不合格。此时队列应给出终止结果,而不是将请求放回队头。把 attemptsUsed、eligibleAt 和 jobDeadline 保存在同一个建议任务记录中,便于检查决策。

退避与随机抖动是不同控制。文档策略可以在重复失败后延长等待,非负抖动则可以把允许的恢复时间进一步错开。两者都不应缩短服务端给出的有效等待。不要因为工作进程超时较短,就把 120 秒压缩成 10 秒;应停止任务,或者交给工作进程之外的机制延后处理。预算不足是放弃重试的理由,不是提前重试的理由。

重试安全性还取决于操作。数据读取与提交购买重复执行的后果不同。仅凭 HTTP 429,不能确定之前的业务操作是否已经改变状态。将改变状态的操作排除在通用抓取重试队列之外,并遵循集成文档的防重复规则。没有共同尝试预算时,不要在任务调度器和自动化库中嵌套重试;否则一个可见任务可能产生多次未计入的请求。

保留能够解释停止原因的记录

事件记录应把 HTTP 响应与调度决定联系起来。使用不透明的运行标识、测试环境或集成版本、浏览器与软件包版本,以及脱敏路由引用。记录响应时间、状态、请求角色、原始 Retry-After、解析状态、派发频率、在途计数和队列年龄。这些是有限诊断记录的建议字段,不代表所有浏览器都会自动提供。

观察项保留值支持的判断
响应状态、请求 ID 与接收时间某条具体请求收到了 429
响应头原值与解析状态等待已解析或仍然未知
范围文档规则或 unknown哪个队列被暂停以及原因
负载派发、在途工作与重试频率不同于工作进程数
预算尝试次数、截止时间与 eligibleAt等待、到期或停止
结果已接受记录或终止原因导航不等于数据被接受

将观察与策略分开。pauseReason=429 记录事件,resumePolicy=documented-window 记录选定规则。“可能是 IP 被封”即使保留,也应放入未经确认的假设字段,而非服务端事实列。这样后来的操作人员可以调整诊断,而不用改写响应实际包含的内容。

为有限观察窗口保留请求账本。失败尝试即使没有产生已接受记录,也计入派发总数。派发前取消与请求开始后取消分开统计。多资源页面保留请求角色,避免把图像请求频率变化误当成数据提取变化。响应内容只保留必要部分,隐藏秘密,并遵守相关留存政策。

事件结束后,恢复授权工作之前,比较实际生效配置与记录配置。检查是否另有进程共享同一文档配额、重试层是否重复启用,以及观察到的等待是否超过任务剩余时间。这些是具体配置问题。不能仅因后来的响应不同,就把新浏览器、新路由或新上下文认定为修复。

BotBrowser 配置与服务端策略

BotBrowser 的代理配置文档介绍 --proxy-server 和支持的路由配置。动态代理文档介绍通过浏览器级 CDP 会话修改 BrowserContext 代理。这些是配置能力,两份文档都不确定外部服务的计数键、重置窗口或允许请求频率。

诊断期间保持声明的路由稳定,避免无关变化遮蔽响应顺序。集成需要区分上下文与路由时,记录脱敏引用。BotBrowser 不保证不同上下文拥有不同服务器配额,不保证换路由消除 429,也不保证完成浏览器配置就取得访问授权。服务端施加的边界仍然约束任务负载。

常见问题

工作进程更少就一定请求更少吗?

不一定。快速完成、衍生资源和嵌套重试可能在工作进程减少后仍增加派发。应测量文档策略对应的请求数量和时间区间。

每个 429 都有 Retry-After 吗?

没有。RFC 6585 将它规定为可选项。应记录缺少指导,然后按集成既定策略处理或停止。

换代理能证明是按 IP 限流吗?

不能。结果改变不能确定原始计数规则。使用服务文档或自有服务器决策记录,不要换路由来规避配额。

重试时间已过就保证成功吗?

不保证。那是时间边界,不是预留容量或访问承诺。权限、操作安全性与剩余任务预算仍然适用。

来源

实践结论

从具体 429 响应和派发记录开始诊断。根据服务端证据确定范围,把并发与请求频率分开,并让解析后的时间边界和有限任务预算决定任何授权恢复。保留未知,不用身份猜测代替事实。眼下应先暂停新派发并保存响应,再考虑改变负载。

#网页抓取#Browser Automation#Network Diagnostics

本文属于指南: 代理配置总览:浏览器网络决策图

在 BotBrowser 里跑一遍同样的检查

加载 profile,让刚读到的这些信号在浏览器内部保持一致,并在正式上线前先在自己的机器上确认结果。