调试
¥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
devtools
totrue
when launching Puppeteer:const browser = await puppeteer.launch({devtools: true});
-
在你想要调试的任何客户端代码中添加
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.
-
将
headless
设置为false
。¥Set
headless
tofalse
. -
将
debugger
添加到你想要调试的任何服务器代码中。例如,¥Add
debugger
to 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/#devices
and clickinspect
. -
在新打开的测试浏览器中,按
F8
恢复测试执行。¥In the newly opened test browser, press
F8
to resume test execution. -
现在你的
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.