Puppeteer 中文文档v25.8.0

调试

使用 Puppeteer进行调试可能是一项艰巨的任务。由于 Puppeteer会涉及浏览器的许多不同组件(例如网络请求和 Web API),因此不存在能够调试所有可能问题的_单一_方法。值得庆幸的是,Puppeteer提供了_多种_调试方法,希望这些方法能够覆盖所有可能的问题。

背景

一般来说,问题可能有两个来源:在 Node.js上运行的代码(我们称之为_服务器代码_),以及在浏览器中运行的代码(我们称之为_客户端代码_)。还有第三个可能的来源,即浏览器本身(我们称之为_内部代码_或_浏览器代码_),但如果你在尝试了以下方法之后怀疑这是问题来源,我们建议先搜索现有问题,再提交问题

适用于所有情况的调试方法

这些方法可用于调试任何情况。在深入使用更复杂的方法之前,应先用这些方法进行快速检查。

关闭 headless

有时查看浏览器正在显示的内容会很有用。与其以headless模式启动,不如将headless设置为false来启动浏览器的完整版本:

const browser = await puppeteer.launch({headless: false});

Puppeteer "slow-mo"

slowMo选项会按指定的毫秒数减慢 Puppeteer操作的速度。这也是帮助查看正在发生什么的另一种方式。

const browser = await puppeteer.launch({
  headless: false,
  slowMo: 250, // slow down by 250ms
});

客户端代码的调试方法

捕获 console.* 输出

由于客户端代码在浏览器中运行,因此在客户端代码中使用console.*不会直接记录到 Node.js。不过,你可以监听(page.on)console事件,该事件会返回包含所记录文本的有效载荷。

page.on('console', msg => console.log('PAGE LOG:', msg.text()));

await page.evaluate(() => console.log(`url is ${location.href}`));

在浏览器中使用调试器

  1. 启动 Puppeteer时将devtools设置为true

    const browser = await puppeteer.launch({devtools: true});
    
  2. 在要调试的任何客户端代码中添加debugger。例如,

    await page.evaluate(() => {
      debugger;
    });
    

    现在,浏览器将在调试模式下停止在找到debugger关键字的位置。

服务器代码的调试方法

在 Node.js 中使用调试器(仅限 Chrome/Chromium)

由于服务器代码与客户端代码相互交织,这种调试方法与浏览器密切相关。例如,你可以在服务器脚本中单步执行await page.click(),并在浏览器中看到点击的发生。

请注意,由于这个Chromium bug,你无法在 DevTools控制台中运行await page.click(),因此如果你想尝试某些内容,必须将其添加到测试文件中。

  1. headless设置为false

  2. 在要调试的任何服务器代码中添加debugger。例如,

    debugger;
    await page.click('a[target=_blank]');
    
  3. 使用--inspect-brk运行服务器代码。例如,

    node --inspect-brk path/to/script.js
    
  4. 在打开的 Chrome/Chromium浏览器中,打开chrome://inspect/#devices并点击inspect

  5. 在新打开的测试浏览器中,按F8恢复测试执行。

  6. 现在你的debugger语句将被命中,你就可以在测试浏览器中进行调试了。

记录 DevTools 协议流量

如果其他方法都不起作用,那么 Puppeteer与 DevTools协议之间可能存在问题。你可以通过在运行脚本之前设置NODE_DEBUG环境变量来调试此问题。这会在puppeteer命名空间下,通过 Node内置的util.debuglog记录内部流量。

⚠️警告

日志可能包含敏感信息。

# Basic verbose logging
env NODE_DEBUG="puppeteer:*" node script.js

记录挂起的协议调用

如果你遇到异步 Puppeteer调用无法完成的问题,可以尝试使用debugInfo接口记录挂起的回调,以查看是哪个调用导致了问题:

console.log(browser.debugInfo.pendingProtocolErrors);

该 getter返回一个Error对象列表,错误对象的堆栈跟踪会指出是哪个代码触发了协议调用。

浏览器代码的调试方法

打印浏览器日志

如果浏览器意外崩溃或无法正常启动,将启动属性dumpio设置为true以检查浏览器进程的日志可能会很有用。

const browser = await puppeteer.launch({
  dumpio: true,
});

在这种情况下,Puppeteer会将浏览器日志转发到 Node进程的 stdio。