mcpField
H
headless-browser

headless-browser

github.com/oxylabs开发87762 次安装2 周前更新
代码仓库

关于 headless-browser

面向开发者的 Oxylabs Headless Browser 技能指南,通过远程 Chrome 会话执行网页采集。内容涵盖 CDP 连接、会话管理、代理与地域参数,以及错误处理和调试流程。

主要功能

  1. 01通过 WebSocket 连接远程 Chrome
  2. 02Playwright、Puppeteer 和 CDP 指南
  3. 03重试与错误处理规则
  4. 04会话配置文件与恢复
  5. 05实时检查与录制说明

适用场景

  1. 01使用 Playwright 或 Puppeteer 采集网页
  2. 02处理会话重连和故障
  3. 03在多个任务间保留登录状态
  4. 04通过检查功能调试页面行为

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/oxylabs/agent-skills --skill headless-browser

安装后在 Claude Code 中输入/headless-browser确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

errors.md
examples.md
parameters.md
targets.md
scripts/
playwright_scrape.js
playwright_scrape.py

详细介绍

Oxylabs 无头浏览器

内置反检测、代理轮换和地理定位功能的远程 Chrome 会话。 所有操作都不会在本地运行:通过 WebSocket 连接,使用你已经在用的 CDP 库控制浏览器,完成后关闭会话。本文件列出规则;详细信息见相关文件: scripts/(可复制的模板)、parameters.md、errors.md、examples.md、targets.md。

1. 连接

项目值
端点wss://USERNAME:[email protected]
凭证OXY_UNBLOCKER_USERNAME / OXY_UNBLOCKER_PASSWORD(别名:OXY_HB_USERNAME / OXY_HB_PASSWORD)
选项仅使用 URL 查询参数,例如 ?p_cc=US&session_name=job-42(参见 parameters.md)
库Playwright chromium.connectOverCDP(推荐)、Puppeteer puppeteer.connect、任何 CDP 客户端
控制面板 / 支持https://hb.oxylabs.io/dashboard · [email protected]

以下规则可避免最常见的 401 错误:

  • 使用 wss://。虽然也接受纯 ws://,但它会以未加密方式发送密码。
  • 使用字符串拼接构建 URL,并使用原始密码。不要将完整 URL 传给 new URL() 或 urllib.parse:它们会对密码进行百分号编码,导致身份验证失败。
  • 使用控制面板中显示的完整用户名,包括 _ab12 之类的后缀。
  • URL 中无法发送包含 : 的密码。请申请新密码,或自行发送 Authorization: Basic 标头(参见 examples.md)。
  • 身份验证会先于参数进行检查:先解决 401,再检查其他问题。

2. 快速入门

最简示例(Playwright,JavaScript):

const { chromium } = require("playwright");
const url = `wss://${process.env.OXY_UNBLOCKER_USERNAME}:${process.env.OXY_UNBLOCKER_PASSWORD}@hb.oxylabs.io?p_cc=US`;
const browser = await chromium.connectOverCDP(url, { timeout: 60000 });
try {
  const page = await browser.contexts()[0].newPage(); // default context: backed by fingerprint, proxy, o_profile
  await page.goto("https://example.com", { waitUntil: "domcontentloaded", timeout: 30000 });
  console.log(await page.content());
} finally {
  await browser.close(); // always: an unclosed session keeps its concurrency slot
}

实际使用时,请完整复制 scripts/playwright_scrape.js 或 scripts/playwright_scrape.py,而不要重新实现。这些脚本加入了本文件其他内容所依赖的五种行为:

  • 带退避机制连接(基准间隔 1 秒,上限 60 秒,加入随机抖动,最多尝试 6 次),但仅针对可重试错误:429、5xx、 CDP_SESSION_IN_USE、CDP_NO_BROWSERS_AVAILABLE、CDP_BROWSER_OVERWORKED、CDP_BAD_PROXY、 CDP_GENERAL_ERROR、超时。400/401/403 表示请求有误:请修正,切勿原样重试。
  • 从所有错误消息中隐藏密码后再记录;Playwright 会在错误消息中嵌入连接 URL。
  • 默认阻止 image、stylesheet、media、font;这些内容会耗费时间,数据提取时并不需要。
  • 在导航前注册监听器:响应标头 X-Error-Description 用于标记页面流量中 Oxylabs 端的错误。
  • 在 finally 中调用 browser.close(),并为整个任务设置截止时间,确保即使会话卡住也能执行到此步骤。

