调试
¥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
-
启动 Puppeteer 时将
devtools设置为true:¥Set
devtoolstotruewhen launching Puppeteer:const browser = await puppeteer.launch({devtools: true}); -
在你想要调试的任何客户端代码中添加
debugger。例如,¥Add
debuggerinside any client code you want debugged. For example,await page.evaluate(() => {
debugger;
});浏览器现在将停在调试模式下找到
debugger单词的位置。¥The Browser will now stop in the location the
debuggerword 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.
-
将
headless设置为false。¥Set
headlesstofalse. -
将
debugger添加到你想要调试的任何服务器代码中。例如,¥Add
debuggerto any server code you want debugged. For example,debugger;
await page.click('a[target=_blank]'); -
使用
--inspect-brk运行你的服务器代码。例如,¥Run your server code with
--inspect-brk. For example,node --inspect-brk path/to/script.js -
在打开的 Chrome/Chromium 浏览器中,打开
chrome://inspect/#devices并单击inspect。¥In the opened Chrome/Chromium browser, open
chrome://inspect/#devicesand clickinspect. -
在新打开的测试浏览器中,按
F8恢复测试执行。¥In the newly opened test browser, press
F8to resume test execution. -
现在你的
debugger语句将被命中,你可以在测试浏览器中进行调试。¥Now your
debuggerstatement 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.
日志可能包含敏感信息。
¥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.