返回知识中心
对比

Web Unblocker 与抓取 API:能做什么,何时不该用

托管解锁服务返回的是数据,不是会话。这一请求形态决定了它适合哪些任务,以及哪些任务需要你自有的浏览器。文中给出成本框架。

BotBrowser Team

文档中心

想直接进入 文档 文档吗?

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

托管解锁服务用一个 HTTP 请求换取数据,随后便不再保留任何东西,而这一请求形态几乎决定了它的全部适用范围。BotBrowser 提供声明式配置,使页面可读取的各项表面在多次启动之间保持一致,但不能替代代理池、托管机群或重试服务。仔细阅读供应商文档即可看清这一类产品真正出售的东西:一条掌握路由、重试、渲染和自有指纹生成的请求流水线,以及一个在有限时间窗内固定代理的会话标识,而不是一个始终保持同一身份的浏览器。

摘要

  • 解锁服务是一条请求流水线:你发送 URL,收到结果,之后没有可供检查的浏览器进程。
  • 文档列明的组成包括路由、重试、JavaScript 渲染,以及由供应商完成的指纹生成。
  • 连续性有边界且范围明确:某供应商文档记载的会话标识最多把代理保留十分钟。
  • 这是出口连续性,不是浏览器身份连续性,两者回答的是不同需求。
  • 托管服务适合一次性提取、小规模任务,以及不需要登录的任务。
  • 当需求是跨越多天保持同一个可识别浏览器,或请求内容不能离开自有边界时,它并不合适。
  • 成本比较本质上是利用率问题,下面的框架在不引用任何报价的情况下计算双方。

目录

两组方案对比。托管解锁服务接收 URL 并返回数据,路由、重试、渲染与指纹生成都在供应商内部完成。自有浏览器在多次运行之间保留配置文件、程序二进制和启动配置。底部的四个问题决定任务属于哪一侧。

这一类产品实际出售什么

文档对组成说明得异常明确,因此这一节可以很短。Oxylabs 将 Web Unblocker 描述为一种由 AI 驱动的代理方案,负责代理类型管理、浏览器指纹生成、自动重试、会话维持和 JavaScript 渲染。Browserless 通过 REST 端点表达同一思路:一个 HTTP 请求执行一个浏览器任务并返回结果,而不是返回一个会话。

you send      -> https://unblock.oxylabs.io:60000  (proxy endpoint) or /content, /scrape (REST)
you receive   -> HTML, JSON or an image, once
you do not get-> a browser process, a profile directory or a build you chose

这份清单里有两个细节比主要卖点更重要。第一是指纹生成:它由供应商生成,这意味着你无法把它跨天保持不变。第二是重试:供应商决定何时重试,这很方便,直到你需要知道某个响应是否经过一次额外尝试才返回,还是第一次就返回;而文档中的计费规则只让你为账单上看得见的那次尝试付费。

这不是批评。对很大一类任务来说,请求流水线是正确的形态,这也是该类别存在的原因。关键在于形态就是形态:它决定了你事后能够断言什么。

这一形态也决定你能比较什么。团队在托管流水线与自有浏览器之间做选择,实际上是在两种保护模型之间做选择,浏览器内核相对于注入脚本覆盖所改变的内容解释了为什么部分保护可能比毫无保护更具辨识度。托管流水线由构造保证一致,因为所有值都由同一个系统生成;自托管浏览器只有在配置文件声明了全部值时才保持一致。

assertable after a request    -> status code, body, latency, credit cost
not assertable               -> which browser build ran, which profile, which fingerprint

请求形态带来的限制

发送一个 URL 并收到一个结果,带来三项限制,每一项都有文档依据,而不是推测出来的。

第一项是有边界的连续性。Oxylabs 文档记载了 X-Oxylabs-Session-Id 头,它把某个代理分配给一个会话标识,最长十分钟,之后会重新分配代理。这是真实功能,对多步骤流程很有用。它同时也是代理亲和窗口,而不是持久的浏览器身份:十分钟后出口发生变化,响应中没有任何信息告诉你浏览器在之前或之后是什么样子。

session id -> one proxy for up to 10 minutes -> new proxy afterwards
             (egress continuity, not browser continuity)

第二项是指纹在供应商内部生成。功能列表直接写明了这一点,架构也决定了如此:每分钟处理数千请求的服务不可能从磁盘读取你的配置文件。它能做的是为每个请求生成一份自洽的指纹,文档所承诺的正是这一点。对读者而言,结论很窄:如果需求是“周一和周五是同一个浏览器”,就不该在这一层提出。

第三项是数据路径。经过托管流水线的请求会把 URL、你设置的请求头、你传入的 cookies 以及响应体都带给第三方。对公开页面这通常可以接受;凡是涉及登录、客户标识或合同约定的数据驻留条款,通常就不可以。这属于合规事实,不是产品缺陷,而且它应当排在价格之前进入决策。