Puppeteer、Python 异步、原始 CDP、会话移交、配置文件、录制和扇出:参见 examples.md。

3. 会话和限制

限制(账户默认值)值超出时
每秒新建会话数10429 CDP_SESSION_RATE_LIMIT_REACHED(空间启动间隔 >= 150 ms)
并发会话数100429 CDP_MAX_CONCURRENT_SESSIONS_REACHED
命名(可恢复)会话数5429 CDP_MAX_PERSISTENT_SESSIONS_REACHED
已存储的配置文件(o_profile)数5403 profile limit reached (5 profiles maximum)
录制数10403 recording limit reached (10 recordings maximum)
并发检查查看器数10CDP_VNC_MAX_CONCURRENT_SESSIONS_REACHED
  • session_name(^[A-Za-z0-9-]{3,36}$)可在断开连接后 10 分钟内恢复会话。 使用它即表示启用 keep_alive;切勿单独发送 keep_alive=true(400 keep_alive requires session_name)。
  • 如果旧连接仍处于连接状态,重新连接会返回 429 CDP_SESSION_IN_USE:请先关闭旧连接。
  • 每个会话的最长存续时间为 1 小时。请将长任务安排为多个会话。
  • 被遗弃的会话会继续占用并发槽位(约 20 秒;命名会话则为完整的 10 分钟),之后可能导致无关的 429 CDP_MAX_CONCURRENT_SESSIONS_REACHED。关闭 Playwright/Puppeteer 对象即可释放。
  • 即使命名会话仍可恢复,browser.close() 也会清除已打开的页面和 Cookie。要交接会话,请使用 Puppeteer browser.disconnect()(参见 examples.md 中的“恢复命名会话”)。需要在会话结束后保留的状态(登录信息、通行 Cookie)应放在 o_profile 中,而非依赖 keep-alive。
  • 每种不同的参数组合都会单独配置:请在整个任务期间保持参数集稳定。
  • 负载较高时,连接可能会排队,并在约一分钟后以 503 queue timeout 结束:请退避并重试。 可通过支持渠道申请更高的限制。

4. 错误

错误分为三个渠道。握手阶段:HTTP 状态码和简短响应正文(Playwright:WebSocket error: <URL with password> <status>,随后是响应正文;Puppeteer:Unexpected server response: <status>)。连接后:WebSocket 会以代码 3000 和 CDP_* 原因关闭,只有原始客户端能看到;Playwright/Puppeteer 只会报告 Target closed,因此会话开始后的前几秒内发生的断连都应视为可重试。页面内:某条被拒绝的命令会返回 CDP 错误 1337。对于页面流量,带有 X-Error-Description 的响应表示 Oxylabs 网络错误(重试);不带此标头的拦截页面则是目标网站的决定(更改方案,不要重试)。

connect failed?
  ├─ 401 ............ fix credentials/scheme, do not retry
  ├─ 400/403/409 .... fix the named parameter, do not retry unchanged (409: wait 30 s+ for the other session)
  ├─ 429 ............ backoff; if MAX_CONCURRENT: hunt for unclosed sessions
  └─ 5xx/503 ........ backoff, up to ~2 min total
session dropped (close 3000)?
  └─ new session with backoff; rotate sticky id on CDP_BAD_PROXY
navigate failed with 1337 Invalid target?
  └─ stop; restricted target (section 7)
page shows block / 403 wall?
  ├─ X-Error-Description present .... Oxylabs network issue: backoff + retry
  └─ absent ......................... target decision: change identity, geo, device, pacing (section 5)

每条消息的原因和解决方法:errors.md。

5. 目标安全性(DataDome 及类似服务)

大多数任务的默认参数集:仅 p_cc。 每个会话都会获得全新的指纹和住宅 IP,这正是单次抓取和独立页面并行抓取所需的。粘性 IP 和已存储的配置文件都是针对特定需求才选择使用的工具,绝不是默认设置。

受保护目标的操作顺序。 先编写普通脚本并确保其运行成功:每页使用一个全新会话,选择正确的地理位置和设备,按真人节奏操作,然后再按下方阶梯逐步升级。只有在尝试完阶梯后脚本仍然失败,才向用户建议使用持久配置文件(采用下方的设置端/使用端模式,并说明它为何可能有效以及代价:需要一个设置步骤,配置文件上限为 5 个),并且只有在用户同意后才实施。切勿自行添加配置文件或粘性 ID。

