调试
使用 Puppeteer 进行调试可能是一项艰巨的任务。 由于 Puppeteer 涉及浏览器的许多不同组件,例如网络请求和 Web API,因此没有单一方法可以调试所有可能的问题。 值得一提的是,Puppeteer 提供了多种调试方法,希望能够涵盖所有可能的问题。
背景
一般来说,问题可能有两个来源:在 Node.js 上运行的代码(我们称之为服务器代码),以及在浏览器中运行的代码(我们称之为客户端代码)。 还有第三个可能的来源是浏览器本身(我们称之为内部代码或浏览器代码),但如果您在尝试以下方法后怀疑这是根源,我们建议您在提交问题之前,先搜索现有问题。
适用于所有情况的调试方法
这些方法可用于调试任何情况。 在深入研究更复杂的方法之前,应将这些方法用作快速的健全性检查。
关闭 headless
有时,查看浏览器显示的内容很有用。 不要以 headless
模式启动,而是使用 headless
设置为 false
启动浏览器的完整版本
const browser = await puppeteer.launch({headless: false});
Puppeteer “慢动作”
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}`));
在浏览器中使用调试器
-
启动 Puppeteer 时,将
devtools
设置为true
const browser = await puppeteer.launch({devtools: true});
-
在要调试的任何客户端代码中添加
debugger
。 例如,await page.evaluate(() => {
debugger;
});浏览器现在将在调试模式下停止在
debugger
单词所在的位置。
用于服务器代码的调试方法
在 Node.js 中使用调试器(仅限 Chrome/Chromium)
由于服务器代码与客户端代码混合在一起,因此这种调试方法与浏览器紧密相关。 例如,您可以单步执行服务器脚本中的 await page.click()
,并查看浏览器中发生的点击操作。
请注意,由于此 Chromium 错误,您将无法在 DevTools 控制台中运行 await page.click()
,因此如果您想尝试某些操作,则必须将其添加到您的测试文件中。
-
将
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 协议流量
如果所有其他方法都失败了,则可能是 Puppeteer 和 DevTools 协议之间存在问题。 您可以通过在运行脚本之前设置 DEBUG
环境变量来调试此问题。 这将通过 debug
在 puppeteer
命名空间下记录内部流量。
# 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
记录挂起的协议调用
如果您遇到异步 Puppeteer 调用未得到解决的问题,请尝试使用 debugInfo
接口记录挂起的回调,以查看是什么调用导致的问题
console.log(browser.debugInfo.pendingProtocolErrors);
getter 返回一个 Error
对象列表,并且错误对象的堆栈跟踪指示哪个代码触发了协议调用。
用于浏览器代码的调试方法
打印浏览器日志
如果浏览器意外崩溃或无法正常启动,则可以通过将启动属性 dumpio
设置为 true
来检查浏览器进程的日志,这可能会很有用。
const browser = await puppeteer.launch({
dumpio: true,
});
在这种情况下,Puppeteer 会将浏览器日志转发到 Node 进程的 stdio。