第三项限制附带一个可执行的测试,短到可以在签约前完成。列出请求携带的字段:URL、每一个请求头、每一个 cookie、请求体以及响应。然后逐个字段问,它能否合法地离开任务运行的环境。只要有一个字段不能,托管流水线就不适合该目标,无论它表现多好;替代方案也不是换一家更好的供应商,而是把浏览器放在边界之内。

allowed to leave -> public URL, no cookies, no account identifiers
not allowed      -> session cookies, bearer tokens, customer records, regulated data
leaves your perimeter -> target URL, request headers, cookies, response body
stays with provider   -> retry history, generated fingerprint, routing decision

还有两项属性影响可复现性。托管流水线按自己的节奏升级,因此相隔一个月的两个相同请求可能由不同的内部组件处理;计费模型计量流量,因此你收到的 body 大小与请求数同样重要。文档中的重试规则是令人安心的一半:以成功结束的内部重试只计费一次。两者都不是隐藏的:它们出现在文档和控制面板里,而不是出现在响应里。

还有第四项限制,往往在真正出问题之前容易被忽略:端点使用 HTTP,因此你对浏览器的唯一杠杆就是供应商文档列出的请求头集合。Oxylabs 为 Web Unblocker 提供自定义浏览器指令和 JavaScript 渲染头,两者都确实有用。但它们都不能让你断言运行的是哪个构建、安装了哪些字体、走了哪条 GPU 路径,因为浏览器在端点之后,而不在你面前。针对托管端点编写的测试可以断言数据;它不能断言浏览器,任何相反的说法描述的都是供应商内部的生成过程,而不是你的复现。

assertable through the endpoint -> status, body, latency, credits spent
assertable only on a browser    -> build, profile, fonts, GPU, extensions, timing

这也是托管服务不适合回归测试套件的原因。把昨天的截图与今天的截图对比,需要两张图来自同一浏览器构建、相同字体和相同设备像素比;而托管端点会在机群中刻意变化这三项,以通过指纹检查。让它在目标站点上奏效的多样性,也正是让它无法充当固定基准的原因。

务实的应对是分工,而不是选出赢家。当问题是“这个 URL 是否返回数据”时,使用托管端点;当问题是“这个页面是否仍按原来的方式渲染”时,使用你自行运行的浏览器。两个问题都合理,只是需要不同的工具。

托管服务何时是合适的工具

最清楚的描述方式是一组必须同时成立的条件,因为满足五项中四项的任务通常属于别处。

  • 你需要的是数据而不是会话,因此下游没有任何环节需要驱动页面。
  • 任务是一次性的,或规模小而稳定,此时维护机群的成本高于节省的成本。
  • 请求之间不需要保留登录状态,因此十分钟的亲和窗口已经足够。
  • 请求内容是公开的或不敏感的,因此数据路径中有第三方可以接受。
  • 你不需要复现浏览器本身,只需要复现提取结果。

当这些条件成立时,托管流水线在所有重要意义上都更便宜:一个 HTTP 请求替代一个进程,带响应体的 200 就是全部契约。没有机器要维护,没有浏览器要升级,也没有代理池要做健康检查。这就是这一类产品的用途,确切需要这些能力的团队不需要自建。

第二种合理用法是在新目标上做一次初步验证。先通过托管服务发送少量请求,可以在有人编写浏览器测试框架之前回答页面是否返回数据,而答案只需要几个额度。按层诊断抓取被拦截是把这个初步验证变成决策而不是习惯的方法,参见抓取被拦截的分层诊断。

第三种是目标不断轮换的负载。一个每天查看两百个互不相关公开页面的监控任务,很难从持久浏览器中获得多少好处,因为每个页面都是不同来源,真正重要的是单次请求内的自洽性,而不是连续性。托管路由直接解决这种情况:供应商为目标选择适合的出口,任务永远不必知道那是什么。同一任务若使用自托管浏览器,就需要按并发目标数量确定代理池规模,并规定每个来源看到哪个出口,这比任务本身所能证明的机械复杂度更高。

one origin, many runs      -> continuity matters; a browser you own
many origins, one run each -> coherence per request; a hosted pipeline

何时它是错误的工具

镜像条件同样具体,每一条都指出请求形态无法满足的需求。

  • 同一个浏览器在下周仍需可识别,因此身份必须比请求活得更久。
  • 数据不能离开你的基础设施,无论是出于驻留、合同还是客户义务。
  • 你需要固定浏览器构建,因为布局或编解码差异会改变结果。
  • 你需要重放一次完全相同的会话以比较两次运行,这要求持有会话,而不是重新请求。
  • 你需要按身份持久保存数天的状态,这对应配置文件目录,而不是会话头。

在这些情况下,浏览器必须运行在你控制的地方,而托管服务原本吸收的工作会变得明确:安装固定构建、保留配置文件目录、维持显示器或容器健康,并记录运行了什么。固定 Chrome for Testing 版本是这项工作中与产物有关的一半,而Browserless 与自托管浏览器则是相邻决策:当身份仍归你所有时,进程应该放在哪里。

