概述
您只为一个数值付费:total。它是您的会话经过代理隧道的所有字节,在网络线路上计量。带宽明细中的其他字段都用于解释 total 的构成,方便您与自己的测量结果进行核对。
如果您使用 Chrome DevTools Protocol(CDP)的 Network.* 事件自行统计流量,得到的数值会与 total 不同,并且通常更低。这是正常的。差异来自以下三个方面:
- 会话开始前完成的工作。 对于部分网站,Browser API 会在您的目标页面加载前预热浏览器,例如先加载网站首页。这是我们以高成功率解锁网站的方式之一。预热发生在您的会话开始之前,因此您的脚本无法在 CDP 事件中看到这部分流量。它记录在
before_session中。 - 协议开销。 加密(TLS)握手和分帧会为每个连接增加字节。它们记录在
overhead_bytes中。 - Chrome 未向您的脚本报告的流量。 部分请求经过网络,但不会产生您的脚本所监听的 CDP 事件。它们记录在
client_hidden_bytes中。
在哪里查看带宽明细
同一个明细对象可在两个位置获取,只有字段名称不同。
1. 会话结束后,通过 Session Logs API 获取。 每条会话记录保留原有的
bandwidth 字段,即以数值表示的计费总量。明细位于新字段 bandwidth_breakdown 中。bandwidth 始终等于 bandwidth_breakdown.total。
GET /browser_sessions 会为列表中的每个会话返回相同的两个字段。
2. 在会话内部,通过 CDP 命令获取。 Browser.getBandwidth 仅返回明细对象,键名为 bandwidth。其字段与 API 中的 bandwidth_breakdown 相同。没有单独的数值字段,计费总量为 bandwidth.total。您可以随时调用该命令读取截至当前的带宽用量,例如在关闭浏览器之前调用。
Browser.getSessionId)相同。在会话中途读取的数值涵盖截至该时刻的流量,最终数值以 Session Logs API 为准。
带宽明细对象包含哪些字段
该对象在 Session Logs API 中名为bandwidth_breakdown,在 CDP 命令中名为 bandwidth。对象包含两组字段。计费字段描述您付费的内容。核对字段按照 Chrome 的视角描述流量,方便您与自己的 CDP 数值进行核对。核对字段永远不会在 total 之外额外计费。
所有数值的单位均为字节。
计费字段
total 始终精确等于 payload_bytes + overhead_bytes。
核对字段
两个明细中的资源类型:
document、script、stylesheet、image、font、media、other。
other 包括所有没有独立字段的资源类型:API 调用(XHR 和 Fetch)、下载、WebSocket 和 EventSource 连接、Web 应用清单、文本轨道、预取和预检请求、ping、CSP 违规报告以及签名交换。它还包括 Chrome 报告为 “Other” 或没有类型的资源,以及 Chrome 未来新增的任何类型。
session_bytes 如何统计
session_bytes 采用以下定义,与您通过标准 CDP 事件得到的结果一致:
- 请求: 请求行、请求头以及请求体(POST 数据)。
- 响应: 状态行、响应头以及传输时的响应体(
encodedDataLength)。gzip 或 Brotli 响应按压缩后的大小计算。 - 请求头和响应头按未压缩形式计算,即纯文本的
Name: value。在网络上,HTTP/2 会压缩头部,因此这部分会略大于线路上的字节数。
为什么您测量的数值与我们的计费不同
您的脚本和我们的计量器在两个不同的位置统计流量。您的脚本通过 Chrome 内部的 CDP 事件获知流量。我们的计量器在 Chrome 处理完成后,统计浏览器与代理之间网络连接上的加密字节。有些流量只存在于第二个位置,有些流量在两个位置的统计方式也不同。 这四类流量都会经过隧道,并计入total。只有第一类会以 CDP 事件的形式到达您的脚本。
差异来自哪里
哪些数值可以对上
- 精确相等:
total = payload_bytes + overhead_bytes,始终成立。 - 精确相等:
session_breakdown中的数值相加等于session_bytes,before_session_breakdown中的数值相加等于before_session。 - 接近,存在少量残差:
payload_bytes ≈ session_bytes + before_session + client_hidden_bytes。
before_session。预热可能很大,并且在不同会话之间变化明显,但它会完整记录在 before_session 中。
少量剩余差异(残差)
按如下方式计算残差:
预期情况:
- 正残差(
payload_bytes高于各字段能解释的数值):大多数情况下很小。 - 负残差(基于 CDP 的字段相加超过
payload_bytes):在请求头较多的页面上可达约 10%。这是头部压缩造成的,您按压缩后较小的大小计费。
total。它不是计量错误:total = payload_bytes + overhead_bytes 始终成立。残差的几种可能原因:
- 头部压缩。 HTTP/2 会在网络上压缩头部,而 CDP 报告的是未压缩的头部。这会使您的 CDP 总和_更高_,因此残差可能为负。
- 加密分帧和连接消息。 TLS 记录头和 HTTP/2 控制消息(SETTINGS、PING、WINDOW_UPDATE)属于连接本身,而不属于任何单个请求。
- 流式、长连接或已取消的请求。 Chrome 为这些请求报告的大小可能与实际经过网络的大小不同。
- 请求体。 上传数据在 CDP 中和线路上的计量方式不同。
- 重传的加密数据,以及隧道内的 TLS 握手。
session_id 联系支持团队。我们会逐一调查这类情况。
客户端常见的统计错误
以下错误会使 CDP 总和偏低,并让残差看起来比实际更大:- 使用解码后的大小。
Network.dataReceived.dataLength统计的是解压后的响应体,而不是网络上传输的数据。请改用Network.loadingFinished中的encodedDataLength。 - 只统计响应。 请求头和 POST 请求体同样是流量。
- 监听器挂载过晚。 在
Network.enable运行之前发出的请求不会报告给您。 - 只监听一个页面。 iframe、弹出窗口和 Service Worker 可能运行在各自独立的目标中,并有自己的事件。
- 忽略失败的请求。 被取消或中途失败的请求仍然传输了字节。请同时检查
Network.loadingFailed。
如何核对您自己的数值
按照以下步骤自行检查一个会话。- 使用与我们相同的定义进行统计。 在首次导航之前挂载监听器,并将请求行、请求头、POST 数据、状态行、响应头和
encodedDataLength相加。下面的示例就是这样做的。 - 将您的总和与
session_bytes比较。 两者应当接近。微小差异来自时序以及其他目标中的请求。 - 计入
payload_bytes的其余部分。 将before_session(预热)和client_hidden_bytes(Chrome 未通告的请求)加到session_bytes上。结果应接近payload_bytes:通常只略低于它,在请求头较多的页面上最多高出约 10%。然后加上overhead_bytes即得到total。 - 正残差明显超过百分之几? 请携带
session_id联系支持团队。我们可以详细查看该会话。
示例:使用 Puppeteer 统计字节
该脚本像您自己的代码一样根据 CDP 事件统计会话流量,然后将结果与Browser.getBandwidth 返回的带宽明细并排打印,方便您比较两者。
total 为准。
如何监控和控制带宽
按网站跟踪成本
带宽明细按会话提供,因此您可以在此基础上构建按网站的监控:- 每个会话结束后,从 Session Logs API 读取
bandwidth_breakdown(或在关闭浏览器前通过 CDP 命令读取bandwidth)。 - 将
total、before_session和session_bytes与目标域名一起存储。 - 当某个域名每个会话的典型
total大幅上升时发出告警。如果上升由before_session引起,说明该网站开始运行预热步骤。如果session_breakdown上升,可以看出是哪种资源类型增长,例如image或media。
设置消费上限
在区域的高级设置中设置消费上限。区域达到上限后,新请求将停止。这可以防止区域内所有网站出现意外的用量激增。减少会话内的带宽
您可以控制会话期间加载的内容。拦截不需要的资源类型,例如图片、媒体和字体。请参阅使用 Browser API 优化带宽使用。使用session_breakdown 查看哪些类型用量最大。拦截 other 中的流量时请谨慎:它包括通常用于加载所需数据的 XHR 和 Fetch 调用,拦截后往往会导致页面无法正常工作。
关于预热(before_session)
预热是 Browser API 以高成功率解锁网站的方式之一。它会自动运行,并且仅在成功加载目标页面需要时才针对相应网站运行。是否预热按网站决定,并可能随着网站调整防护措施而变化。您无法在 CDP 中看到预热,也无法在脚本中将其关闭。禁用验证码解算同样不会关闭预热。
如果某个网站之前没有预热、现在开始预热,或者 before_session 随时间增长,这可能是正常现象:预热会随着网站调整防护措施而自适应变化。