【问题标题】:Puppeteer log inside page.evaluatePuppeteer 记录在 page.evaluate
【发布时间】:2018-02-22 05:21:36
【问题描述】:

如何在 page.evaluate 中控制台记录某些内容,将其传递给节点并在页面评估期间使用它?

我实际上想记录页面的进度。评估到控制台并向用户显示一些结果。

【问题讨论】:

  • 当您说“用户”时,您是指 Puppeteer/Node 上下文还是浏览器上下文?如果您指的是 Puppeteer/Node,请参阅 this answer 以将对象打印到控制台。

标签: javascript node.js puppeteer


【解决方案1】:

puppeteer 12 的更新,改编自 the current documentation

page.on('console', async (msg) => {
  const msgArgs = msg.args();
  for (let i = 0; i < msgArgs.length; ++i) {
    console.log(await msgArgs[i].jsonValue());
  }
});

await page.evaluate(() => console.log('hello', 5));
await page.evaluate(() => console.log({ foo: 'bar' }));
await page.evaluate(() => console.log([1, 2, 3, 4, 5]));

显示以下结果:

hello  
5  
{ foo: 'bar' }  
[ 1, 2, 3, 4, 5 ]  

【讨论】:

  • 我建议使用 consoleObj.text() 而不是 _text 因为 _text 表示使用私有变量
  • @Colin 嗨,你知道除了 .text() 之外是否还有其他属性?如果我想得到一个打印到控制台的数组缓冲区怎么办?
  • 即使我没有记录任何内容,此消息 “加载资源失败:服务器响应状态为 404 ()” 也会出现在我的控制台中
  • 这个不打印数组,只给JSHandle@array
  • @tim-montague 更新为最新的 pptr
【解决方案2】:

让它完全按照您的预期工作的最简单方法

const page = await browser.newPage();
page.on('console', (log) => console[log._type](log._text));

【讨论】:

    【解决方案3】:

    以前提供的许多答案今天不再适用。在某些页面上可能非常烦人的一件事是污染输出的“警告”消息。解决此问题的一种方法是过滤消息的类型。以下代码有助于减少噪音并适用于当前版本的 Puppeteer:

    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    page.on('console', consoleMessageObject => function (consoleMessageObject) {
        if (consoleMessageObject._type !== 'warning') {
            console.debug(consoleMessageObject._text)
        }
    });
    
    await page.goto('https://google.com');
    const result = await page.evaluate(() => {
        console.log('Browser scope.');
        return 'Normal scope.';
    });
    console.log(result)
    

    【讨论】:

      【解决方案4】:

      我喜欢@Vaviloff 的回答,但是当您可能只需要文本时,您将记录整个 ConsoleMessage 对象。因此,我个人使用以下内容:

      const EOL = require('os').EOL;
      const _page = await browser.newPage();
      
      _page.on('console', _fCleanLog);
      
      function _fCleanLog(ConsoleMessage) {
          console.log(ConsoleMessage.text + EOL);
      }
      

      【讨论】:

        【解决方案5】:

        1.15.x 及更高版本的更新 - 2020 年 1 月

        在最新版本中,args 已替换为 _args。

        因此,当您使用 page.evaluate()page.evaluateHandle() 并希望将浏览器上下文中的 console.log() 文本返回到节点时,请使用以下代码并确保在任何 console.log() 调用之前设置侦听器:

        代码:

            // First we register our listener.
            page.on('console', msg => {
            for (let i = 0; i < msg._args.length; ++i)
                console.log(`${i}: ${msg._args[i]}`);
            });
        
            // Then we call the log.
            page.evaluate(() => console.log('Hello World'));
        

        说明:

        您无法在节点控制台中看到 console.log() 文本或在 page.evaluate()page.evaluateHandle() 内设置节点断点,因为这些函数中的代码仅在浏览器上下文中运行。如果您以非无头模式启动 puppeteer,您会在浏览器中看到 console.log() 消息。

        旁注:

        在大多数情况下,您实际上并不需要在浏览器上下文中登录,您可以在浏览器“开发者工具”部分的“控制台”选项卡中执行相同的工作。

        【讨论】:

          【解决方案6】:

          在此代码示例中实现notifyUi 函数:

          const page = await browser.newPage();
          page.on('console', (...args) => {
              this.notifyUi('[chrome] ' + args[0]);
          });
          await page.goto(url);
          const result = await page.evaluate(() => {
              console.log('I am alive');
              return Promise.resolve(true);
          });
          this.notifyUi('Evaluation returned with ' + result);
          

          【讨论】:

            【解决方案7】:
            const page = await browser.newPage();
            page.on("console", msg => {
            for (let i = 0; i < msg.args().length; ++i)
            console.log(`${i}: ${msg.args()[i]}`);
            });
            

            如果上述方法均无效,请尝试此方法。不显示错误日志,只显示我创建的日志。

            【讨论】:

              【解决方案8】:

              如果将来对任何人有帮助,我会尝试分享我的解决方法。

              1. 将所有控制台输出打印到标准输出,包括警告、错误、日志:

                page = await browser.newPage();
                page.on("console", (consoleObj) => console.log(consoleObj.text()));
                
              2. 打印除警告之外的所有内容:

                page.on('console', consoleObj => {
                    if (consoleObj.type() !== 'warning') {
                        console.log(consoleObj.text());
                    }
                })
                
              3. 仅打印日志(例如:console.logs)。

                page.on('console', consoleObj => {
                    if (consoleObj.type() === 'log') {
                        console.log(consoleObj.text());
                    }
                })
                

              最后一个帮助我更有效地调试。

              【讨论】:

                【解决方案9】:

                我将this solution 分享给希望了解如何获取评估返回值的未来读者。

                const element = await page.$("a selector");
                const text = await page.evaluate(element => element.textContent);
                

                【讨论】:

                  【解决方案10】:
                  await page.evaluate(()=>{
                        var string = 'I want to print this';
                        return string;
                  }).then(console.log);
                          
                  

                  【讨论】:

                    【解决方案11】:

                    2021 年的今天,puppeteer 8.x.x 的主要答案没有向我们展示控制台对象的完整描述。例如,您无法获取所有错误堆栈跟踪文本,message.text() 仅包含有关 js 错误的一些信息。

                    我最好的方法在这里的另一条评论https://stackoverflow.com/a/66801550/9026103

                    【讨论】:

                      【解决方案12】:
                      const page = await browser.newPage();
                      page.on('console', ConsoleMessage => console.log(ConsoleMessage.text));
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2019-09-03
                        • 2020-07-20
                        • 1970-01-01
                        • 1970-01-01
                        • 2019-10-20
                        • 2020-04-07
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多