首页
/ Puppeteer Browser.target() 详解:获取默认浏览器上下文对应的 Target 及其 CDP 与 BiDi 两种实现

Puppeteer Browser.target() 详解:获取默认浏览器上下文对应的 Target 及其 CDP 与 BiDi 两种实现

2026-09-04 15:31:31作者:农烁颖Land

Browser.target() 是 Puppeteer 中用于获取与默认浏览器上下文(default browser context)关联的 Target 对象的 API。读懂它能帮助你理解 Puppeteer "浏览器 → 上下文 → 目标" 的层级模型,并掌握在 CDP 与 WebDriver BiDi 两种协议实现下该方法的真实行为差异——这在编写跨浏览器自动化逻辑、排查 "Browser target is not found" 错误时非常有用。

API 概述

按照 官方 API 文档 的定义,该方法的功能是:

Gets the target associated with the default browser context.

方法签名为:

class Browser {
  abstract target(): Target;
}
  • 返回类型Target(同步方法,不返回 Promise)
  • 方法性质abstract,即抽象方法。Browser 只是声明契约,具体行为由各协议实现类(CDP 的 CdpBrowser、BiDi 的 BidiBrowser)分别提供

它返回的是 Target 类实例。在 Puppeteer 中,Target 表示一个 CDP 意义上的"可调试实体"——页面(page)、frame、Worker、Service Worker,乃至浏览器本身都是一个 Target。相关方法还包括:

方法 说明
browser.target() 返回默认浏览器上下文关联的 Target
browser.targets() 返回所有活跃 Target 的数组(跨所有浏览器上下文)
browser.waitForTarget(predicate) 等待匹配谓词的 Target 出现,如 window.open 打开的新窗口

源码实现:CDP 与 BiDi 的行为差异

target() 的抽象声明位于 packages/puppeteer-core/src/api/Browser.ts

/**
 * Gets all active {@link Target | targets}.
 *
 * In case of multiple {@link BrowserContext | browser contexts}, this returns
 * all {@link Target | targets} in all
 * {@link BrowserContext | browser contexts}.
 */
abstract targets(): Target[];

/**
 * Gets the {@link Target | target} associated with the
 * {@link Browser.defaultBrowserContext | default browser context}).
 */
abstract target(): Target;

值得注意的是,targets()target() 是紧邻声明的一对姊妹方法:前者列出全部可用目标,后者只取"浏览器级"那一个。

CDP 实现:从目标列表中查找 browser 类型

在 CDP 协议实现中,target() 位于 packages/puppeteer-core/src/cdp/Browser.ts

override target(): CdpTarget {
  const browserTarget = this.targets().find(target => {
    return target.type() === 'browser';
  });
  if (!browserTarget) {
    throw new Error('Browser target is not found');
  }
  return browserTarget;
}

从源码结构看,CDP 版本的实现逻辑是:

  1. 调用 targets() 获取当前所有已暴露且初始化成功的 Target(targets() 内部会过滤掉 _isTargetExposed() 为 false 或初始化未成功的目标);
  2. 在其中查找 type() === 'browser' 的目标,即浏览器进程自身对应的 Target;
  3. 若找不到,直接抛出 Error: Browser target is not found

因此有两个实际使用要点:

  • 这是同步方法,调用时如果目标尚未注册(例如连接刚建立、TargetManager 还未收到初始的 Target 列表),可能拿不到浏览器 Target 而抛错;
  • 返回的是 CdpTarget,可继续调用 Target.createCDPSession()Target 类方法。

BiDi 实现:直接返回预置的 BidiBrowserTarget

在 WebDriver BiDi 实现中,target() 位于 packages/puppeteer-core/src/bidi/Browser.ts

override target(): BidiBrowserTarget {
  return this.#target;
}

BiDi 版本的实现更为直接:BidiBrowser 在构造时已持有一个 BidiBrowserTarget 实例(this.#target),target() 只是原样返回它。同样的模式也体现在 BidiBrowser.targets() 中——列表的首个元素就是这个浏览器级 Target,其余元素来自各浏览器上下文的 context.targets() 扁平展开。

从源码结构看,两种实现存在明显的设计差异:

  • CDP:Target 列表是"事件驱动 + 动态过滤"的,target() 是一次运行时查找,存在查不到的失败路径;
  • BiDi:浏览器 Target 在连接建立时就已物化,target() 是"恒可用"的直接返回,没有失败分支。

对上层代码而言,由于两者都实现同一个 abstract target(): Target 契约,调用方写法完全一致,这正是 Puppeteer API 抽象层(api/Browser.ts 下的抽象类 + cdp/bidi/ 下的具体实现)的典型分层模式。

与 Page.target() 的对照

不要混淆 browser.target()Page.target()

  • browser.target() 返回的是浏览器级 Target(类型为 browser);
  • page.target() 返回的是该页面对应的 Target,例如 CDP 实现中 CdpPage.target() 会返回页面自身的 CdpTarget

如果你已经持有一个 Page 对象,通常优先用 page.target() 拿到页面目标,再用它的 createCDPSession() 建立 CDP 会话,而不必绕道 browser.target()

典型使用场景

browser.target() 的返回值虽然"只是"一个 Target,但它打通了几条实用路径。结合 Target 类文档,常用组合如下:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();

// 获取浏览器级 Target
const browserTarget = browser.target();
console.log(browserTarget.type()); // 'browser'

// 基于浏览器级 Target 创建 CDP 会话(仅限 CDP 浏览器)
// 可用于发送 Browser.* 系列等命令
const session = await browserTarget.createCDPSession();

// 对照:遍历所有 Target
for (const target of browser.targets()) {
  console.log(target.type(), target.url());
}

await browser.close();

另外,当需要等待某个目标出现(比如 window.open 产生的新窗口)时,应使用 browser.waitForTarget() 而非反复轮询 targets()抽象定义中的示例展示了标准写法:

await page.evaluate(() => window.open('https://www.example.com/'));
const newWindowTarget = await browser.waitForTarget(
  target => target.url() === 'https://www.example.com/',
);

注意事项与适用前提

  1. 同步返回,但存在失败路径(CDP):CDP 实现中若找不到 browser 类型目标会抛 Browser target is not found。一般发生在连接刚建立、目标列表尚未同步完成的瞬间,建议在 launch() / connect() 完成、或至少创建过页面之后再调用;
  2. BiDi 实现无失败路径:从 BidiBrowser 源码 看,目标在构造时即已就绪;
  3. 返回的是 Target 而非 Page:如需操作页面,仍应通过 Target.page()(或 asPage())转换,page() 仅对 "page""webview""background_page" 类型返回非空值;
  4. 协议差异createCDPSession() 等 CDP 专属能力只对 CDP 浏览器有效,在 BiDi 浏览器下调用同类方法会受到协议能力限制。

小结

Browser.target() 是一个小而关键的 API:它以同步方式返回与默认浏览器上下文关联的浏览器级 Target。本文梳理了它的抽象声明位置(api/Browser.ts)、CDP 的"查找 + 抛错"实现(cdp/Browser.ts)与 BiDi 的"直接返回预置目标"实现(bidi/Browser.ts),并区分了它与 targets()waitForTarget()Page.target() 的分工。掌握这些细节后,你在跨协议编写自动化代码时,就能准确预期该方法的返回时机与失败条件。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.83 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
987
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384