Doramagic 项目包 · 项目说明书

puppeteer 项目

生成时间:2026-05-16 04:41:15 UTC

Puppeteer项目概览

Puppeteer是一个由Google维护的Node.js库,它提供了高级API来通过Chrome DevTools Protocol控制无头Chrome或Chromium浏览器。Puppeteer本质上是Chrome浏览器的自动化工具,允许开发者以编程方式执行通常需要手动操作的任务。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 1.1 核心功能

继续阅读本节完整说明和来源证据。

章节 2.1 核心包结构

继续阅读本节完整说明和来源证据。

章节 2.2 主要包说明

继续阅读本节完整说明和来源证据。

1. 项目简介

Puppeteer是一个由Google维护的Node.js库,它提供了高级API来通过Chrome DevTools Protocol控制无头Chrome或Chromium浏览器。Puppeteer本质上是Chrome浏览器的自动化工具,允许开发者以编程方式执行通常需要手动操作的任务。

1.1 核心功能

功能类别说明
页面导航加载网页、访问URL、处理导航事件
内容抓取提取页面DOM、获取元素内容、截图
用户交互模拟键盘输入、鼠标点击、表单提交
性能监控跟踪网络请求、测量页面性能
设备模拟模拟移动设备、iPhone、Android等
浏览器扩展支持加载Chrome扩展程序

资料来源:README.md:1-15

2. 项目架构

Puppeteer采用monorepo架构,主要由核心包和配套工具组成。

2.1 核心包结构

graph TD
    A[Puppeteer] --> B[puppeteer-core]
    A --> C[@puppeteer/browsers]
    A --> D[@puppeteer/ng-schematics]
    
    B --> E[API层]
    B --> F[CDP通信层]
    B --> G[公共组件]
    
    E --> H[Page]
    E --> I[Browser]
    E --> J[BrowserContext]
    
    G --> K[Configuration]
    G --> L[Device]
    G --> M[LazyArg]
    G --> N[Debug]

2.2 主要包说明

包名用途
puppeteer完整包,包含浏览器下载功能
puppeteer-core轻量级核心库,不自动下载浏览器
@puppeteer/browsers浏览器管理和下载CLI工具
@puppeteer/ng-schematicsAngular集成工具

资料来源:README.md:1-10

3. 安装与配置

3.1 安装方式

# 完整安装(自动下载Chrome)
npm i puppeteer

# 仅安装核心库(不下载浏览器)
npm i puppeteer-core

3.2 启动选项配置

Puppeteer支持丰富的浏览器启动配置选项:

选项类型默认值说明
executablePathstring-指定浏览器可执行文件路径
ignoreDefaultArgs`boolean \string[]`false是否忽略默认启动参数
enableExtensions`boolean \string[]`-启用Chrome扩展
handleSIGINTbooleantrueCtrl+C时关闭浏览器
handleSIGTERMbooleantrueSIGTERM时关闭浏览器
handleSIGHUPbooleantrueSIGHUP时关闭浏览器
timeoutnumber30000启动超时时间(毫秒)

资料来源:packages/puppeteer-core/src/node/LaunchOptions.ts:1-50

3.3 全局配置

Configuration接口定义了全局配置选项:

interface Configuration {
  defaultBrowser?: SupportedBrowser;
  temporaryDirectory?: string;
  skipDownload?: boolean;
  logLevel?: 'silent' | 'error' | 'warn';
  experiments?: ExperimentsConfiguration;
  chrome?: ChromeSettings;
  firefox?: FirefoxSettings;
}
配置项说明
defaultBrowser默认浏览器类型,默认chrome
temporaryDirectory临时文件目录,默认为os.tmpdir()
skipDownload安装时跳过浏览器下载
logLevel日志级别,默认warn
chromeChrome特定配置

资料来源:packages/puppeteer-core/src/common/Configuration.ts:1-40

4. 核心API

4.1 Page类

Page类是Puppeteer最核心的类,继承自EventEmitter,负责页面操作和交互。

graph LR
    A[Page] --> B[事件监听]
    A --> C[页面导航]
    A --> D[元素查询]
    A --> E[函数暴露]

#### 4.1.1 常用方法

方法说明
goto(url)导航到指定URL
waitForSelector(selector)等待元素出现
click(selector)点击元素
type(selector, text)输入文本
evaluate(fn)在页面上下文执行JavaScript
screenshot()页面截图
setViewport()设置视口大小

#### 4.1.2 事件系统

Page类继承EventEmitter模式,支持以下典型事件:

page.once('load', () => console.log('Page loaded!'));

function logRequest(interceptedRequest) {
  console.log('A request was made:', interceptedRequest.url());
}
page.on('request', logRequest);
page.off('request', logRequest);

资料来源:packages/puppeteer-core/src/api/Page.ts:1-80

4.2 exposeFunction方法

exposeFunction允许将Node.js函数暴露给浏览器页面调用:

page.exposeFunction('readfile', async filePath => {
  return fs.readFile(filePath, 'utf8');
});

await page.evaluate(async () => {
  const content = await window.readfile('/etc/hosts');
  console.log(content);
});

资料来源:packages/puppeteer-core/src/api/Page.ts:100-140

4.3 Locators API

Locators是实验性的定位器API,提供更可靠的元素定位方式:

// 使用ARIA文本定位
await page.locator('::-p-aria(Search)').fill('automate beyond recorder');

// 使用文本内容定位
await page.locator('::-p-text(Customize and automate)').waitHandle();

// 使用组合选择器
await page.locator('.devsite-result-item-link').click();

5. 设备模拟

Puppeteer内置了丰富的设备模拟功能,通过KnownDevices对象提供:

import {KnownDevices} from 'puppeteer';

const iPhone = KnownDevices['iPhone 15 Pro'];
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.emulate(iPhone);
设备类别示例设备
iPhone系列iPhone 12, iPhone 15 Pro
iPad系列iPad Mini, iPad Pro
AndroidAndroid Phone, Android Tablet

资料来源:packages/puppeteer-core/src/common/Device.ts:1-30

6. @puppeteer/browsers CLI

@puppeteer/browsers包提供浏览器管理的命令行工具:

6.1 常用命令

# 安装Chrome稳定版
npx @puppeteer/browsers install chrome@stable

# 安装指定版本
npx @puppeteer/browsers install [email protected]

# 安装ChromeDriver
npx @puppeteer/browsers install chromedriver@canary

# 列出已安装浏览器
npx @puppeteer/browsers list

# 清除所有已安装浏览器
npx @puppeteer/browsers clear

6.2 系统要求

平台依赖
Linux/MacOSunzip
Windowstar.exe
Firefox下载(Linux)xz, bzip2
Firefox下载(MacOS)hdiutil

资料来源:packages/browsers/README.md:1-60

7. 工作流程示例

7.1 基础使用流程

graph TD
    A[启动浏览器] --> B[创建页面]
    B --> C[设置视口]
    C --> D[导航到URL]
    D --> E[执行操作]
    E --> F[提取数据]
    F --> G[关闭浏览器]
    
    D -.->|网络请求| H[request事件]
    E -.->|控制台| I[console事件]
    F -.->|截图| J[screenshot]

7.2 完整示例代码

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const page = await browser.newPage();

await page.setViewport({width: 1080, height: 1024});
await page.goto('https://developer.chrome.com/');

await page.keyboard.press('/');
await page.locator('::-p-aria(Search)').fill('automate beyond recorder');
await page.locator('.devsite-result-item-link').click();

const textSelector = await page
  .locator('::-p-text(Customize and automate)')
  .waitHandle();
const fullTitle = await textSelector?.evaluate(el => el.textContent);

console.log('The title of this blog post is "%s".', fullTitle);

await browser.close();

资料来源:README.md:15-40

8. 调试功能

Puppeteer提供内置调试支持,通过__PUPPETEER_DEBUG环境变量控制:

# 开启所有日志
window.__PUPPETEER_DEBUG='*';

# 仅记录Page通道
window.__PUPPETEER_DEBUG='Page';

# 记录所有以Page开头的通道
window.__PUPPETEER_DEBUG='Page*';

调试输出示例:

const log = debug('Page');
log('new page created');
// 输出: "Page: new page created"

资料来源:packages/puppeteer-core/src/common/Debug.ts:1-30

9. 项目组织结构

puppeteer/
├── packages/
│   ├── puppeteer-core/     # 核心API包
│   │   └── src/
│   │       ├── api/        # Page、Browser等API
│   │       ├── cdp/        # Chrome DevTools Protocol通信
│   │       └── common/     # 公共组件
│   ├── browsers/           # 浏览器管理CLI
│   └── ng-schematics/      # Angular集成
├── examples/               # 示例代码
├── docker/                 # Docker配置
└── tools/                  # 开发工具(ESLint等)

10. 相关资源

资源链接
官方文档pptr.dev
示例集合pptr.dev/examples
选择器指南pptr.dev/guides/page-interactions#selectors
MCP支持chrome-devtools-mcp
WebMCPpptr.dev/guides/webmcp

资料来源:README.md:5-15, examples/README.md:1-20

资料来源:[README.md:1-15]()

安装与入门指南

Puppeteer 是一个流行的 Node.js 库,它提供了高级 API 来通过 DevTools 协议控制 Chromium、Chrome 或 Firefox 浏览器。Puppeteer 主要用于网页自动化、网页抓取、生成截图、生成 PDF、测试 Web 应用等场景。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 使用 npm 安装

继续阅读本节完整说明和来源证据。

章节 使用 puppeteer-core 的注意事项

继续阅读本节完整说明和来源证据。

章节 Node.js 版本要求

继续阅读本节完整说明和来源证据。

概述

Puppeteer 是一个流行的 Node.js 库,它提供了高级 API 来通过 DevTools 协议控制 Chromium、Chrome 或 Firefox 浏览器。Puppeteer 主要用于网页自动化、网页抓取、生成截图、生成 PDF、测试 Web 应用等场景。

本指南将详细介绍 Puppeteer 的安装方式、系统要求、浏览器配置以及快速入门方法,帮助开发者快速上手使用 Puppeteer。

安装方式

使用 npm 安装

Puppeteer 提供两个主要的 npm 包,开发者可以根据需求选择合适的版本:

包名说明适用场景
puppeteer完整版,包含浏览器下载功能标准使用,需要自动下载 Chrome
puppeteer-core精简版,不包含浏览器已在环境中安装浏览器,或使用自定义浏览器

标准安装命令如下:

npm i puppeteer

此命令会在安装过程中自动下载与 Puppeteer 版本兼容的 Chrome 浏览器。

如果只需要将 Puppeteer 作为库使用,而不包含浏览器:

npm i puppeteer-core

资料来源:README.md:Installation

使用 puppeteer-core 的注意事项

使用 puppeteer-core 时,需要在 puppeteer.launch() 方法中通过 executablePath 参数指定浏览器可执行文件路径:

import puppeteer from 'puppeteer-core';

const browser = await puppeteer.launch({
  executablePath: '/path/to/chromium',
  // 其他配置选项
});

系统要求

Node.js 版本要求

Puppeteer 对 Node.js 版本有特定要求,具体版本信息请参考 package.json 中的 engines 字段。建议使用 LTS(长期支持)版本的 Node.js 以确保稳定性。

资料来源:packages/browsers/README.md:1-10

浏览器下载的系统依赖

不同的浏览器下载需要不同的系统工具支持:

#### Firefox 下载要求

操作系统必需工具
Linuxxzbzip2 工具(用于解压 .tar.gz.tar.bz2 归档文件)
macOShdiutil(用于解压 .dmg 归档文件)

#### Chrome 下载要求

操作系统必需工具
Linux/macOSunzip
Windowstar.exe

资料来源:packages/browsers/README.md:System requirements

浏览器管理

@puppeteer/browsers 包

@puppeteer/browsers 是官方提供的浏览器管理工具,支持从命令行界面(CLI)或编程方式管理浏览器和驱动。

核心命令

#### 安装浏览器

# 下载最新的 Stable 频道 Chrome for Testing
npx @puppeteer/browsers install chrome@stable

# 下载指定版本的 Chrome for Testing
npx @puppeteer/browsers install [email protected]

# 下载指定里程碑的最新版本
npx @puppeteer/browsers install chrome@117

# 下载最新的 ChromeDriver(Canary 频道)
npx @puppeteer/browsers install chromedriver@canary

# 下载指定版本的 ChromeDriver
npx @puppeteer/browsers install chromedriver@116

#### 列出已安装的浏览器

npx @puppeteer/browsers list

#### 清除所有已安装的浏览器

npx @puppeteer/browsers clear

#### 获取帮助信息

# 获取所有命令的帮助
npx @puppeteer/browsers --help

# 获取特定命令的帮助
npx @puppeteer/browsers install --help
npx @puppeteer/browsers launch --help

版本指定方式

指定方式示例说明
latestchrome@latest下载最新稳定版
里程碑版本chrome@117下载该里程碑的最新版本
完整版本号[email protected]下载指定精确版本
频道chromedriver@canary下载指定频道的最新版本

资料来源:packages/browsers/README.md:CLI

浏览器管理 API

除了 CLI,还可以编程方式使用 @puppeteer/browsers

import {install, launch, clear, list} from '@puppeteer/browsers';

// 列出已安装的浏览器
const installed = await list({});

// 安装浏览器
await install({
  browser: 'chrome',
  channel: 'stable',
});

