ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Puppeteer Browser.wsEndpoint() 详解:获取浏览器 WebSocket 端点并实现断线重连

Puppeteer Browser.wsEndpoint() 详解:获取浏览器 WebSocket 端点并实现断线重连 Puppeteer Browser.wsEndpoint() 详解获取浏览器 WebSocket 端点并实现断线重连【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteerBrowser.wsEndpoint()是 Puppeteer 中用于获取与当前浏览器实例通信的 WebSocket URL 的核心 API也是puppeteer.connect()进行连接已有浏览器或断线重连的关键输入。本文以 wsEndpoint 官方文档 为主体结合仓库源码讲清楚该方法的签名与返回值、标准用法、端点格式约定以及 CDP / WebDriver BiDi 两种协议下它在源码中的真实实现路径帮助你掌握获取端点 → 断开 → 重连的完整实战方案。方法签名与返回类型按照 API 文档该方法定义在抽象类Browser上是一个同步方法class Browser { abstract wsEndpoint(): string; }返回值string即连接该浏览器实例的 WebSocket URL。文档明确给出端点格式约定The format is alwaysws://HOST:PORT/devtools/browser/id.即返回的 URL 始终遵循ws://HOST:PORT/devtools/browser/id的形式其中id是浏览器自身的调试目标标识。这也意味着你拿到返回值后无需再做解析拼接可以直接透传给puppeteer.connect()。抽象声明位于 api/Browser.ts/** * Gets the WebSocket URL to connect to this Browser. * ... * remarks The format is always ws://HOST:PORT/devtools/browser/id. */ abstract wsEndpoint(): string;Browser的构造函数标记为内部internal第三方代码不应直接实例化或继承该类而应通过puppeteer.launch()或puppeteer.connect()获取Browser实例——参见 Browser 类文档。标准用法断开连接后用端点重连wsEndpoint()最典型的场景是先记录端点、断开、再重连。这是 Browser 类文档示例 2 给出的官方用法也是 api/Browser.ts 中 JSDoc 的原始示例import puppeteer from puppeteer; const browser await puppeteer.launch(); // 先保存端点以便之后重连。 const browserWSEndpoint browser.wsEndpoint(); // 断开 Puppeteer 与浏览器的连接浏览器进程仍在运行。 await browser.disconnect(); // 使用端点重新建立连接 const browser2 await puppeteer.connect({browserWSEndpoint}); // 关闭浏览器。 await browser2.close();这里有两个容易混淆的语义值得对照 disconnect() 文档注意区分browser.disconnect()仅断开 Puppeteer 侧的连接浏览器进程继续存活因此之后可以用wsEndpoint()拿到的 URL 重新接上browser.close()关闭浏览器进程及其所有页面端点随之失效。也就是说可重连的前提是浏览器进程没有被close()这一点正是wsEndpoint()disconnect()组合的价值所在让 Node 侧会话可断开、可迁移例如跨进程、跨 Worker 传递端点字符串。不从 Puppeteer 启动时如何获得端点当浏览器不是由puppeteer.launch()拉起的例如你自己用命令行启动 Chrome、或浏览器跑在远程机器 / Docker 容器里就无法调用browser.wsEndpoint()此时需要按文档说明手动获取调试器 URLYou can find the debugger URL (webSocketDebuggerUrl) fromhttp://HOST:PORT/json/version.即向浏览器调试 HTTP 端点发送 GET 请求从 JSON 响应中取出webSocketDebuggerUrl字段。这一做法在源码中同样得到印证BrowserConnector.ts 的getWSEndpoint()内部就是fetch(/json/version)并读取data.webSocketDebuggerUrl。对应到puppeteer.connect()上有等价的两种方式// 方式一直接给 WebSocket 端点 const browser await puppeteer.connect({ browserWSEndpoint: ws://HOST:PORT/devtools/browser/id, }); // 方式二只给 HTTP 端点Puppeteer 自动走 /json/version 换取 ws 端点 const browser await puppeteer.connect({ browserURL: http://HOST:PORT, });源码纵深端点在两种协议下的实现wsEndpoint()在抽象层只声明契约真实返回的 URL 来自当前连接持有的端点地址。仓库中packages/puppeteer-core/src下共有三处涉及wsEndpoint的实现/声明分别对应抽象基类和 CDP、BiDi 两套协议CDP 实现cdp/Browser.tsoverride wsEndpoint(): string { return this.#connection.url(); }CDP 版Browser直接返回内部Connection对象记录的服务端 URL。而这个 URL 最初从哪来看 node/BrowserLauncher.ts 的createCdpSocketConnection()const browserWSEndpoint await browserProcess.waitForLineOutput( CDP_WEBSOCKET_ENDPOINT_REGEX, opts.timeout, ); const transport await WebSocketTransport.create( browserWSEndpoint, undefined, opts.logger, ); return new Connection(browserWSEndpoint, transport, ...);即puppeteer.launch()启动浏览器子进程后用正则CDP_WEBSOCKET_ENDPOINT_REGEX定义于 packages/browsers/src/launch.ts从浏览器 stdout 首行输出中提取ws://...端点再以该端点构造Connection。所以launch 时的wsEndpoint()返回值本质上是从子进程输出捕获到的那个 URL与http://HOST:PORT/json/version返回的webSocketDebuggerUrl是同一个东西。WebDriver BiDi 实现bidi/Browser.tsoverride wsEndpoint(): string { return this.connection.url; }BiDi 版Browser返回 BiDi 连接持有的 URL。注意从源码结构看BiDi 场景下的端点路径形态由底层 BiDi 实现决定文档中alwaysws://HOST:PORT/devtools/browser/id的强格式约定主要针对 CDPChrome场景Firefox 等走 WebDriver BiDi 协议时端点语义相同可用于puppeteer.connect()重连但路径细节以实际连接对象为准。Puppeteer.connect() 如何消费这个端点wsEndpoint()的返回值作为browserWSEndpoint传给puppeteer.connect()后BrowserConnector.ts 的getConnectionTransport()处理它其中有两条值得注意的源码事实互斥校验browserWSEndpoint、browserURL、transport、channel四个选项必须且只能指定一个否则抛出Exactly one of browserWSEndpoint, browserURL, transport or channel must be passed to puppeteer.connect协议分流建立 WebSocket 传输后_connectToBrowser()会根据protocol选项选择_connectToBiDiBrowser或_connectToCdpBrowser。因此用wsEndpoint()重连时如果原浏览器是 BiDi 协议启动的重连也应带上相同的protocolConnectOptions.ts 中protocol默认按 CDP 连接处理。此外ConnectOptions还支持headers仅 Node.js 环境生效用于给 WebSocket 握手附加请求头便于反向代理鉴权等参数完整参数说明见 connect() 文档。测试用例佐证仓库测试直接验证了wsEndpoint()驱动的重连后行为语义。browser.test.ts 中的should not return child_process for remote browserconst browserWSEndpoint browser.wsEndpoint(); using remoteBrowser await puppeteer.connect({ browserWSEndpoint, protocol: browser.protocol, }); expect(remoteBrowser.process()).toBe(null);该用例印证了两点其一launch()得到的端点可以直接用于connect()其二通过connect()建立的Browser不持有子进程句柄process()返回null——这与 process() 文档 的说明一致。换言之重连回来的Browser管连接管不了进程如果你需要终止浏览器进程只能调用browser2.close()向浏览器发送关闭命令而非依赖本地 ChildProcess。实战要点小结场景获取端点的方式备注puppeteer.launch()启动browser.wsEndpoint()端点来自子进程 stdout 捕获可直接重连自建 / 远程 / 容器化浏览器GET http://HOST:PORT/json/version取webSocketDebuggerUrl等价于connect({browserURL})的自动流程重连puppeteer.connect({browserWSEndpoint})注意带上与原浏览器一致的protocol断开后再连disconnect()而非close()close()会终结进程端点失效使用wsEndpoint()时请牢记它返回的是纯字符串同步取值没有任何异步开销它反映的是 Puppeteer 当前实际连接的服务端地址因此在launch → 断连 → 重连生命周期中是最可靠的连接凭据。配合 disconnect()、connect() 与 Browser 类总览即可覆盖绝大多数分布式或长生命周期浏览器会话管理需求。【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表