调试
使用 Puppeteer进行调试可能是一项艰巨的任务。由于 Puppeteer会涉及浏览器的许多不同组件(例如网络请求和 Web API),因此不存在能够调试所有可能问题的_单一_方法。值得庆幸的是,Puppeteer提供了_多种_调试方法,希望这些方法能够覆盖所有可能的问题。
背景
一般来说,问题可能有两个来源:在 Node.js上运行的代码(我们称之为_服务器代码_),以及在浏览器中运行的代码(我们称之为_客户端代码_)。还有第三个可能的来源,即浏览器本身(我们称之为_内部代码_或_浏览器代码_),但如果你在尝试了以下方法之后怀疑这是问题来源,我们建议先搜索现有问题,再提交问题。
适用于所有情况的调试方法
这些方法可用于调试任何情况。在深入使用更复杂的方法之前,应先用这些方法进行快速检查。
关闭 headless
有时查看浏览器正在显示的内容会很有用。与其以headless模式启动,不如将headless设置为false来启动浏览器的完整版本:
const browser = await puppeteer.launch({headless: false});
Puppeteer "slow-mo"
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 bug,你无法在 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协议之间可能存在问题。你可以通过在运行脚本之前设置NODE_DEBUG环境变量来调试此问题。这会在puppeteer命名空间下,通过 Node内置的util.debuglog记录内部流量。
日志可能包含敏感信息。
# Basic verbose logging
env NODE_DEBUG="puppeteer:*" node script.js
记录挂起的协议调用
如果你遇到异步 Puppeteer调用无法完成的问题,可以尝试使用debugInfo接口记录挂起的回调,以查看是哪个调用导致了问题:
console.log(browser.debugInfo.pendingProtocolErrors);
该 getter返回一个Error对象列表,错误对象的堆栈跟踪会指出是哪个代码触发了协议调用。
浏览器代码的调试方法
打印浏览器日志
如果浏览器意外崩溃或无法正常启动,将启动属性dumpio设置为true以检查浏览器进程的日志可能会很有用。
const browser = await puppeteer.launch({
dumpio: true,
});
在这种情况下,Puppeteer会将浏览器日志转发到 Node进程的 stdio。