// 启动浏览器
const process = await launch({
  browser: 'chrome',
  channel: 'stable',
});

快速入门

基本示例

以下是一个完整的 Puppeteer 使用示例,展示了打开浏览器、导航到网页、模拟用户交互的基本流程:

import puppeteer from 'puppeteer';

async function main() {
  // 启动浏览器并打开新的空白页
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // 导航到目标 URL
  await page.goto('https://developer.chrome.com/');

  // 设置视口大小
  await page.setViewport({width: 1080, height: 1024});

  // 使用键盘按下搜索菜单快捷键
  await page.keyboard.press('/');

  // 使用可访问的输入框名称填写搜索内容
  await page.locator('::-p-aria(Search)').fill('automate beyond recorder');

  // 等待并点击第一个搜索结果
  await page.locator('.devsite-result-item-link').click();

  // 使用文本定位器获取元素句柄
  const textSelector = await page
    .locator('::-p-text(Customize and automate)')
    .waitHandle();

  // 获取元素的文本内容
  const fullTitle = await textSelector?.evaluate(el => el.textContent);

  // 打印结果
  console.log('The title of this blog post is "%s".', fullTitle);

  // 关闭浏览器
  await browser.close();
}

main();

资料来源:README.md:Example

核心概念说明

#### 浏览器实例(Browser)

通过 puppeteer.launch() 创建浏览器实例,这是所有浏览器操作的基础。

const browser = await puppeteer.launch({
  headless: true,      // 是否使用无头模式
  args: ['--no-sandbox'],  // 浏览器启动参数
  timeout: 30000,      // 启动超时时间(毫秒)
});

#### 页面(Page)

通过 browser.newPage() 创建新的页面实例,Page 类继承自 EventEmitter,支持丰富的事件机制:

page.on('console', msg => console.log('PAGE LOG:', msg.text()));
page.on('request', request => console.log('REQUEST:', request.url()));
page.on('load', () => console.log('Page loaded!'));

#### 定位器(Locator)

Puppeteer 推荐使用 Locator API 进行元素定位和交互,Locator 提供了更强大的等待和重试机制:

// 使用文本内容定位
await page.locator('::-p-text(Submit)').click();

// 使用 ARIA 属性定位
await page.locator('::-p-aria(Search)').fill('query');

// 使用 CSS 选择器定位
await page.locator('.button.primary').click();

#### 元素操作

操作方法说明
点击locator.click()单击元素
输入locator.fill()填充输入框
获取文本evaluate(el => el.textContent)获取元素文本
获取属性locator.getAttribute()获取元素属性值
截图page.screenshot()截取页面截图
生成 PDFpage.pdf()生成 PDF 文档

资料来源:packages/puppeteer-core/src/api/Page.ts:$$eval

运行示例项目

环境准备

  1. 克隆仓库并安装依赖
git clone https://github.com/puppeteer/puppeteer.git
cd puppeteer
npm install
  1. 构建 Puppeteer
npm run build

运行单个示例

构建完成后,使用以下命令运行单个示例脚本:

NODE_PATH=../ node examples/search.js

示例脚本位于 examples/ 目录下,提供了多种使用场景的参考实现,包括网页搜索、截图、PDF 生成等功能。

资料来源:examples/README.md:Run

选择器语法参考

Puppeteer 专用选择器

选择器类型语法格式示例
文本选择器::-p-text(<文本>)page.locator('::-p-text(Submit)')
ARIA 选择器::-p-aria(<角色>[name=<名称>])page.locator('::-p-aria(Button)')
XPath 选择器::-p-xpath(<xpath>)page.locator('::-p-xpath(//button)')
Shadow DOM>>> <选择器>page.locator('>>> .custom-element')

Angular Schematics 选择器对照

对于从 Angular/Protractor 迁移的用户,以下是选择器语法对照:

ProtractorPuppeteer
$(by.id('id'))page.$('#id')
$(by.cssContainingText('css', 'text'))page.$('css ::-p-text(text)')
$(by.deepCss('css'))page.$(':scope >>> css')
$(by.xpath('xpath'))page.$('::-p-xpath(xpath)')

资料来源:packages/ng-schematics/README.md:Selectors

MCP 集成

Puppeteer 支持 Model Context Protocol (MCP),可以用于 AI 驱动的浏览器自动化:

安装 chrome-devtools-mcp

npm install chrome-devtools-mcp

WebMCP 支持

Puppeteer 还支持实验性的 WebMCP API,为基于 Web 的 AI 代理提供浏览器自动化能力。

资料来源:README.md:MCP

故障排除

常见安装问题

#### 浏览器下载失败

如果浏览器下载失败,可以尝试:

  1. 手动下载浏览器并使用 executablePath 指定路径
  2. 使用已安装系统的浏览器
  3. 检查网络连接和代理设置

#### 权限错误

在 Linux 或容器环境中,可能需要添加额外参数:

const browser = await puppeteer.launch({
  args: ['--no-sandbox', '--disable-setuid-sandbox'],
});

调试模式

启用 Puppeteer 调试日志:

# 设置调试环境变量
window.__PUPPETEER_DEBUG='*';  // 记录所有日志
window.__PUPPETEER_DEBUG='Page';  // 只记录 Page 频道
window.__PUPPETEER_DEBUG='foo*';  // 记录所有以 foo 开头的频道

在代码中使用调试日志:

import {debug} from '@puppeteer/puppeteer-core';

const log = debug('Page');
log('new page created');

资料来源:packages/puppeteer-core/src/common/Debug.ts:Debug

下一步

完成安装和入门后,建议进一步了解以下内容:

  • 页面交互:深入学习页面点击、表单填写、键盘输入等交互操作
  • 网络请求拦截:掌握请求和响应的监控、修改和模拟
  • 性能分析:使用 Puppeteer 进行页面性能测试和优化
  • 无头模式与有头模式:了解不同模式下的使用场景和配置
  • 高级配置:学习浏览器启动参数、代理设置、用户数据目录等高级特性

如需更多示例和详细文档,请访问 pptr.dev/examples

资料来源:[README.md:Installation]()

Puppeteer系统架构

Puppeteer是一个由Google维护的Node.js库,它提供了高级API来通过DevTools协议控制Chrome或Firefox浏览器。该项目的核心设计围绕浏览器自动化、网页抓取和性能监控等场景展开,采用分层架构以实现良好的模块化和可扩展性。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 1. 包结构

继续阅读本节完整说明和来源证据。

章节 2. Page类架构

继续阅读本节完整说明和来源证据。

章节 3. 抽象设计与实现分离

继续阅读本节完整说明和来源证据。

概述

Puppeteer是一个由Google维护的Node.js库,它提供了高级API来通过DevTools协议控制Chrome或Firefox浏览器。该项目的核心设计围绕浏览器自动化、网页抓取和性能监控等场景展开,采用分层架构以实现良好的模块化和可扩展性。

Puppeteer的架构主要分为以下几个层次:

层次描述主要模块
用户API层面向开发者的TypeScript/JavaScript接口Page、Browser、Frame
协议抽象层封装浏览器通信协议CDP (Chrome DevTools Protocol)
核心引擎层实现核心自动化逻辑puppeteer-core
节点运行时层Node.js环境特定功能LaunchOptions、PuppeteerNode
工具层辅助功能设备模拟、调试、配置管理

资料来源:packages/puppeteer-core/src/api/Page.ts:310-320

核心模块架构

1. 包结构

Puppeteer项目采用monorepo结构,主要包含以下npm包:

包名用途
puppeteer完整的Puppeteer包,包含浏览器下载
puppeteer-core核心库,不包含浏览器二进制文件
@puppeteer/browsers浏览器管理和启动CLI工具
@puppeteer/ng-schematicsAngular schematics集成

资料来源:README.md:1-10

2. Page类架构

Page是Puppeteer中最核心的类之一,它继承自EventEmitter并提供了丰富的浏览器页面操作能力。

graph TD
    EventEmitter --> Page
    Page --> |extends| CDPPage
    Page --> |extends| WebDriverPage
    
    Page --> |使用| TimeoutSettings
    Page --> |管理| RequestHandlers
    Page --> |发出| PageEvents
    
    subgraph "Page核心功能"
        exposeFunction
        evaluate
        goto
        setContent
        locator
    end

Page类的关键内部状态

abstract class Page extends EventEmitter<PageEvents> {
  _isDragging = false;                    // 拖拽状态
  _timeoutSettings = new TimeoutSettings(); // 超时设置
  _tabId = '';                            // 标签页标识符
  #requestHandlers = new WeakMap<>();    // 请求处理器
  #inflight$ = new ReplaySubject<number>(1); // 进行中的请求
}

资料来源:packages/puppeteer-core/src/api/Page.ts:290-305

3. 抽象设计与实现分离

Puppeteer采用了抽象基类的设计模式,定义了清晰的接口契约。这种设计允许不同的协议实现共存:

graph LR
    subgraph "抽象层"
        Page
        Browser
        Frame
    end
    
    subgraph "CDP实现"
        CDPPage
        CDPBrowser
        CDPFrame
    end
    
    subgraph "WebDriver实现"
        WebDriverPage
        WebDriverBrowser
        WebDriverFrame
    end
    
    Page --> CDPPage
    Page --> WebDriverPage

配置系统

Configuration接口

Puppeteer提供了灵活的配置系统,支持多种自定义选项:

interface Configuration {
  defaultBrowser?: SupportedBrowser;     // 默认浏览器
  temporaryDirectory?: string;           // 临时目录
  skipDownload?: boolean;               // 跳过下载
  logLevel?: 'silent' | 'error' | 'warn'; // 日志级别
  experiments?: ExperimentsConfiguration; // 实验性选项
  chrome?: ChromeSettings;              // Chrome特定设置
  firefox?: FirefoxSettings;            // Firefox特定设置
}

资料来源:packages/puppeteer-core/src/common/Configuration.ts:30-60

环境变量覆盖

配置选项可以通过环境变量进行覆盖:

配置属性环境变量默认值
temporaryDirectoryPUPPETEER_TMP_DIRos.tmpdir()
skipDownloadPUPPETEER_SKIP_DOWNLOADfalse
Chrome skipDownloadPUPPETEER_CHROME_SKIP_DOWNLOADfalse
Chrome downloadBaseUrlPUPPETEER_CHROME_DOWNLOAD_BASE_URLstorage.googleapis.com

执行上下文与代码注入

ExecutionContext执行上下文

Puppeteer通过ExecutionContext类封装了CDP的Runtime.evaluateRuntime.callFunctionOn方法:

sequenceDiagram
    用户代码 ->> Page: evaluate(pageFunction)
    Page ->> ExecutionContext: evaluate(pageFunction)
    ExecutionContext ->> CDPClient: Runtime.evaluate
    CDPClient -->> ExecutionContext: remoteObject
    ExecutionContext ->> ExecutionContext: createCdpHandle
    ExecutionContext -->> 用户代码: JSHandle

核心评估逻辑

// 处理字符串表达式
if (isString(pageFunction)) {
  const expressionWithSourceUrl = `${expression}\n${sourceUrlComment}\n`;
  const {exceptionDetails, result: remoteObject} = await client.send(
    'Runtime.evaluate', {
      expression: expressionWithSourceUrl,
      contextId,
      returnByValue,
      awaitPromise: true,
      userGesture: true,
    }
  );
}

资料来源:packages/puppeteer-core/src/cdp/ExecutionContext.ts:45-75

LazyArg延迟参数机制

LazyArg是Puppeteer用于在页面上下文中延迟解析参数的机制:

class LazyArg<T, Context = PuppeteerUtilWrapper> {
  static create = <T>(
    get: (context: PuppeteerUtilWrapper) => Promise<T> | T
  ): T => {
    return new LazyArg(get) as unknown as T;
  };

  async get(context: Context): Promise<T> {
    return await this.#get(context);
  }
}

这个机制确保了传递给页面函数的参数在被实际使用时才进行求值,避免了闭包捕获问题。

资料来源:packages/puppeteer-core/src/common/LazyArg.ts:20-35

设备模拟系统

KnownDevices预定义设备

Puppeteer内置了丰富的设备模拟配置,通过KnownDevices对象提供:

export const KnownDevices = Object.freeze(knownDevicesByName);

支持的设备包括各种iPhone、Android设备和桌面浏览器的预设配置,涵盖视口尺寸、用户代理字符串和触摸能力等属性。

资料来源:packages/puppeteer-core/src/common/Device.ts:180-190

设备模拟使用流程

graph LR
    A[获取设备配置] --> B[创建Browser]
    B --> C[创建Page]
    C --> D[page.emulate]
    D --> E[导航到目标URL]

启动选项与浏览器管理

LaunchOptions启动配置

LaunchOptions接口定义了浏览器启动时的各项参数:

选项类型默认值描述
executablePathstring-使用指定的浏览器可执行文件
ignoreDefaultArgs`boolean \string[]`false忽略默认启动参数
enableExtensions`boolean \string[]`-启用浏览器扩展
handleSIGINTbooleantrueCtrl+C关闭浏览器
handleSIGTERMbooleantrueSIGTERM关闭浏览器
handleSIGHUPbooleantrueSIGHUP关闭浏览器
timeoutnumber30000启动超时(ms)

资料来源:packages/puppeteer-core/src/node/LaunchOptions.ts:25-60

信号处理机制

