调试
🌐 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“慢动作”
🌐 Puppeteer "slow-mo"
[slowMo](../api/puppeteer.connectoptions) 选项会将 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。不过,你可以监听 (page.on) console 事件,该事件会返回包含记录文本的载荷。
🌐 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
-
在启动 Puppeteer 时,将
devtools设置为true:const browser = await puppeteer.launch({devtools: true}); -
在你希望调试的任何客户端代码中添加
debugger。例如,await page.evaluate(() => {
debugger;
});浏览器现在将在调试模式中
debugger单词被找到的位置停止。
服务器代码的调试方法
🌐 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 bug,你无法在 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.
-
将
headless设置为false。 -
将
debugger添加到任何你想调试的服务器代码中。例如,debugger;
await page.click('a[target=_blank]'); -
使用
--inspect-brk运行你的服务器代码。例如,node --inspect-brk path/to/script.js -
在已打开的 Chrome/Chromium 浏览器中,打开
chrome://inspect/#devices并点击inspect。 -
在新打开的测试浏览器中,按
F8以继续测试执行。 -
现在你的
debugger语句将被执行,你可以在测试浏览器中进行调试。
记录 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.
日志可能包含敏感信息。
🌐 The logs may include sensitive information.
# 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.