最后一项条件最容易让团队意外,值得说清楚。重放一次完全相同的会话,意味着在两次观察之间持有浏览器,而不是把同一个请求发送两次。托管端点做不到,因为第二个请求按构造就是新会话;自有浏览器可以,因为配置文件目录和进程仍然存在。当报告声称“周二时它是可行的”,检验这句话的唯一办法就是回到同一个浏览器,这是一种能力,而不是便利。

replay definition -> same process, same profile, same build, second observation
not a replay      -> same URL sent again through a stateless endpoint
hosted unblocker  -> you own: the query, the parsing, the decision to retry
self-hosted       -> you own: the binary, the profile, the pool, the display, the record

如实计算成本

没有你的工作负载,任何一侧都不是一个具体数字;但两侧都可以计算,把公式写下来比读别人的价格更有用。

hosted monthly    ~= consumed_traffic x unit_price    (request bytes + response bytes)
self-hosted cost  ~= machines x hours + ops_hours x loaded_rate + egress
crossover         -> where hosted_traffic x unit_price equals the fixed side

两项修正让这套算术更诚实,而且都来自供应商自己的计费页面,而不是对代理池如何运作的猜测。第一,计量的是流量而不是请求数:Oxylabs 对成功抓取的数据收取请求字节与响应字节,所以大的 JSON body 比小的更贵,压缩差异会改变账单而请求数不变。第二是重试规则,它与多数人的直觉相反。当一个请求内部尝试三次而最后一次成功时,文档说明只对最后一次成功尝试所消耗的流量计费;当供应商自身以 5xx 失败时,该次尝试不计费。文档记载的例外方向相反:由客户端造成的失败仍然计费,所以格式错误的请求或错误的凭据可能消耗流量却不返回数据。

一个算例可以在不引用任何供应商费率的情况下把形态说具体。假设任务每月发出五万个请求,其中十分之一需要一次额外的内部尝试才能成功,合计五万五千次尝试。按文档中的规则,计费单元仍是五万个成功请求,因为成功请求内部的额外尝试不单独计费。真正会变动的是流量:如果每次成功在请求与响应之间消耗两百千字节,该月就是十吉字节的计费流量;页面体积翻倍的目标,对账单的影响是重试率翻倍的两倍。在自托管一侧,同一任务可以放进两台机器上少数几个并发浏览器,每天运行八小时;算术就是机器小时加上有人升级它们所花的时间。

requests issued          50000
internal attempts        55000  (1 in 10 needs one extra)
billed successful units  50000  (only the last, successful attempt)
billed traffic           ~10 GB at 200 kB per success
low, spiky volume   -> per-request billing follows the spikes; hosted usually cheaper
high, steady volume -> fixed machines amortise; self-hosted usually cheaper
either way          -> the identity requirement is not in this arithmetic at all

免费额度值得一句直白的说明,而不是轻视,因为围绕这一类产品的搜索中有很大一部分正是在找它。供应商会公布免费额度,Oxylabs 还记录了欢迎额度。免费额度是评估流水线的正当方式;但它不是运行需要并发的工作负载的方式,因为已公布的免费层会限制并发会话数和会话时长。在免费层上构建之前先读清上限,是试点与故障之间的区别。

开源替代方案是这些搜索寻找的另一类东西,同样值得直白对待。自托管解锁服务确实存在,它基本上就是上文所述的浏览器池工作,再加上路由层和面向检测器的报告循环,是需要维护的大量代码。当规模稳定且身份要求真实时,它值得投入;但如果只是为了避免为一个每周运行两次的任务付费,它并不值得,因为代理池的运营成本主要来自有人盯着它的时间,而不是它使用的机器。无人看管的池会在某个周六悄悄失败,而它替代的订阅付的正是这份注意力。

free tier        -> good for a pilot, capped on concurrency and session length
open-source      -> good at steady volume, costs engineering hours to operate
paid per request -> good for spiky or low volume, follows the spikes

实践结论

按顺序问四个问题。输出需要是数据还是会话?任何状态是否需要比供应商窗口活得更久?请求内容是否必须留在你的边界之内?浏览器本身是否需要可复现?回答“数据、否、否、否”的任务属于托管解锁服务,十分钟的会话头对它已经足够。回答“会话、是、是、是”的任务属于你运行的浏览器,无论怎样调整托管请求都无法替代。

需要避免的失败模式是混合情形:团队从托管流水线开始,加上登录,再加上持久化需求,然后不断扩展请求,直到它变成用重试拼出的浏览器测试框架。到那时,诚实的做法是运行浏览器、保留配置文件,只把托管服务用于仍然符合请求形态的目标。

这两项改变的成本都低于替代方案,也就是无人能复现其行为的流水线。记录每个目标使用哪一侧以及原因;无头浏览器抓取:真正改变的是什么列出了浏览器站到你这一侧之后发生变化的事项。

来源

#Web Unblocker#抓取 API#托管抓取#代理池#成本模型

在 BotBrowser 里跑一遍同样的检查

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