Puppeteer实现了健壮的进程信号处理:

graph TD
    SIGINT --> handleSIGINT --> browser.close
    SIGTERM --> handleSIGTERM --> browser.close
    SIGHUP --> handleSIGHUP --> browser.close

调试系统

Debug模块架构

Puppeteer提供了灵活的调试日志系统,支持Node.js和浏览器环境:

export const debug = (prefix: string): ((...args: unknown[]) => void) => {
  if (isNode) {
    return async (...logArgs: unknown[]) => {
      if (captureLogs) {
        capturedLogs.push(prefix + logArgs);
      }
      (await importDebug())(prefix)(logArgs);
    };
  }
  
  return (...logArgs: unknown[]): void => {
    // 浏览器环境使用console.log
    console.log(`${prefix}:`, ...logArgs);
  };
};

调试通道配置

通过window.__PUPPETEER_DEBUG环境变量控制调试输出:

行为
'*'记录所有通道
'Page'仅记录Page通道
'Page*'记录所有以Page开头的通道

资料来源:packages/puppeteer-core/src/common/Debug.ts:30-60

事件系统

PageEvent事件类型

Page类继承自EventEmitter,使用标准的事件发布-订阅模式:

// 订阅事件
page.on('request', logRequest);

// 取消订阅
page.off('request', logRequest);

// 单次事件监听
page.once('load', () => console.log('Page loaded!'));

常见的页面事件包括:loaddomcontentloadedrequestresponseconsole等。

资料来源:packages/puppeteer-core/src/api/Page.ts:1-50

查询选择器系统

Puppeteer支持多种选择器类型,实现灵活的元素定位:

