调试
使用 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 的 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 协议之间存在问题。您可以通过在运行脚本之前设置 `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