需求添加不适用于
多个连接必须看起来像同一位访客(登录、购物车、持续时间超过一个会话的流程)proxy_resi_ses_id + proxy_resi_ses_time每个会话只访问一个页面
Cookie 或登录状态必须在不同任务间保留(DataDome 放行状态、经过身份验证的抓取)用户同意后,由一次设置运行预先准备 o_profile首次尝试;不设拦截即可正常提供内容的目标
在 10 分钟内恢复同一个浏览器session_name其他所有情况

使用这些参数时,它们的组合代表一个身份。务必保持一致:

setup, exactly once :  ?o_profile=acme-us-01&o_profile_save=true&p_cc=US&proxy_resi_ses_id=acmeus01&proxy_resi_ses_time=30
consumers, any number:  ?o_profile=acme-us-01&p_cc=US&proxy_resi_ses_id=acmeus01&proxy_resi_ses_time=30
  • 一个运行实例写入配置文件,其他实例读取。 设置运行实例是唯一会发送 o_profile_save=true 的连接:它获取 Cookie(通过入口页面、登录),验证页面,然后关闭。使用运行实例仅发送 o_profile=<name>:只读,不加写锁,也不会出现 409。切勿由使用运行实例“补充”配置文件;如果配置文件失效,请使用新名称重新运行设置。在生产环境中,应由一个设置服务准备并验证配置文件,由一个使用服务仅负责使用它们(examples.md,“配置文件设置和使用运行”)。
  • proxy_resi_ses_id + proxy_resi_ses_time 会固定出口 IP(最长 1440 min)。固定 ID 会禁用自动代理重试:遇到 CDP_BAD_PROXY 时,请更换为新的 ID。
  • 对于已有 Cookie 的身份,切勿更改 p_cc/p_city/p_state。 请新建配置文件和粘性 ID。
  • 让交互方式匹配 p_device:mobile = 轻触、小幅滚动、不悬停;desktop(默认值)= 采用相反的操作方式。切勿自行设置视口或设备指标;指纹由服务管理。
  • 按真人节奏操作:页面加载间隔 3 到 8 s,点击前先滚动,每个身份一次只访问一个页面。并行运行多个身份,而不是打开并行标签页。
  • 被拦截时的升级步骤,每个全新连接逐级尝试:全新会话 → 扩大地理范围(移除 p_city)→ p_device=mobile → 放慢速度 → 检查(第 6 节)→ 向用户建议使用持久配置文件 → 停止并报告。重复完全相同的请求不算升级。

各供应商的拦截特征、注意事项表,以及新受保护目标的起始值:targets.md。

6. 运维规范

  • 调试。 有两种工具;每当用户询问如何调试、浏览器正在做什么,或运行为何失败时,都要告知他们这两种工具:实时检查(通过 CDP 命令 __session_id 获取会话 ID,打开 https://hb.oxylabs.io/novnc/?id=<id>,并在会话运行时查看)和录制(record=true& record_name=<job> 会将会话视频保存下来,以便之后在 https://hb.oxylabs.io/dashboard 中回放;上限为 10 个,可在那里删除旧视频)。两者默认均关闭。在同一目标上连续失败 3 次后,请自行使用这两种工具,确认页面实际显示的内容。代码片段见 examples.md 中的 "Session id, live inspection and recording"。
  • 超时。 连接超时为 60 s,导航超时为 30 s,另有整体任务截止时间。
  • 日志记录。 切勿记录连接 URL 或原始错误消息;记录参数集和会话 ID。
  • 上下文。 使用 browser.contexts()[0]。newContext() 与配置文件存储和指纹调优隔离。

7. 受限目标

默认禁止访问;需通过账户经理进行简短的 KYC 才能访问:娱乐和流媒体、银行和金融、政府网站、游戏平台、票务、网页邮箱、广告网络、第三方 IP 检查器。使用 https://ip.oxylabs.io/location 验证出口 IP 和地理位置。访问受限目标时,Page.navigate 会因 CDP 错误 1337 Invalid target 而失败。

另请参阅:scripts/(完整的 Playwright 模板、JS 和 Python)、parameters.md(所有参数及其验证)、errors.md(所有消息)、examples.md(Puppeteer、Python 异步、原始 CDP、重新连接、配置文件、录制、扇出)、targets.md(拦截检测、DataDome 操作手册)。

评论

支持 Markdown