选择器类型语法示例描述
CSS选择器page.$('div.class')标准CSS选择器
ARIA选择器::-p-aria(Search)无障碍角色和名称
文本选择器::-p-text(Submit)按文本内容匹配
XPath选择器::-p-xpath(//button)XPath表达式
Pierce选择器::p-deep(div)穿透Shadow DOM

资料来源:packages/ng-schematics/README.md:40-60

典型工作流程

graph TD
    A[启动浏览器] --> B[创建新页面]
    B --> C[设置视口和用户代理]
    C --> D[导航到URL]
    D --> E[执行自动化操作]
    E --> F{是否需要交互}
    F -->|是| G[执行交互操作]
    G --> H[等待条件满足]
    H --> E
    F -->|否| I[提取数据]
    I --> J[关闭浏览器]

安全考虑

沙箱模式

Docker运行Puppeteer时需要特殊权限:

docker run -i --init --rm --cap-add=SYS_ADMIN \
  --name puppeteer-chrome puppeteer-chrome-linux \
  node -e "..."

--cap-add=SYS_ADMIN用于启用Chrome沙箱安全机制,或使用--no-sandbox标志禁用沙箱。

资料来源:docker/README.md:15-25

总结

Puppeteer的系统架构体现了以下设计原则:

  1. 抽象与实现分离:通过抽象基类支持CDP和WebDriver等多种协议实现
  2. 模块化设计:核心功能与特定运行时环境解耦
  3. 灵活的配置系统:支持代码配置和环境变量覆盖
  4. 事件驱动架构:基于EventEmitter的统一事件系统
  5. 跨平台支持:同时支持Node.js和浏览器环境的调试能力

这种架构使得Puppeteer能够适应各种复杂的浏览器自动化场景,同时保持代码的可维护性和可扩展性。

资料来源:[packages/puppeteer-core/src/api/Page.ts:310-320]()

协议实现:CDP与WebDriver BiDi

Puppeteer 同时支持两种浏览器自动化协议:CDP(Chrome DevTools Protocol) 和 WebDriver BiDi(WebDriver Bi-Directional)。这种双协议支持使 Puppeteer 能够提供跨浏览器兼容性和向后兼容性。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 双协议架构

继续阅读本节完整说明和来源证据。

章节 CDP over BiDi 混合模式

继续阅读本节完整说明和来源证据。

章节 CDP Browser

继续阅读本节完整说明和来源证据。

概述

Puppeteer 同时支持两种浏览器自动化协议:CDP(Chrome DevTools Protocol)WebDriver BiDi(WebDriver Bi-Directional)。这种双协议支持使 Puppeteer 能够提供跨浏览器兼容性和向后兼容性。

协议类型支持浏览器用途
CDPChrome 专有Chrome、Chromium提供最完整的 Chrome 控制能力
WebDriver BiDiW3C 标准Chrome、Firefox、Edge跨浏览器兼容性

资料来源:packages/puppeteer-core/src/node/PuppeteerNode.ts

架构设计

双协议架构

Puppeteer 的协议实现采用分层架构,抽象层将底层协议细节与高级 API 解耦:

graph TB
    subgraph "高级API层"
        P[Page]
        B[Browser]
        T[Target]
    end
    
    subgraph "协议抽象层"
        CDPA[CDP Browser]
        BiDiA[BiDi Browser]
    end
    
    subgraph "连接层"
        CDPC[CDP Connection]
        BiDiC[BiDi Connection]
    end
    
    P --> CDPA
    P --> BiDiA
    B --> CDPA
    B --> BiDiA
    T --> CDPA
    T --> BiDiA
    
    CDPA --> CDPC
    BiDiA --> BiDiC

CDP over BiDi 混合模式

当使用 CDP 连接时,Puppeteer 可以选择性地将 BiDi 协议叠加在 CDP 连接之上:

const bidiOnly = process.env['PUPPETEER_WEBDRIVER_BIDI_ONLY'] === 'true';
const BiDi = await import('../bidi/bidi.js');
const bidiConnection = await BiDi.connectBidiOverCdp(cdpConnection);

资料来源:packages/puppeteer-core/src/node/BrowserLauncher.ts:45-48

CDP 实现

CDP Browser

CDP Browser 类负责管理基于 Chrome DevTools Protocol 的浏览器实例。CDP 协议提供对 Chrome 内部功能的深度控制,包括:

  • 完整的 JavaScript 执行环境
  • 网络请求拦截和修改
  • 性能分析
  • 页面截图和 PDF 生成
  • DOM 操作

CDP Connection

CDP Connection 实现了基于 WebSocket 的 CDP 通信机制:

组件职责
WebSocket 传输底层双向通信
命令分发将 API 调用转换为 CDP 命令
事件监听转发浏览器事件到上层
会话管理管理多个 CDP 会话

CDP 连接支持通过 puppeteer.connect() 方法进行远程连接,实现浏览器控制与浏览器进程的分离。

WebDriver BiDi 实现

BiDi 协议核心

WebDriver BiDi 是 W3C 标准化的一种双向协议,设计目标是提供跨浏览器统一的自动化接口。Puppeteer 的 BiDi 实现位于 packages/puppeteer-core/src/bidi/core/ 目录。

#### 设计原则

BiDi 核心实现遵循以下原则:

  1. 遵循规范bidi/core 严格遵循 WebDriver BiDi 规范,而非 Puppeteer 特定需求
  2. 全面性:按图结构实现所有节点和边,不跳过任何中间步骤
  3. 最小化:仅实现协议必需的功能,避免过度设计

资料来源:packages/puppeteer-core/src/bidi/core/README.md

BiDi Browser

BiDi Browser 类提供基于 WebDriver BiDi 协议的浏览器控制:

return await BiDi.BidiBrowser.create({
  connection: bidiConnection,
  // 当启用 BiDi-only 模式时不传递 CDP 连接
  cdpConnection: bidiOnly ? undefined : cdpConnection,
  closeCallback,
  process: browserProcess.nodeProcess,
  defaultViewport: opts.defaultViewport,
  acceptInsecureCerts: opts.acceptInsecureCerts,
  networkEnabled: opts.networkEnabled,
  issuesEnabled: opts.issuesEnabled,
});

资料来源:packages/puppeteer-core/src/node/BrowserLauncher.ts:50-60

BiDi Connection

BiDi Connection 负责 WebSocket 双向通信,处理 BiDi 协议的握手和消息传递。

BiDi Core 模块

bidi/core 模块是 WebDriver BiDi 协议的纯规范实现:

模块功能
core.ts协议核心逻辑、命令处理、事件分发
EventEmitter双向事件传输
Browsing Context浏览器上下文管理
ScriptJavaScript 执行域

#### 事件图结构

BiDi 协议中的事件遵循严格的图结构。例如,导航事件必须按以下顺序触发:

fragment navigation → navigation → browsing context

不允许跳过中间节点,也不允许存在组合边(如同时存在上述路径和 fragment navigation → browsing context)。

资料来源:packages/puppeteer-core/src/bidi/core/README.md

协议选择与配置

环境变量控制

环境变量作用
PUPPETEER_WEBDRIVER_BIDI_ONLY启用纯 BiDi 模式truefalse

PUPPETEER_WEBDRIVER_BIDI_ONLY=true 时,Browser 对象不会持有 CDP 连接引用,强制使用 BiDi 端点:

cdpConnection: bidiOnly ? undefined : cdpConnection,

资料来源:packages/puppeteer-core/src/node/BrowserLauncher.ts:55

启动配置

通过 LaunchOptions 可自定义浏览器启动行为:

选项说明默认值
executablePath浏览器可执行文件路径自动检测
ignoreDefaultArgs跳过默认参数false
enableExtensions启用扩展支持false
timeout启动超时(ms)30000
protocolTimeout协议超时(ms)undefined

资料来源:packages/puppeteer-core/src/node/LaunchOptions.ts

Target 抽象

Puppeteer 通过 Target 抽象统一管理不同类型的浏览器目标:

graph TD
    T[Target 抽象]
    CDPT[CDP Target]
    BiDiT[BiDi Target]
    
    CDPT --> CDPT_Browser[CDP Browser Target]
    CDPT --> CDPT_Page[CDP Page Target]
    
    BiDiT --> BiDiT_Browser[BiDi Browser Target]
    BiDiT --> BiDiT_Page[BiDi Page Target]
    
    T --> CDPT
    T --> BiDiT

BiDi Target 实现

BiDi Target 类体系包括:

类型说明
BidiBrowserTargetTargetType.BROWSER浏览器级别目标
BidiPageTargetTargetType.PAGE页面级别目标
BidiFrameTargetTargetType.FRAME帧级别目标
BidiWorkerTargetTargetType.WORKERWeb Worker 目标
export class BidiBrowserTarget extends Target {
  override type(): TargetType {
    return TargetType.BROWSER;
  }
  override browser(): BidiBrowser {
    return this.#browser;
  }
}

资料来源:packages/puppeteer-core/src/bidi/Target.ts

协议特性对比

特性CDPWebDriver BiDi
标准化程度Chrome 专有W3C 标准
浏览器支持仅 ChromeChrome、Firefox、Edge
API 完整性完整部分功能
跨浏览器兼容
网络拦截完整支持基础支持
性能分析深度支持有限支持
JavaScript 执行完整上下文受限沙箱

使用场景建议

选择 CDP 的场景

  • 需要完整的 Chrome 特性支持
  • 进行性能分析和调试
  • 需要精细的网络请求控制
  • 仅针对 Chrome/Chromium 环境

选择 WebDriver BiDi 的场景

  • 需要跨浏览器兼容性
  • 遵循标准化协议要求
  • 与 Selenium 等工具集成
  • 测试环境包含多种浏览器

扩展机制

协议扩展

Puppeteer 支持通过自定义 Provider 扩展浏览器下载和安装机制:

import {install} from '@puppeteer/browsers';

await install({
  browser: Browser.CHROMEDRIVER,
  cacheDir: './cache',
  providers: [new CustomProvider()],
});

资料来源:packages/browsers/src/install.ts

总结

Puppeteer 的双协议架构提供了灵活性和兼容性的平衡:

  1. CDP 协议 提供最深度的 Chrome 控制能力,适合需要高级功能的项目
  2. WebDriver BiDi 提供跨浏览器标准化接口,适合需要多浏览器支持的项目
  3. 混合模式 允许在 CDP 连接上叠加 BiDi 协议,兼顾功能完整性和标准化
  4. 严格规范遵循 确保 BiDi 实现的可移植性和正确性

资料来源:[packages/puppeteer-core/src/node/PuppeteerNode.ts](packages/puppeteer-core/src/node/PuppeteerNode.ts)

浏览器启动与管理

Puppeteer 的浏览器启动与管理模块是整个项目的核心组件之一,负责协调浏览器的生命周期、进程管理和资源分配。该模块通过抽象统一的 API,支持 Chrome、Firefox 等多种浏览器的启动、配置和销毁操作,同时提供细粒度的信号控制、超时管理和多上下文隔离机制。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 核心组件关系

继续阅读本节完整说明和来源证据。

章节 启动流程时序

继续阅读本节完整说明和来源证据。

章节 浏览器枚举

继续阅读本节完整说明和来源证据。

概述

Puppeteer 的浏览器启动与管理模块是整个项目的核心组件之一,负责协调浏览器的生命周期、进程管理和资源分配。该模块通过抽象统一的 API,支持 Chrome、Firefox 等多种浏览器的启动、配置和销毁操作,同时提供细粒度的信号控制、超时管理和多上下文隔离机制。

浏览器启动系统的设计遵循以下核心原则:

  • 跨平台兼容性:统一处理不同操作系统(Linux、macOS、Windows)上的浏览器启动差异
  • 进程生命周期管理:通过信号处理机制确保浏览器进程能够被正确终止
  • 可扩展性:支持自定义可执行路径、浏览器参数和实验性功能配置
  • 资源隔离:通过 BrowserContext 实现多浏览器上下文隔离

资料来源:packages/puppeteer-core/src/node/BrowserLauncher.ts:1-50

架构设计

核心组件关系

Puppeteer 的浏览器启动架构采用分层设计,各层职责分明:

graph TD
    A[用户调用 puppeteer.launch] --> B[BrowserLauncher 抽象基类]
    B --> C[ChromeLauncher]
    B --> D[FirefoxLauncher]
    C --> E[Chrome/Chromium 进程]
    D --> F[Firefox 进程]
    G[Configuration 配置] --> B
    H[LaunchOptions 启动选项] --> B
层级组件职责
接口层BrowserLauncher定义浏览器启动的统一接口和流程
实现层ChromeLauncher处理 Chrome/Chromium 特定启动逻辑
实现层FirefoxLauncher处理 Firefox 特定启动逻辑
配置层Configuration全局默认配置和浏览器特定设置
选项层LaunchOptions用户指定的运行时启动参数

资料来源:packages/puppeteer-core/src/node/BrowserLauncher.ts

启动流程时序

浏览器启动涉及多个阶段的协调操作:

sequenceDiagram
    participant U as 用户代码
    participant P as Puppeteer
    participant L as BrowserLauncher
    participant B as 浏览器进程
    participant C as CDP/WebDriver
    
    U->>P: puppeteer.launch(options)
    P->>L: 创建 Launcher 实例
    L->>L: 解析配置和选项
    L->>B: 启动浏览器进程
    B-->>L: 进程已启动
    L->>C: 建立连接
    C-->>L: 连接就绪
    L-->>P: 返回 Browser 实例
    P-->>U: 返回 Browser 实例

资料来源:packages/browsers/src/launch.ts:1-100

支持的浏览器类型

浏览器枚举

Puppeteer 通过 SupportedBrowser 枚举定义支持的浏览器类型:

枚举值浏览器说明
chromeChrome for Testing默认浏览器,Puppeteer 主要支持的浏览器
chrome-headless-shellChrome Headless Shell无头 Chrome 精简版,体积更小
firefoxFirefoxMozilla Firefox 浏览器

配置接口中指定默认浏览器为 chrome

Defines the default browser to use.
@defaultValue chrome

资料来源:packages/puppeteer-core/src/common/Configuration.ts:1-50

浏览器特定配置

每种浏览器都有独立的配置命名空间:

interface Configuration {
  chrome?: ChromeSettings;
  ['chrome-headless-shell']?: ChromeHeadlessShellSettings;
  firefox?: FirefoxSettings;
}

Chrome 设置参数:

参数类型默认值说明
skipDownloadbooleanfalse跳过浏览器下载
downloadBaseUrlstringhttps://storage.googleapis.com/chrome-for-testing-public下载基础 URL
executablePathstring自动推断自定义可执行文件路径

Firefox 设置参数:

参数类型默认值说明
skipDownloadbooleantrue跳过浏览器下载
downloadBaseUrlstringhttps://archive.mozilla.org/pub/firefox/releases下载基础 URL
versionstringPuppeteer 固定的版本指定 Firefox 版本

资料来源:packages/puppeteer-core/src/common/Configuration.ts:50-150

启动选项详解

LaunchOptions 接口定义了启动浏览器时可配置的所有参数:

基础配置参数

参数类型默认值说明
executablePathstring捆绑浏览器指定自定义浏览器可执行文件路径
ignoreDefaultArgs`boolean \string[]`false是否忽略默认参数或排除指定参数
enableExtensions`boolean \string[]`false启用扩展支持
If true, avoids passing default arguments to the browser that would prevent extensions from being enabled. Passing a list of strings will load the provided paths as unpacked extensions.

资料来源:packages/puppeteer-core/src/node/LaunchOptions.ts:1-60

进程信号控制

Puppeteer 提供了完善的进程信号处理机制,确保在不同终止场景下浏览器进程能被正确关闭:

参数类型默认值说明
handleSIGINTbooleantrue接收到 Ctrl+C 时关闭浏览器
handleSIGTERMbooleantrue接收到 SIGTERM 信号时关闭浏览器
handleSIGHUPbooleantrue接收到 SIGHUP 信号时关闭浏览器

超时配置

参数类型默认值说明
timeoutnumber30_000 (30秒)浏览器启动超时时间(毫秒),设为 0 禁用超时
Maximum time in milliseconds to wait for the browser to start. Pass 0 to disable the timeout.

资料来源:packages/puppeteer-core/src/node/LaunchOptions.ts:60-100

其他启动参数

参数类型说明
pipeboolean使用管道而非 WebSocket 连接
dumpioboolean将浏览器 stdout/stderr 导出到进程
userDataDirstring用户数据目录(-profile 路径)
envRecord<string, string>浏览器进程环境变量

Browser 类 API

Browser 类是浏览器实例的抽象表示,封装了所有浏览器操作:

核心方法

方法返回值说明
newPage()Promise<Page>创建新页面
pages()Promise<Page[]>获取所有打开的页面
createIncognitoBrowserContext()Promise<BrowserContext>创建私有浏览器上下文
browserContexts()BrowserContext[]获取所有浏览器上下文
version()Promise<string>获取浏览器版本
process()`ChildProcess \null`获取浏览器进程对象
close()Promise<void>关闭浏览器

资料来源:packages/puppeteer-core/src/api/Browser.ts:1-100

浏览器进程管理

通过 process() 方法可以访问底层的 Node.js 子进程:

const browser = await puppeteer.launch();
const proc = browser.process();

if (proc) {
  console.log(`Browser PID: ${proc.pid}`);
  proc.kill(); // 强制终止
}

版本检测

const browser = await puppeteer.launch();
const version = await browser.version();
console.log(`Browser version: ${version}`);

BrowserContext 浏览器上下文

BrowserContext 提供了浏览器实例的隔离机制,类似于浏览器中的"无痕模式":

特性说明

  • 每个 BrowserContext 拥有独立的 cookie 存储
  • 每个 BrowserContext 拥有独立的会话存储
  • 不同 BrowserContext 之间的页面完全隔离
  • 共享进程但通过不同 CDP 会话隔离
graph LR
    A[Browser] --> B[BrowserContext A]
    A --> C[BrowserContext B]
    A --> D[BrowserContext C]
    B --> E[Page 1]
    B --> F[Page 2]
    C --> G[Page 3]
    D --> H[Page 4]
    
    style B fill:#e1f5fe
    style C fill:#e1f5fe
    style D fill:#e1f5fe

上下文 API

方法说明
createPage()在当前上下文中创建新页面
pages()获取当前上下文中的所有页面
close()关闭浏览器上下文
overridePermissions()覆盖指定源的权限
clearPermissionOverrides()清除所有权限覆盖

资料来源:packages/puppeteer-core/src/api/BrowserContext.ts:1-80

使用示例

// 创建两个隔离的浏览器上下文
const context1 = await browser.createIncognitoBrowserContext();
const context2 = await browser.createIncognitoBrowserContext();

const page1 = await context1.newPage();
const page2 = await context2.newPage();

// 两个页面的 cookie 完全隔离
await page1.goto('https://example.com');
await page2.goto('https://example.com');

// 关闭上下文时释放资源
await context1.close();

生命周期管理

启动阶段

flowchart TD
    A[调用 launch] --> B{是否指定 executablePath}
    B -->|是| C[验证可执行文件存在]
    B -->|否| D[从缓存目录查找]
    C --> E{文件存在?}
    D --> E
    E -->|否| F[抛出错误]
    E -->|是| G[应用默认参数]
    G --> H[启动子进程]
    H --> I[建立 CDP 连接]
    I --> J[等待浏览器就绪]
    J --> K[返回 Browser 实例]

关闭阶段

关闭方式触发条件行为
正常关闭调用 browser.close()优雅关闭所有页面和上下文
SIGINTCtrl+C触发正常关闭流程
SIGTERM系统终止信号触发正常关闭流程
SIGHUP终端挂起触发正常关闭流程
强制终止process.exit()浏览器进程可能残留

错误处理

浏览器启动失败时,Puppeteer 会根据失败原因抛出详细的错误信息:

Could not find Firefox (rev. ${browserVersion}). This can occur if either
1. you did not perform an installation for Firefox before running the script (e.g. npx puppeteer browsers install firefox) or
2. your cache path is incorrectly configured

资料来源:packages/puppeteer-core/src/node/BrowserLauncher.ts:80-100

配置管理

环境变量覆盖

Puppeteer 支持通过环境变量覆盖配置:

环境变量配置属性说明
PUPPETEER_SKIP_DOWNLOADskipDownload跳过浏览器下载
PUPPETEER_TMP_DIRtemporaryDirectory临时文件目录
PUPPETEER_CACHE_DIRcacheDirectory浏览器缓存目录
PUPPETEER_CHROME_SKIP_DOWNLOADchrome.skipDownload跳过 Chrome 下载
PUPPETEER_FIREFOX_SKIP_DOWNLOADfirefox.skipDownload跳过 Firefox 下载

配置文件方式

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({
  // 启动选项
  timeout: 60000,
  headless: true,
  
  // 浏览器特定配置
  chrome: {
    executablePath: '/custom/chrome/path',
    args: ['--disable-dev-shm-usage']
  }
});

实际使用示例

基础启动

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const page = await browser.newPage();

await page.goto('https://example.com');

await browser.close();

自定义配置启动

const browser = await puppeteer.launch({
  headless: false,
  executablePath: '/path/to/chrome',
  args: [
    '--disable-gpu',
    '--no-sandbox',
    '--disable-setuid-sandbox',
    '--disable-dev-shm-usage'
  ],
  timeout: 60000,
  handleSIGINT: true,
  handleSIGTERM: true
});

多上下文隔离

const browser = await puppeteer.launch();

// 用户 A 的上下文
const contextA = await browser.createIncognitoBrowserContext();
const pageA = await contextA.newPage();
await pageA.goto('https://login.example.com');
await pageA.type('#username', 'user_a');

// 用户 B 的上下文
const contextB = await browser.createIncognitoBrowserContext();
const pageB = await contextB.newPage();
await pageB.goto('https://login.example.com');
await pageB.type('#username', 'user_b');

// 独立验证,不会互相干扰
await Promise.all([
  pageA.click('#submit'),
  pageB.click('#submit')
]);

await contextA.close();
await contextB.close();
await browser.close();

最佳实践

资源管理

  1. 始终关闭浏览器:使用 try...finallyawait browser.close() 确保资源释放
  2. 限制页面数量:避免创建过多页面导致资源耗尽
  3. 使用上下文隔离:需要隔离操作时使用 BrowserContext 而非启动多个浏览器实例

稳定性建议

场景推荐配置
Docker/容器环境添加 --no-sandbox--disable-dev-shm-usage 参数
CI/CD 环境使用 headless: true 并设置合理的 timeout
资源受限环境使用 chrome-headless-shell 减少内存占用
需要扩展支持设置 enableExtensionstrue

调试技巧

  1. 查看浏览器日志dumpio: true 可捕获浏览器输出
  2. 使用自定义用户数据目录:便于检查浏览器状态
  3. 禁用默认参数调试ignoreDefaultArgs: true 后手动添加所需参数

相关命令

浏览器管理 CLI

通过 @puppeteer/browsers 包管理已安装的浏览器:

# 列出已安装的浏览器
npx @puppeteer/browsers list

# 安装 Chrome Stable
npx @puppeteer/browsers install chrome@stable

# 安装指定版本 Chrome
npx @puppeteer/browsers install [email protected]

# 安装最新 ChromeDriver
npx @puppeteer/browsers install chromedriver@canary

# 清理所有已安装浏览器
npx @puppeteer/browsers clear

资料来源:packages/browsers/README.md:1-80

总结

Puppeteer 的浏览器启动与管理模块通过统一的抽象层,优雅地解决了跨浏览器、跨平台的启动管理问题。其核心设计包括:

  • 统一接口BrowserLauncher 抽象基类为不同浏览器提供一致的操作体验
  • 灵活配置:通过 LaunchOptionsConfiguration 支持细粒度的参数控制
  • 进程安全:完善的信号处理机制确保浏览器进程在各种场景下都能正确关闭
  • 上下文隔离BrowserContext 提供会话级隔离,适合多用户模拟场景
  • 错误友好:详细的错误信息帮助开发者快速定位问题

掌握这些机制,能够帮助开发者构建更加稳定、可靠的浏览器自动化应用。

资料来源:[packages/puppeteer-core/src/node/BrowserLauncher.ts:1-50]()

Page页面操作API

Page页面操作API是Puppeteer的核心模块之一,提供了与浏览器页面进行交互的完整能力。该API封装了浏览器自动化所需的各种操作,包括页面导航、内容查询、元素交互、JavaScript执行、截图和PDF生成等功能。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 实现层次结构

继续阅读本节完整说明和来源证据。

章节 核心组件关系

继续阅读本节完整说明和来源证据。

章节 页面状态管理

继续阅读本节完整说明和来源证据。

概述

Page页面操作API是Puppeteer的核心模块之一,提供了与浏览器页面进行交互的完整能力。该API封装了浏览器自动化所需的各种操作,包括页面导航、内容查询、元素交互、JavaScript执行、截图和PDF生成等功能。

Page类继承自Puppeteer的EventEmitter类,会发出各种在PageEvent枚举中定义的事件。Puppeteer支持两种底层协议实现:Chrome DevTools Protocol (CDP) 和 WebDriver BiDi (BiDi),它们都实现了统一的Page抽象接口。

资料来源:packages/puppeteer-core/src/api/Page.ts:100

架构设计

实现层次结构

graph TD
    A[Page 抽象基类] --> B[CDPPage CDP协议实现]
    A --> C[BiDiPage BiDi协议实现]
    D[Frame 抽象基类] --> E[CDPFrame]
    D --> F[BiDiFrame]
    G[EventEmitter] --> A
    H[JSHandle] --> I[ElementHandle]

核心组件关系

组件类型职责
Page抽象类定义页面操作的统一接口
CDPPage实现类通过CDP协议与Chrome通信
BiDiPage实现类通过BiDi协议与浏览器通信
Frame抽象类管理页面帧结构
JSHandle抽象类JavaScript对象句柄
ElementHandle抽象类DOM元素句柄

资料来源:packages/puppeteer-core/src/api/Page.ts:97-120

页面生命周期

页面状态管理

stateDiagram-v2
    [*] --> 创建中: browser.newPage()
    创建中 --> 已加载: 页面初始化完成
    已加载 --> 导航中: goto() / setContent()
    导航中 --> 已加载: 导航完成
    已加载 --> 关闭中: close()
    关闭中 --> [*]: 资源清理完成
    已加载 --> 已加载: 页面刷新/前进后退

内部状态变量

Page类维护以下内部状态:

_isDragging = false;           // 拖拽状态
_timeoutSettings = new TimeoutSettings();  // 超时配置
_tabId = '';                   // 浏览器标签页ID
#requestHandlers = WeakMap;    // 请求处理器映射
#inflight$ = ReplaySubject;    // 进行中的请求流

资料来源:packages/puppeteer-core/src/api/Page.ts:105-115

页面导航操作

goto - 页面跳转

导航到指定URL并等待页面加载完成。

await page.goto('https://developer.chrome.com/');

参数说明:

参数类型必填说明
urlstring目标页面URL
optionsNavigationOptions导航选项配置

导航选项:

选项类型默认值说明
timeoutnumber30s导航超时时间(毫秒)
waitUntilWaitUntilOptionsload等待条件
refererstring-引荐来源URL

waitUntil 支持的值:

说明
load等待 load 事件触发
domcontentloaded等待 DOMContentLoaded 事件
networkidle0等待无网络连接(500ms内)
networkidle2等待最多2个网络连接

setContent - 设置页面内容

直接设置页面的HTML内容。

await page.setContent('<html><body><h1>Hello</h1></body></html>');

reload - 刷新页面

await page.reload();
await page.reload({ timeout: 60000 });

goBack / goForward - 历史导航

await page.goBack();      // 返回上一页
await page.goForward();   // 前进到下一页

元素查询与选择器

选择器类型

Puppeteer支持多种选择器类型,可以满足不同的查询需求:

graph LR
    A[选择器查询] --> B[CSS选择器]
    A --> C[ARIA选择器]
    A --> D[文本选择器]
    A --> E[XPath选择器]
    A --> F[Pierce选择器]

选择器类型对照表

类型语法示例
CSS标准CSS选择器page.$('div.container')
ARIA::-p-aria(...)page.locator('::-p-aria(Search)')
文本::-p-text(...)page.locator('::-p-text(Click me)')
XPath::-p-xpath(...)page.locator('::-p-xpath(//button)')
Pierce::-p-shadow(...)穿透Shadow DOM查询

资料来源:packages/ng-schematics/README.md

查询方法

#### 单元素查询

// CSS选择器
const button = await page.$('button.submit');

// ARIA选择器
const searchInput = await page.$('::-p-aria(Search field)');

// 文本选择器
const heading = await page.locator('::-p-text(Welcome)');

#### 多元素查询

const inputs = await page.$$('input[type="text"]');
const items = await page.locator('li.item');

#### 高级查询

// 跨Shadow DOM查询
const shadowElement = await page.locator('::-p-shadow(div.inner)');

// 组合选择器
const complex = await page.locator('div.container >> text=Submit');

$$eval - 批量元素操作

在所有匹配元素上执行JavaScript函数:

const allInputValues = await page.$$eval('input', elements =>
  elements.map(e => e.textContent)
);

参数说明:

参数类型说明
selectorstringCSS或其他类型选择器
pageFunctionFunction在页面上下文执行的函数
argsany[]额外参数

资料来源:packages/puppeteer-core/src/api/Page.ts:220-240

JavaScript执行与函数注入

evaluate - 页面内执行JavaScript

const title = await page.evaluate(() => document.title);

const result = await page.evaluate(async () => {
  const response = await fetch('/api/data');
  return await response.json();
});

exposeFunction - 注入全局函数

将Node.js函数暴露到页面window对象,页面JavaScript可以直接调用:

import crypto from 'crypto';

await page.exposeFunction('md5', text =>
  crypto.createHash('md5').update(text).digest('hex')
);

await page.evaluate(async () => {
  const hash = await window.md5('PUPPETEER');
  console.log(`md5: ${hash}`);
});

使用场景:

场景说明
文件读取在页面中读取服务器文件系统
数据库访问从页面查询数据库
API调用使用Node.js HTTP客户端
加密操作复杂加密在Node端执行

特性:

  • 通过exposeFunction注入的函数在页面导航后仍然有效
  • 如果注入的函数返回Promise,会自动await
  • 支持Function{default: Function}类型

资料来源:packages/puppeteer-core/src/api/Page.ts:155-185

ExecutionContext - 执行上下文

CDP实现的执行上下文提供了更底层的控制:

sequenceDiagram
    participant P as Puppeteer
    participant EC as ExecutionContext
    participant B as Browser
    
    P->>EC: evaluate(pageFunction)
    EC->>B: Runtime.evaluate
    B-->>EC: result/exceptionDetails
    EC-->>P: HandleFor<T> 或值

页面截图

基本截图

await page.screenshot({ path: 'screenshot.png' });

截图选项

选项类型说明
type'png' \'jpeg' \'webp'图片格式
qualitynumber图片质量(0-100)
fullPageboolean是否截取完整页面
clipClip截图区域
omitBackgroundboolean隐藏默认背景
encoding'binary' \'base64'返回格式

完整页面截图

await page.screenshot({
  path: 'fullpage.png',
  fullPage: true
});

区域截图

await page.screenshot({
  path: 'header.png',
  clip: {
    x: 0,
    y: 0,
    width: 800,
    height: 100
  }
});

Buffer返回

const buffer = await page.screenshot({
  type: 'png',
  encoding: 'binary'
});

资料来源:docs/guides/screenshots.md

PDF生成

基本PDF生成

await page.pdf({ path: 'page.pdf' });

PDF选项

选项类型默认值说明
printBackgroundbooleanfalse打印背景色和图片
landscapebooleanfalse横向打印
formatPaperFormat'Letter'纸张格式
widthstring-自定义宽度
heightstring-自定义高度
marginMargin-页边距
scalenumber1缩放比例
displayHeaderFooterbooleanfalse显示页眉页脚
headerTemplatestring-页眉HTML模板
footerTemplatestring-页脚HTML模板

常用纸张格式

格式尺寸
Letter8.5in x 11in
Legal8.5in x 14in
Tabloid11in x 17in
A4210mm x 297mm
A3297mm x 420mm
A5148mm x 210mm

自定义尺寸示例

await page.pdf({
  path: 'custom.pdf',
  width: '210mm',
  height: '297mm',
  printBackground: true,
  margin: {
    top: '20mm',
    bottom: '20mm',
    left: '20mm',
    right: '20mm'
  }
});

资料来源:docs/guides/pdf-generation.md

页面事件系统

事件类型

Page类继承自EventEmitter,支持以下核心事件:

graph LR
    A[Page Events] --> B[导航事件]
    A --> C[请求事件]
    A --> D[响应事件]
    A --> E[对话框事件]
    A --> F[帧事件]
    
    B --> B1[load]
    B --> B2[domcontentloaded]
    B --> B3[navigation]
    
    C --> C1[request]
    C --> C2[requestfailed]
    C --> C3[requestfinished]
    
    D --> D1[response]
    
    E --> E1[dialog]
    
    F --> F1[frameattached]
    F --> F2[framedetached]
    F --> F3[framenavigated]

常用事件监听

// 页面加载完成
page.once('load', () => console.log('Page loaded!'));

// 监听所有请求
page.on('request', request => {
  console.log('Request:', request.url());
});

// 监听响应
page.on('response', response => {
  console.log('Response:', response.url(), response.status());
});

// 处理对话框
page.on('dialog', async dialog => {
  console.log('Dialog:', dialog.message());
  await dialog.accept();
});

// 订阅与取消订阅
const handler = request => console.log(request.url());
page.on('request', handler);
page.off('request', handler);

导航相关事件

事件说明回调参数
load页面完全加载-
domcontentloadedDOM解析完成-
navigation导航开始-
framenavigated帧导航完成Frame

请求相关事件

事件说明回调参数
request发起请求HTTPRequest
requestfailed请求失败HTTPRequest
requestfinished请求完成HTTPRequest
response收到响应HTTPResponse

帧(Frame)处理

Frame类结构

Frame类提供了页面帧管理的能力,包括主框架和iframe。

graph TD
    Page --> Frame
    Frame --> IFrame1[iframe]
    Frame --> IFrame2[iframe]
    IFrame1 --> NestedFrame[嵌套帧]

帧查询方法

// 获取主框架
const mainFrame = page.mainFrame();

// 获取所有框架
const frames = page.frames();

// 根据name属性查找iframe
const iframe = page.frame('my-iframe');

// 通过URL查找框架
const authFrame = page.frame({ url: /\/auth/ });

Frame中的操作

Frame类实现了与Page类似的API,可以在帧上下文中执行操作:

// 在特定帧中执行JavaScript
const result = await frame.evaluate(() => document.title);

// 在特定帧中查找元素
const button = await frame.$('button.submit');

// 等待帧加载
await frame.waitForSelector('.content-loaded');

Frame与Page的关系

// Frame的parentFrame
const parent = frame.parentFrame();  // 返回父帧或null

// 帧的name属性
console.log(frame.name());  // iframe的name属性值

// 帧的URL
console.log(frame.url());   // 帧的当前URL

资料来源:packages/puppeteer-core/src/api/Frame.ts

Viewport与设备模拟

setViewport - 设置视口

await page.setViewport({ width: 1080, height: 1024 });

设备模拟

Puppeteer内置了常用设备的配置:

import { KnownDevices } from 'puppeteer';

const iPhone = KnownDevices['iPhone 15 Pro'];

await page.emulate(iPhone);

自定义设备配置

await page.emulate({
  name: 'Custom Device',
  userAgent: 'Mozilla/5.0...',
  viewport: {
    width: 375,
    height: 812,
    deviceScaleFactor: 3,
    isMobile: true,
    hasTouch: true,
    isLandscape: false
  }
});

资料来源:packages/puppeteer-core/src/common/Device.ts

超时配置

TimeoutSettings

Puppeteer使用TimeoutSettings类统一管理各种超时配置。

常用超时配置

// 设置默认导航超时
page.setDefaultNavigationTimeout(60000);

// 设置默认操作超时
page.setDefaultTimeout(30000);

// 设置单次操作超时
await page.waitForSelector('.element', { timeout: 5000 });

超时选项说明

选项默认值说明
navigationTimeout30000ms页面导航超时
defaultTimeout30000ms默认操作超时
waitForTimeout30000ms等待元素超时

CDP与BiDi实现差异

架构对比

特性CDPPageBiDiPage
底层协议Chrome DevTools ProtocolWebDriver BiDi
浏览器支持Chrome/Edge所有主流浏览器
功能完整性完整部分特性
性能较高相对较低
调试能力一般

实现文件

两种实现都遵循packages/puppeteer-core/src/api/Page.ts中定义的抽象接口,确保API行为的一致性。

最佳实践

页面操作流程

graph TD
    A[启动浏览器] --> B[创建页面]
    B --> C[设置Viewport]
    C --> D[导航到URL]
    D --> E{等待条件}
    E -->|元素存在| F[执行操作]
    E -->|等待超时| G[处理错误]
    F --> H[截图/PDF]
    H --> I[关闭页面]
    G --> I

错误处理

try {
  await page.goto('https://example.com', {
    timeout: 30000,
    waitUntil: 'networkidle0'
  });
} catch (error) {
  if (error.message.includes('net::ERR_')) {
    console.error('Network error occurred');
  } else if (error.message.includes('timeout')) {
    console.error('Navigation timeout');
  }
}

资源清理

// 使用完记得关闭页面
const page = await browser.newPage();
try {
  // 操作...
} finally {
  await page.close();
}

// 等待特定元素时使用waitForSelector的cleanup
const handle = await page.waitForSelector('.modal', {
  timeout: 5000
}).catch(() => null);

if (handle) {
  // 使用handle
  await handle.dispose();
}

性能优化建议

  1. 避免频繁截图 - 截图操作较耗时,按需使用
  2. 合理设置超时 - 过长超时会增加等待时间
  3. 使用waitForSelector - 比固定延迟更高效
  4. 批量操作 - 减少页面交互次数
  5. 复用Page实例 - 避免频繁创建销毁页面

相关链接

资料来源:[packages/puppeteer-core/src/api/Page.ts:100]()

元素定位器与操作

元素定位器与操作是 Puppeteer 自动化框架中用于在网页中查找和交互 DOM 元素的核心模块。该系统提供了多种定位策略,包括 CSS 选择器、ARIA 角色定位、文本匹配、XPath 表达式以及穿透 Shadow DOM 的选择器,同时支持通过定位器 API 实现稳定的元素等待和交互操作。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 核心组件关系

继续阅读本节完整说明和来源证据。

章节 定位器与元素句柄的职责划分

继续阅读本节完整说明和来源证据。

章节 支持的选择器类型

继续阅读本节完整说明和来源证据。

概述

元素定位器与操作是 Puppeteer 自动化框架中用于在网页中查找和交互 DOM 元素的核心模块。该系统提供了多种定位策略,包括 CSS 选择器、ARIA 角色定位、文本匹配、XPath 表达式以及穿透 Shadow DOM 的选择器,同时支持通过定位器 API 实现稳定的元素等待和交互操作。

定位器(Locator)是对传统 page.$()page.$$() 查询方式的现代化封装,提供了更好的错误处理、自动重试机制以及流畅的 API 设计。元素句柄(ElementHandle)则代表了页面中 DOM 元素的引用,通过它可以执行点击、填充、拖拽等交互操作。

架构设计

核心组件关系

graph TD
    A[Page] --> B[Locator API]
    A --> C[ElementHandle API]
    B --> D[Query Handler]
    C --> D
    D --> E[CSS Selector Handler]
    D --> F[ARIA Selector Handler]
    D --> G[Text Selector Handler]
    D --> H[XPath Selector Handler]
    D --> I[Pierce Selector Handler]
    D --> J[Custom Query Handler]

定位器与元素句柄的职责划分

组件职责特点
Locator描述如何定位元素,提供延迟解析和自动等待每次调用都会重新查询,支持重试
ElementHandle持有元素引用,执行具体操作可能因导航而失效,需要管理生命周期
QueryHandler实现具体的查询逻辑插件化设计,支持自定义扩展

资料来源:packages/puppeteer-core/src/api/locators/locators.ts:1-50

选择器类型详解

支持的选择器类型

Puppeteer 支持多种选择器语法,可通过前缀或组合方式使用:

选择器类型前缀示例说明
CSS 选择器div.container标准 CSS 选择器
ARIA 角色::-p-aria::-p-aria([name="搜索"])通过无障碍属性定位
文本匹配::-p-text::-p-text(提交)通过元素文本内容定位
XPath::-p-xpath::-p-xpath(//button)XPath 表达式
穿透选择器pierce/pierce/>>> button穿透 Shadow DOM 边界

资料来源:packages/puppeteer-core/src/common/CustomQueryHandler.ts:1-30

ARIA 选择器实现

ARIA 选择器通过无障碍 API 查询页面元素,其核心实现在 ARIAQuerySelector.ts 中:

export class ARIAQueryHandler {
  async queryOne(
    root: Node,
    selector: string
  ): Promise<ElementHandle<Node> | null> {
    // 使用 ARIA 属性查询 DOM
  }
}

该处理器利用浏览器原生 ARIA 查询能力,支持通过角色、名称、状态等属性定位元素。

资料来源:packages/puppeteer-core/src/injected/ARIAQuerySelector.ts:1-80

穿透选择器实现

穿透选择器(Pierce Selector)能够跨越 Shadow DOM 边界进行查询:

export class PierceQueryHandler {
  async queryOne(
    root: Node,
    selector: string
  ): Promise<ElementHandle<Node> | null> {
    // 递归遍历 shadowRoot 查找匹配元素
  }
}

该选择器通过递归遍历文档树和所有 Shadow DOM 来查找匹配的元素,适用于复杂的 Web 组件场景。

资料来源:packages/puppeteer-core/src/injected/PierceQuerySelector.ts:1-60

定位器 API

定位器工作流程

sequenceDiagram
    participant User as 用户
    participant Locator as Locator
    participant QueryHandler as QueryHandler
    participant Browser as 浏览器

    User->>Locator: 创建定位器
    Locator->>User: 返回 Locator 实例
    User->>Locator: waitHandle()
    Locator->>QueryHandler: 执行查询
    QueryHandler->>Browser: DOM 查询
    Browser-->>QueryHandler: 返回元素引用
    QueryHandler-->>Locator: ElementHandle
    Locator-->>User: Promise<Handle>

主要定位器方法

方法返回类型说明
locator(selector)Locator创建新的定位器
waitHandle()Promise<Handle>等待并返回元素句柄
first()Locator获取匹配的第一个元素定位器
nth(index)Locator获取指定索引的定位器
filter(options)Locator按条件过滤定位结果
map(fn)...映射操作
wait(options?)Promise等待元素出现

资料来源:packages/puppeteer-core/src/api/locators/locators.ts:50-150

使用示例

// 使用 locator API 进行稳定操作
const button = page.locator('button[type="submit"]');
await button.wait();
await button.click();

// 使用 ARIA 选择器
const searchInput = page.locator('::-p-aria([name="搜索框"])');

// 使用文本选择器
const submitBtn = page.locator('::-p-text(提交)');

// 穿透 Shadow DOM
const nestedButton = page.locator('pierce/>>> my-component >>> button');

元素句柄操作

元素句柄生命周期

graph LR
    A[创建 ElementHandle] --> B{页面导航}
    B -->|发生| C[句柄失效]
    B -->|未发生| D[可继续使用]
    C --> E[需重新查询]
    D --> F[执行操作]
    F --> G[释放资源]

ElementHandle 核心方法

方法说明返回值
click(options?)点击元素Promise<void>
fill(value)填充输入框Promise<void>
tap()触发触摸事件Promise<void>
hover()鼠标悬停Promise<void>
scrollIntoViewIfNeeded()滚动到可视区域Promise<void>
drag(...targets)执行拖拽操作Promise<void>
uploadFile(...filePaths)上传文件Promise<void>

资料来源:packages/puppeteer-core/src/api/ElementHandle.ts:50-200

CDP 实现细节

CDP(Chrome DevTools Protocol)实现提供了高性能的元素交互能力:

class ElementHandleImpl extends CDPJSHandle implements ElementHandle<Node> {
  #client: CdpCDPClient;
  
  async click(options?: ClickOptions): Promise<void> {
    const { x, y } = await this.clickablePoint();
    this.#client.input.dispatchMouseEvent({
      type: 'mousePressed',
      button: 'left',
      x, y
    });
  }
}

