Skip to main content
Version: 23.10.1

调试

¥Debugging

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

¥Debugging with Puppeteer can be an arduous task. There is no single method for debugging all possible issues since Puppeteer touches many distinct components of a browser such as network requests and Web APIs. On a high note, Puppeteer provides several methods for debugging which hopefully do cover all possible issues.

背景

¥Background

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

¥In general, there are two possible sources of an issue: Code running on Node.js (which we call server code), and code running in the browser (which we call client code). There is also a third possible source being the browser itself (which we call internal code or browser code), but if you suspect this is the source after attempting the methods below, we suggest searching existing issues before filing an issue.

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

¥Debugging methods for all situations

这些方法可用于调试任何情况。在深入研究更复杂的方法之前,应将它们用作快速健全性检查。

¥These methods can be used to debug any situation. These should be used as a quick sanity check before diving into more complex methods.

关闭 headless

¥Turn off headless

有时查看浏览器显示的内容很有用。不要以 headless 模式启动,而是启动完整版本的浏览器并将 headless 设置为 false

¥Sometimes it's useful to see what the browser is displaying. Instead of launching in headless mode, launch a full version of the browser with headless set to false:

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

Puppeteer "slow-mo"

slowMo 选项会使 Puppeteer 操作减慢指定的毫秒数。这是帮助了解正在发生的情况的另一种方法。

¥The slowMo option slows down Puppeteer operations by a specified amount of milliseconds. It's another way to help see what's going on.

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

客户端代码的调试方法

¥Debugging methods for client code

捕获 console.* 输出

¥Capture console.* output

由于客户端代码运行在浏览器中,因此在客户端代码中执行 console.* 不会直接登录到 Node.js。但是,你可以对 console 事件执行 listen (page.on),该事件返回包含记录文本的有效负载。

¥Since client code runs in the browser, doing console.* in client code will not directly log to Node.js. However, you can listen (page.on) for the console event which returns a payload with the logged text.

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

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

使用浏览器中的调试器

¥Use the debugger in the browser

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

    ¥Set devtools to true when launching Puppeteer:

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

    ¥Add debugger inside any client code you want debugged. For example,

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

    浏览器现在将停在调试模式下找到 debugger 单词的位置。

    ¥The Browser will now stop in the location the debugger word is found in debug mode.

服务器代码的调试方法

¥Debugging methods for server code

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

¥Use the debugger in Node.js (Chrome/Chromium-only)

由于服务器代码与客户端代码混合在一起,因此这种调试方法与浏览器紧密相连。例如,你可以在服务器脚本中跳过 await page.click(),并在浏览器中看到单击发生的情况。

¥Since server code intermingles with client code, this method of debugging is closely tied with the browser. For example, you can step over await page.click() in the server script and see the click happen in the browser.

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

¥Note that you won't be able to run await page.click() in DevTools console due to this Chromium bug, so if you want to try something out, you have to add it to your test file.

  1. headless 设置为 false

    ¥Set headless to false.

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

    ¥Add debugger to any server code you want debugged. For example,

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

    ¥Run your server code with --inspect-brk. For example,

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

    ¥In the opened Chrome/Chromium browser, open chrome://inspect/#devices and click inspect.

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

    ¥In the newly opened test browser, press F8 to resume test execution.

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

    ¥Now your debugger statement will be hit and you can debug in the test browser.

记录 DevTools 协议流量

¥Log DevTools protocol traffic

如果所有其他方法都失败,则 Puppeteer 和 DevTools 协议之间可能存在问题。你可以在运行脚本之前通过设置 DEBUG 环境变量来对此进行调试。这将在 puppeteer 命名空间下通过 debug 记录内部流量。

¥If all else fails, it's possible there may be an issue between Puppeteer and the DevTools protocol. You can debug this by setting the DEBUG environment variable before running your script. This will log internal traffic via debug under the puppeteer namespace.

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

# Prevent truncating of long messages
env DEBUG="puppeteer:*" env DEBUG_MAX_STRING_LENGTH=null node script.js

# Protocol traffic can be rather noisy. This example filters out all Network domain messages
env DEBUG="puppeteer:*" env DEBUG_COLORS=true node script.js 2>&1 | grep -v '"Network'

# Filter out all protocol messages but keep all other logging
env DEBUG="puppeteer:*,-puppeteer:protocol:*" node script.js

记录待处理的协议调用

¥Log pending protocol calls

如果你遇到异步 Puppeteer 调用未解决的问题,请尝试使用 debugInfo 接口记录挂起的回调,以查看导致什么调用的原因:

¥If you encounter issues with async Puppeteer calls not getting resolved, try logging pending callbacks by using the debugInfo interface to see what call is the cause:

console.log(browser.debugInfo.pendingProtocolErrors);

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

¥The getter returns a list of Error objects and the stacktraces of the error objects indicate which code triggered a protocol call.

浏览器代码的调试方法

¥Debugging methods for the browser code

¥Print browser logs

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

¥If the browser unexpectedly crashes or does not launch properly, it could be useful to inspect logs from the browser process by setting the launch attribute dumpio to true.

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

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

¥In this case, Puppeteer forwards browser logs to the Node process' stdio.