资料来源:packages/puppeteer-core/src/cdp/ElementHandle.ts:100-180

自定义查询处理器

注册自定义选择器

通过 CustomQueryHandler 可以扩展 Puppeteer 的查询能力:

import { register } from 'puppeteer';

register('jQuery', {
  queryOne: (root: Node, selector: string) => {
    // 实现 jQuery 选择逻辑
    return root.querySelector(selector);
  },
  queryAll: (root: Node, selector: string) => {
    return root.querySelectorAll(selector);
  }
});

自定义处理器结构

属性类型说明
queryOne`(root: Node, selector: string) => ElementHandle \null`返回第一个匹配元素
queryAll(root: Node, selector: string) => ElementHandle[]返回所有匹配元素

资料来源:packages/puppeteer-core/src/common/CustomQueryHandler.ts:30-80

等待与重试机制

定位器等待策略

graph TD
    A[开始等待] --> B{超时?}
    B -->|是| C[抛出 TimeoutError]
    B -->|否| D{元素存在?}
    D -->|否| E[重新查询]
    E --> B
    D -->|是| F{检查条件?}
    F -->|否| G[等待后重新检查]
    G --> B
    F -->|是| H[返回元素句柄]

等待选项

选项类型默认值说明
timeoutnumber继承自 page等待超时时间(毫秒)
state'attached' \'detached' \'visible' \'hidden''visible'元素状态条件
signalAbortSignalundefined中止信号

最佳实践

选择器性能优化

场景推荐选择器原因
唯一元素#iddata-testid最快,浏览器原生支持
语义化查询::-p-aria可访问性好,不依赖样式
复杂层级pierce/穿透 Shadow DOM
避免:nth-of-type 深层嵌套性能较差

稳定性建议

  1. 优先使用定位器 API:相比 ElementHandle,定位器提供自动重试和更好的错误信息
  2. 显式等待而非硬编码延迟:使用 wait() 方法等待元素状态变化
  3. 使用语义化选择器:通过 ARIA 属性而非 CSS 类名定位元素
  4. 管理资源生命周期:使用 using 声明自动释放 ElementHandle
// 推荐写法
await page.locator('button[type="submit"]').click();

// 避免硬编码延迟
// await new Promise(r => setTimeout(r, 2000));

相关文档

资料来源:[packages/puppeteer-core/src/api/locators/locators.ts:1-50](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/locators/locators.ts)

网络请求拦截与管理

Puppeteer 的网络请求拦截与管理功能允许开发者监控、修改、阻止或重定向网页发出的 HTTP 请求和响应。该功能是浏览器自动化测试和开发调试的核心能力之一,开发者可以借此实现广告屏蔽、请求日志记录、网络条件模拟、API 响应模拟等高级功能。

章节 相关页面

继续阅读本节完整说明和来源证据。

概述

Puppeteer 的网络请求拦截与管理功能允许开发者监控、修改、阻止或重定向网页发出的 HTTP 请求和响应。该功能是浏览器自动化测试和开发调试的核心能力之一,开发者可以借此实现广告屏蔽、请求日志记录、网络条件模拟、API 响应模拟等高级功能。

网络拦截机制基于事件驱动架构,通过 requestresponserequestfailedrequestfinished 等事件向外暴露网络活动的完整生命周期。Puppeteer 支持两种协议实现:Chrome DevTools Protocol (CDP) 和 WebDriver BiDi,本质上都是通过底层协议拦截和处理网络请求。

资料来源:packages/puppeteer-core/src/api/Page.ts:setRequestInterception

资料来源:[packages/puppeteer-core/src/api/Page.ts:setRequestInterception](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)

浏览器上下文与扩展支持

Puppeteer 的浏览器上下文(Browser Context)与扩展支持功能为开发者提供了在同一浏览器实例中创建隔离环境的能力,并支持加载 Chrome 扩展程序。这些功能使得高级自动化场景(如多租户隔离、扩展辅助测试、隐私浏览模式等)成为可能。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 核心概念

继续阅读本节完整说明和来源证据。

章节 抽象层设计

继续阅读本节完整说明和来源证据。

章节 CDP 实现

继续阅读本节完整说明和来源证据。

概述

Puppeteer 的浏览器上下文(Browser Context)与扩展支持功能为开发者提供了在同一浏览器实例中创建隔离环境的能力,并支持加载 Chrome 扩展程序。这些功能使得高级自动化场景(如多租户隔离、扩展辅助测试、隐私浏览模式等)成为可能。

核心概念

  • 浏览器上下文(Browser Context):一个独立的浏览器会话环境,拥有独立的 Cookie 存储、缓存和本地存储。不同上下文之间的数据完全隔离。
  • 扩展支持(Extension Support):Puppeteer 允许将未打包的扩展程序加载到浏览器实例中,以辅助自动化测试或实现自定义功能。

浏览器上下文架构

抽象层设计

Puppeteer 在 packages/puppeteer-core/src/api/ 目录下定义了 BrowserContext 的抽象接口。具体实现分别针对 CDP(Chrome DevTools Protocol)和 BiDi(WebDriver BiDi)协议提供了独立的实现类。

CDP 实现

在 CDP(Chrome DevTools Protocol)实现中,浏览器上下文通过创建独立的浏览器会话来实现隔离。CDP 协议原生支持上下文隔离,每个上下文拥有独立的 Target(目标),包括页面、服务工作者等。

BiDi 实现

在 BiDi(WebDriver BiDi)协议实现中,浏览器上下文作为独立的会话存在。BiDi 协议的上下文管理机制与 CDP 类似,但提供了标准化的跨浏览器支持。

扩展加载机制

启动配置

Puppeteer 通过 LaunchOptions 接口提供扩展支持配置。扩展可以在浏览器启动时加载:

interface LaunchOptions {
  /**
   * 如果为 true,则避免传递会阻止扩展启用的默认参数。
   * 传递字符串数组将加载提供的路径作为未打包的扩展程序。
   */
  enableExtensions?: boolean | string[];
}

资料来源:packages/puppeteer-core/src/node/LaunchOptions.ts:1-50

配置选项说明

参数类型默认值说明
enableExtensions`boolean \string[]`undefined启用扩展支持。布尔值启用所有默认扩展行为;字符串数组指定要加载的扩展路径
handleSIGINTbooleantrue在 Ctrl+C 时关闭浏览器进程
handleSIGTERMbooleantrue在 SIGTERM 时关闭浏览器进程
handleSIGHUPbooleantrue在 SIGHUP 时关闭浏览器进程

扩展上下文通信

exposeFunction 方法

exposeFunction 是 Page 类提供的核心方法,允许从浏览器页面调用 Node.js 环境中的函数。这对于扩展辅助测试和双向通信至关重要:

abstract exposeFunction(
  name: string,
  pptrFunction: Function | {default: Function},
): Promise<void>;

资料来源:packages/puppeteer-core/src/api/Page.ts:1-100

使用模式

#### 基本用法

import puppeteer from 'puppeteer';
import fs from 'node:fs';

const browser = await puppeteer.launch();
const page = await browser.newPage();
page.on('console', msg => console.log(msg.text()));

await page.exposeFunction('readfile', async filePath => {
  return new Promise((resolve, reject) => {
    fs.readFile(filePath, 'utf8', (err, text) => {
      if (err) reject(err);
      else resolve(text);
    });
  });
});

await page.evaluate(async () => {
  const content = await window.readfile('/etc/hosts');
  console.log(content);
});

await browser.close();

#### 与扩展配合使用

通过 exposeFunction,开发者可以创建桥接函数,使扩展程序能够与 Node.js 环境交互:

await page.exposeFunction('md5', async (myString: string) => {
  const hash = await window.md5(myString);
  console.log(`md5 of ${myString} is ${hash}`);
});

内部实现机制

在 CDP 实现中,exposeFunction 通过以下步骤工作:

  1. 在页面的执行上下文中注册一个全局函数
  2. 监听页面中对该函数的调用
  3. 将调用参数从浏览器环境传递到 Node.js 环境
  4. 执行提供的 Node.js 回调函数
  5. 将结果返回到浏览器环境

资料来源:packages/puppeteer-core/src/cdp/ExecutionContext.ts:1-80

evaluateOnNewDocument 功能

evaluateOnNewDocument 方法允许在每个新文档创建后、任何脚本运行前注入代码。这对于在页面加载前修改 JavaScript 环境非常有用:

abstract evaluateOnNewDocument<
  Params extends unknown[],
  Func extends (...args: Params) => unknown = (...args: Params) => unknown,
>(
  pageFunction: Func | string,
  ...args: Params
): Promise<NewDocumentScriptEvaluation>;

应用场景

#### 覆盖 navigator.languages

// preload.js
Object.defineProperty(navigator, 'languages', {
  get: function () {
    return ['en-US', 'en', 'bn'];
  },
});

// 在 Puppeteer 脚本中使用
const preloadFile = fs.readFileSync('./preload.js', 'utf8');
await page.evaluateOnNewDocument(preloadFile);

配置系统

全局配置接口

Puppeteer 提供了 Configuration 接口用于全局配置:

export interface Configuration {
  defaultBrowser?: SupportedBrowser;
  temporaryDirectory?: string;
  skipDownload?: boolean;
  logLevel?: 'silent' | 'error' | 'warn';
  experiments?: ExperimentsConfiguration;
  chrome?: ChromeSettings;
  ['chrome-headless-shell']?: ChromeHeadlessShellSettings;
  firefox?: FirefoxSettings;
}

资料来源:packages/puppeteer-core/src/common/Configuration.ts:1-80

环境变量覆盖

环境变量对应配置项说明
PUPPETEER_TMP_DIRtemporaryDirectory临时文件目录
PUPPETEER_SKIP_DOWNLOADskipDownload跳过浏览器下载
PUPPETEER_LOG_LEVELlogLevel日志级别
PUPPETEER_CHROME_SKIP_DOWNLOADchrome.skipDownload跳过 Chrome 下载
PUPPETEER_CHROME_DOWNLOAD_BASE_URLchrome.downloadBaseUrlChrome 下载基础 URL

调试支持

Puppeteer 提供了可配置的调试日志系统:

export const debug = (prefix: string): ((...args: unknown[]) => void) => {
  if (isNode) {
    return async (...logArgs: unknown[]) => {
      if (captureLogs) {
        capturedLogs.push(prefix + logArgs);
      }
      (await importDebug())(prefix)(logArgs);
    };
  }
  // 浏览器环境实现...
};

资料来源:packages/puppeteer-core/src/common/Debug.ts:1-60

调试通道

通道前缀说明
Page页面相关日志
BrowserContext浏览器上下文日志
Extension扩展相关日志
Target目标管理日志

使用方法

// 设置日志级别
window.__PUPPETEER_DEBUG='Page';        // 仅记录 Page 通道
window.__PUPPETEER_DEBUG='Page*';        // 记录所有 Page 开头的通道
window.__PUPPETEER_DEBUG='*';           // 记录所有通道

错误处理

执行上下文错误

Puppeteer 提供了专门的错误重写函数用于处理常见错误场景:

export function rewriteEvaluationError(error: unknown): never {
  if (error instanceof Error) {
    if (
      error.message.includes('ExecutionContext was destroyed') ||
      error.message.includes('Inspected target navigated or closed')
    ) {
      throw new Error(
        'Execution context was destroyed, most likely because of a navigation.',
      );
    }
  }
  throw error;
}

资料来源:packages/puppeteer-core/src/bidi/util.ts:1-80

导航超时处理

export function rewriteNavigationError(
  message: string,
  ms: number,
): (error: unknown) => never {
  return error => {
    if (error instanceof ProtocolError) {
      error.message += ` at ${message}`;
    } else if (error instanceof TimeoutError) {
      error.message = `Navigation timeout of ${ms} ms exceeded`;
    }
    throw error;
  };
}

完整使用示例

import puppeteer from 'puppeteer';

async function main() {
  // 启用扩展支持
  const browser = await puppeteer.launch({
    enableExtensions: ['/path/to/unpacked/extension'],
    handleSIGINT: true,
    handleSIGTERM: true,
    timeout: 30000,
  });

  // 创建隔离上下文
  const context = browser.createBrowserContext();
  const page = await context.newPage();

  // 设置调试日志
  page.on('console', msg => console.log('PAGE LOG:', msg.text()));

  // 暴露 Node.js 函数到页面
  await page.exposeFunction('getNodeVersion', () => process.version);
  await page.exposeFunction('readConfig', async () => {
    return {apiKey: 'xxx', endpoint: 'https://api.example.com'};
  });

  // 在文档创建前注入代码
  await page.evaluateOnNewDocument(() => {
    console.log('Document about to be created');
  });

  await page.goto('https://example.com');
  await browser.close();
}

main().catch(console.error);

最佳实践

  1. 资源清理:使用完毕后调用 browser.close()context.close() 释放资源
  2. 超时配置:根据网络状况和目标网站性能合理设置超时时间
  3. 扩展路径:使用绝对路径确保扩展能够正确加载
  4. 错误处理:实现健壮的错误处理逻辑,特别是导航超时和执行上下文销毁场景
  5. 调试日志:在开发阶段启用调试日志便于排查问题

相关资源

资料来源:[packages/puppeteer-core/src/node/LaunchOptions.ts:1-50]()

覆盖率检测与调试功能

Puppeteer 提供了丰富的覆盖率检测与调试功能,使开发者能够在浏览器自动化过程中收集性能指标、追踪代码执行、分析控制台输出以及诊断运行时错误。这些功能对于优化网页性能、调试自动化脚本以及生成详细的测试报告至关重要。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 模块关系

继续阅读本节完整说明和来源证据。

章节 关键组件

继续阅读本节完整说明和来源证据。

章节 JavaScript 代码覆盖率

继续阅读本节完整说明和来源证据。

概述

Puppeteer 提供了丰富的覆盖率检测与调试功能,使开发者能够在浏览器自动化过程中收集性能指标、追踪代码执行、分析控制台输出以及诊断运行时错误。这些功能对于优化网页性能、调试自动化脚本以及生成详细的测试报告至关重要。

覆盖率检测功能主要通过 Chrome DevTools Protocol (CDP) 实现,支持 JavaScript 代码覆盖率统计、堆快照捕获以及性能指标采集。调试功能则涵盖控制台消息捕获、页面事件监听、调试日志输出以及详细的错误报告机制。

核心架构

模块关系

Puppeteer 的覆盖率检测与调试系统由多个核心模块组成,各模块协同工作以提供完整的诊断能力。

graph TD
    A[Puppeteer 核心层] --> B[覆盖率模块]
    A --> C[调试模块]
    A --> D[追踪模块]
    B --> E[CDP Coverage API]
    C --> F[ConsoleMessage 处理]
    C --> G[Errors 处理]
    D --> H[CDP Tracing API]
    E --> I[CoverageResult]
    F --> J[控制台事件]
    G --> K[错误类型定义]
    H --> L[追踪数据]

关键组件

组件名称文件路径职责说明
Coveragepackages/puppeteer-core/src/cdp/Coverage.ts提供 JavaScript 和 CSS 覆盖率统计功能
Tracingpackages/puppeteer-core/src/cdp/Tracing.ts管理性能追踪和事件流记录
ConsoleMessagepackages/puppeteer-core/src/common/ConsoleMessage.ts处理和解析控制台消息
Errorspackages/puppeteer-core/src/common/Errors.ts定义错误类型和错误处理机制
Accessibilitypackages/puppeteer-core/src/cdp/Accessibility.ts提供无障碍访问相关诊断

覆盖率检测功能

JavaScript 代码覆盖率

Puppeteer 支持获取页面的性能指标数据,这些数据包括文档数量、帧数、JavaScript 事件监听器数量、DOM 节点数量以及布局和样式重算的统计信息。

性能指标数据结构定义如下:

属性名类型说明
Timestampnumber指标采样的时间戳(单调递增)
Documentsnumber页面中的文档数量
Framesnumber页面中的帧数量
JSEventListenersnumber页面中的 JavaScript 事件监听器数量
NodesnumberDOM 节点总数
LayoutCountnumber完整或部分页面布局的总次数
RecalcStyleCountnumber页面样式重算的总次数
LayoutDurationnumber所有页面布局的累计时长
RecalcStyleDurationnumber所有样式重算的累计时长
ScriptDurationnumberJavaScript 执行的总时长
TaskDurationnumber浏览器执行的所有任务累计时长
JSHeapUsedSizenumber已使用的 JavaScript 堆大小
JSHeapTotalSizenumberJavaScript 堆总大小

资料来源:packages/puppeteer-core/src/api/Page.ts:250-290

堆快照捕获

Puppeteer 提供了 captureHeapSnapshot() 方法用于捕获 JavaScript 堆的快照并写入文件。这对于内存泄漏排查和堆内存分析非常有价值。该方法为抽象方法,需要在具体的 Page 实现中由 CDP 或其他浏览器协议实现。

// 捕获堆快照的典型用法
const browser = await puppeteer.launch();
const page = await browser.newPage();

// 执行页面操作后捕获堆快照
await page.captureHeapSnapshot({ path: 'heap-snapshot.json' });

await browser.close();

CSS 覆盖率

通过 CDP 的 Coverage API,Puppeteer 能够追踪 CSS 规则的使用情况,帮助开发者识别页面中未使用的 CSS 样式。

调试功能

调试日志系统

Puppeteer 实现了灵活的调试日志系统,支持通过环境变量 window.__PUPPETEER_DEBUG 配置日志输出级别和通道。

// 输出所有调试日志
window.__PUPPETEER_DEBUG = '*';

// 输出特定通道的日志
window.__PUPPETEER_DEBUG = 'Page';

// 输出以指定前缀开头的所有通道
window.__PUPPETEER_DEBUG = 'Page*';

调试日志函数接受一个前缀参数,该前缀会被添加到每条日志消息的开头,便于区分不同模块的输出:

const log = debug('Page');
log('new page created');
// 输出: "Page: new page created"

资料来源:packages/puppeteer-core/src/common/Debug.ts:30-60

日志输出流程

graph LR
    A[日志调用] --> B{运行环境检测}
    B -->|Node.js| C[debug 模块]
    B -->|浏览器| D[环境变量检查]
    D --> E{匹配检查}
    E -->|完全匹配| F[console.log 输出]
    E -->|通配符匹配| F
    E -->|不匹配| G[无输出]
    C --> H[异步日志输出]

控制台消息处理

ConsoleMessage 模块负责解析和传递来自页面的控制台消息。该模块支持多种消息类型,包括日志、警告、错误、信息和调试消息。

消息类型说明典型用途
log日志消息一般性信息输出
warn警告消息潜在问题的提示
error错误消息运行时错误的报告
info信息消息提示性信息
debug调试消息开发调试信息

监听控制台消息的标准模式:

const browser = await puppeteer.launch();
const page = await browser.newPage();

page.on('console', msg => {
  console.log(`[${msg.type()}] ${msg.text()}`);
});

await page.goto('https://example.com');

await browser.close();

资料来源:packages/puppeteer-core/src/common/ConsoleMessage.ts

错误处理机制

Puppeteer 定义了完整的错误类型体系,确保各种运行时异常能够被正确识别和处理。

错误类型错误码说明
UnsupportedOperationError错误码定义在 Errors.ts不支持的操作错误
EvaluationError错误码定义在 Errors.tsJavaScript 评估错误
TimeoutError错误码定义在 Errors.ts操作超时错误
ProtocolError错误码定义在 Errors.tsCDP 协议通信错误

评估上下文中发生的异常会被捕获并转换为结构化的错误对象:

const {exceptionDetails, result: remoteObject} = await this.#client
  .send('Runtime.evaluate', {
    expression: expressionWithSourceUrl,
    contextId,
    returnByValue,
    awaitPromise: true,
    userGesture: true,
  })
  .catch(rewriteError);

if (exceptionDetails) {
  throw createEvaluationError(exceptionDetails);
}

资料来源:packages/puppeteer-core/src/cdp/ExecutionContext.ts:40-70

性能追踪功能

Tracing 模块概述

Tracing 模块提供了强大的性能追踪能力,能够记录页面的各种事件流并生成详细的追踪报告。这对于分析页面加载性能、识别性能瓶颈以及生成 Chrome DevTools 兼容的追踪文件非常有用。

追踪数据流

graph TD
    A[追踪开始] --> B[CDP Tracing.start]
    B --> C[事件收集阶段]
    C --> D[Page 事件]
    C --> E[Network 事件]
    C --> F[JavaScript 事件]
    D --> G[缓冲区写入]
    E --> G
    F --> G
    G --> H[CDP Tracing.end]
    H --> I[追踪数据处理]
    I --> J[结果输出]

无障碍功能诊断

Accessibility 模块提供了页面无障碍访问相关的诊断能力,帮助开发者检查页面元素的可访问性属性。

ARIA 选择器支持

Puppeteer 支持通过 ARIA 选择器查询页面元素,这依赖于 Accessibility 组件提供的基础能力:

// 使用 ARIA 选择器定位元素
await page.locator('::-p-aria(Search)').fill('automate beyond recorder');

配置选项

覆盖率相关配置

配置项类型默认值说明
defaultBrowserSupportedBrowser'chrome'默认浏览器类型
temporaryDirectorystringos.tmpdir()临时文件目录
skipDownloadbooleanfalse是否跳过浏览器下载
logLevel'silent' \'error' \'warn''warn'日志级别

浏览器启动调试选项

选项名称类型说明
executablePathstring浏览器可执行文件路径
ignoreDefaultArgsboolean \string[]是否忽略默认参数
enableExtensionsboolean \string[]启用扩展支持
handleSIGINTboolean是否处理 Ctrl+C 信号
handleSIGTERMboolean是否处理 SIGTERM 信号
handleSIGHUPboolean是否处理 SIGHUP 信号
timeoutnumber浏览器启动超时时间(毫秒)

资料来源:packages/puppeteer-core/src/node/LaunchOptions.ts:40-80

最佳实践

调试模式启用

在开发环境中启用完整调试日志:

PUPPETEER_DEBUG='*' node your-script.js

性能分析工作流

  1. 启动追踪:使用 Tracing API 开始记录性能数据
  2. 执行操作:在页面上执行待分析的操作
  3. 结束追踪:停止数据收集并获取结果
  4. 分析结果:使用 Chrome DevTools 或其他工具分析追踪数据

覆盖率采集建议

  • 在关键测试场景中启用覆盖率统计
  • 定期检查未使用的 CSS 和 JavaScript 代码
  • 结合性能指标识别优化机会

相关资源

资料来源:[packages/puppeteer-core/src/api/Page.ts:250-290]()

失败模式与踩坑日记

保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。

high 来源证据:Chrome Canary/Firefox Nightly test results

可能增加新用户试用和生产接入成本。

high 来源证据:Puppeteer v25

可能影响升级、迁移或版本选择。

high 来源证据:[Bug]: GHSA issued a false malicious package alert for puppeteer

可能增加新用户试用和生产接入成本。

high 来源证据:[Task]: Flaky `[fixtures.spec] Fixtures should dump browser process stderr`

可能影响授权、密钥配置或安全边界。

Pitfall Log / 踩坑日志

项目:puppeteer/puppeteer

摘要:发现 21 个潜在踩坑项,其中 4 个为 high/blocking;最高优先级:安装坑 - 来源证据:Chrome Canary/Firefox Nightly test results。

1. 安装坑 · 来源证据:Chrome Canary/Firefox Nightly test results

  • 严重度:high
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Chrome Canary/Firefox Nightly test results
  • 对用户的影响:可能增加新用户试用和生产接入成本。
  • 建议检查:来源问题仍为 open,Pack Agent 需要复核是否仍影响当前版本。
  • 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
  • 证据:community_evidence:github | cevd_1aabe120a9df47a2adbd293381b50a64 | https://github.com/puppeteer/puppeteer/issues/12379 | 来源类型 github_issue 暴露的待验证使用条件。

2. 安装坑 · 来源证据:Puppeteer v25

  • 严重度:high
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Puppeteer v25
  • 对用户的影响:可能影响升级、迁移或版本选择。
  • 建议检查:来源问题仍为 open,Pack Agent 需要复核是否仍影响当前版本。
  • 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
  • 证据:community_evidence:github | cevd_050f65ceff2a455da4a3538895a7538b | https://github.com/puppeteer/puppeteer/issues/14342 | 来源讨论提到 node 相关条件,需在安装/试用前复核。

3. 安全/权限坑 · 来源证据:[Bug]: GHSA issued a false malicious package alert for puppeteer

  • 严重度:high
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:[Bug]: GHSA issued a false malicious package alert for puppeteer
  • 对用户的影响:可能增加新用户试用和生产接入成本。
  • 建议检查:来源问题仍为 open,Pack Agent 需要复核是否仍影响当前版本。
  • 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
  • 证据:community_evidence:github | cevd_55588dfbd41442fdb8a2f4f1be57e4c9 | https://github.com/puppeteer/puppeteer/issues/14986 | 来源讨论提到 npm 相关条件,需在安装/试用前复核。

4. 安全/权限坑 · 来源证据:[Task]: Flaky `[fixtures.spec] Fixtures should dump browser process stderr`

  • 严重度:high
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:[Task]: Flaky [fixtures.spec] Fixtures should dump browser process stderr
  • 对用户的影响:可能影响授权、密钥配置或安全边界。
  • 建议检查:来源问题仍为 open,Pack Agent 需要复核是否仍影响当前版本。
  • 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
  • 证据:community_evidence:github | cevd_9b1ef7c38ed14c41b3e4ce786adcdf26 | https://github.com/puppeteer/puppeteer/issues/14774 | 来源讨论提到 windows 相关条件,需在安装/试用前复核。

5. 安装坑 · 来源证据:[Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26 (extract-zip 2.0.1)

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:[Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26 (extract-zip 2.0.1)
  • 对用户的影响:可能增加新用户试用和生产接入成本。
  • 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
  • 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
  • 证据:community_evidence:github | cevd_5d1f448d8768460a806ab32e8d4f6997 | https://github.com/puppeteer/puppeteer/issues/14957 | 来源讨论提到 node 相关条件,需在安装/试用前复核。

6. 安装坑 · 来源证据:[Bug]: `setViewport` crashes on Firefox if uncaught

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:[Bug]: setViewport crashes on Firefox if uncaught
  • 对用户的影响:可能阻塞安装或首次运行。
  • 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
  • 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
  • 证据:community_evidence:github | cevd_75bddb8a74194cf7a8978853f19db23a | https://github.com/puppeteer/puppeteer/issues/14989 | 来源讨论提到 node 相关条件,需在安装/试用前复核。

7. 安装坑 · 来源证据:[Bug]: chrome binary is not present when installing latest chrome

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:[Bug]: chrome binary is not present when installing latest chrome
  • 对用户的影响:可能增加新用户试用和生产接入成本。
  • 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
  • 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
  • 证据:community_evidence:github | cevd_1e85cdab2b684dda8e5c83f55b8ff7b6 | https://github.com/puppeteer/puppeteer/issues/14988 | 来源讨论提到 node 相关条件,需在安装/试用前复核。

8. 安装坑 · 来源证据:[Feature]: Make proxy-agent dependency optional

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:[Feature]: Make proxy-agent dependency optional
  • 对用户的影响:可能影响升级、迁移或版本选择。
  • 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
  • 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
  • 证据:community_evidence:github | cevd_195c51e4a5e84edda14a2a79b456821c | https://github.com/puppeteer/puppeteer/issues/13775 | 来源讨论提到 node 相关条件,需在安装/试用前复核。

9. 安装坑 · 来源证据:browsers: v3.0.0

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:browsers: v3.0.0
  • 对用户的影响:可能影响升级、迁移或版本选择。
  • 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
  • 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
  • 证据:community_evidence:github | cevd_bf2d83568c54447fbfd3047d24be0c48 | https://github.com/puppeteer/puppeteer/releases/tag/browsers-v3.0.0 | 来源讨论提到 node 相关条件,需在安装/试用前复核。

10. 能力坑 · 来源证据:browsers: v3.0.2

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个能力理解相关的待验证问题:browsers: v3.0.2
  • 对用户的影响:可能增加新用户试用和生产接入成本。
  • 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
  • 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
  • 证据:community_evidence:github | cevd_c9f08632e7ee4e9485d27b864a21e462 | https://github.com/puppeteer/puppeteer/releases/tag/browsers-v3.0.2 | 来源类型 github_release 暴露的待验证使用条件。

11. 能力坑 · 来源证据:puppeteer-core: v25.0.2

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个能力理解相关的待验证问题:puppeteer-core: v25.0.2
  • 对用户的影响:可能增加新用户试用和生产接入成本。
  • 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
  • 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
  • 证据:community_evidence:github | cevd_3a8b10a5263e4d6488e16972c8249a38 | https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v25.0.2 | 来源类型 github_release 暴露的待验证使用条件。

12. 能力坑 · 能力判断依赖假设

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:README/documentation is current enough for a first validation pass.
  • 对用户的影响:假设不成立时,用户拿不到承诺的能力。
  • 建议检查:将假设转成下游验证清单。
  • 防护动作:假设必须转成验证项;没有验证结果前不能写成事实。
  • 证据:capability.assumptions | github_repo:90796663 | https://github.com/puppeteer/puppeteer | README/documentation is current enough for a first validation pass.

13. 维护坑 · 来源证据:ng-schematics: v0.8.0

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题:ng-schematics: v0.8.0
  • 对用户的影响:可能影响升级、迁移或版本选择。
  • 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
  • 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
  • 证据:community_evidence:github | cevd_4e7ee6a70b1d4fb6879ab4670099d205 | https://github.com/puppeteer/puppeteer/releases/tag/ng-schematics-v0.8.0 | 来源讨论提到 node 相关条件,需在安装/试用前复核。

14. 维护坑 · 来源证据:puppeteer-core: v25.0.0

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题:puppeteer-core: v25.0.0
  • 对用户的影响:可能影响升级、迁移或版本选择。
  • 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
  • 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
  • 证据:community_evidence:github | cevd_3e6a5770b15146ddab5249f1aa687cae | https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v25.0.0 | 来源讨论提到 node 相关条件,需在安装/试用前复核。

15. 维护坑 · 来源证据:puppeteer: v25.0.0

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题:puppeteer: v25.0.0
  • 对用户的影响:可能影响升级、迁移或版本选择。
  • 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
  • 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
  • 证据:community_evidence:github | cevd_9294fdbab95d446887bdb54a11df66d2 | https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-v25.0.0 | 来源讨论提到 node 相关条件,需在安装/试用前复核。

16. 维护坑 · 维护活跃度未知

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:未记录 last_activity_observed。
  • 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
  • 建议检查:补 GitHub 最近 commit、release、issue/PR 响应信号。
  • 防护动作:维护活跃度未知时,推荐强度不能标为高信任。
  • 证据:evidence.maintainer_signals | github_repo:90796663 | https://github.com/puppeteer/puppeteer | last_activity_observed missing

17. 安全/权限坑 · 下游验证发现风险项

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 对用户的影响:下游已经要求复核,不能在页面中弱化。
  • 建议检查:进入安全/权限治理复核队列。
  • 防护动作:下游风险存在时必须保持 review/recommendation 降级。
  • 证据:downstream_validation.risk_items | github_repo:90796663 | https://github.com/puppeteer/puppeteer | no_demo; severity=medium

18. 安全/权限坑 · 存在评分风险

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 对用户的影响:风险会影响是否适合普通用户安装。
  • 建议检查:把风险写入边界卡,并确认是否需要人工复核。
  • 防护动作:评分风险必须进入边界卡,不能只作为内部分数。
  • 证据:risks.scoring_risks | github_repo:90796663 | https://github.com/puppeteer/puppeteer | no_demo; severity=medium

19. 安全/权限坑 · 来源证据:[Feature]: Reducing dependencies

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:[Feature]: Reducing dependencies
  • 对用户的影响:可能增加新用户试用和生产接入成本。
  • 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
  • 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
  • 证据:community_evidence:github | cevd_cb21a546ebb04ca39b334255b205c9da | https://github.com/puppeteer/puppeteer/issues/13552 | 来源讨论提到 node 相关条件,需在安装/试用前复核。

20. 维护坑 · issue/PR 响应质量未知

  • 严重度:low
  • 证据强度:source_linked
  • 发现:issue_or_pr_quality=unknown。
  • 对用户的影响:用户无法判断遇到问题后是否有人维护。
  • 建议检查:抽样最近 issue/PR,判断是否长期无人处理。
  • 防护动作:issue/PR 响应未知时,必须提示维护风险。
  • 证据:evidence.maintainer_signals | github_repo:90796663 | https://github.com/puppeteer/puppeteer | issue_or_pr_quality=unknown

21. 维护坑 · 发布节奏不明确

  • 严重度:low
  • 证据强度:source_linked
  • 发现:release_recency=unknown。
  • 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
  • 建议检查:确认最近 release/tag 和 README 安装命令是否一致。
  • 防护动作:发布节奏未知或过期时,安装说明必须标注可能漂移。
  • 证据:evidence.maintainer_signals | github_repo:90796663 | https://github.com/puppeteer/puppeteer | release_recency=unknown

来源:Doramagic 发现、验证与编译记录