Javascript 如何通过Headless Chrome Runtime.evaluate在终端中获取console.log输出

Javascript 如何通过Headless Chrome Runtime.evaluate在终端中获取console.log输出,javascript,node.js,google-chrome-devtools,google-chrome-headless,Javascript,Node.js,Google Chrome Devtools,Google Chrome Headless,我在这里关注这篇文章: 但我似乎无法在Mac终端中获得console.log输出。它可能在ChromeDevTools窗口内,我看不到 那么如何通过Runtime.evaluate表达式在Mac终端中获得console.log输出? 我的代码如下: const chromeLauncher = require('chrome-launcher'); const CDP = require('chrome-remote-interface'); const file = require('fs'

我在这里关注这篇文章:

但我似乎无法在Mac终端中获得
console.log
输出。它可能在ChromeDevTools窗口内,我看不到

那么如何通过Runtime.evaluate表达式在Mac终端中获得console.log输出?

我的代码如下:

const chromeLauncher = require('chrome-launcher');
const CDP = require('chrome-remote-interface');
const file = require('fs');

(async function() {
  async function launchChrome() {
    return await chromeLauncher.launch({
      chromeFlags: [
        '--headless',
        '--disable-gpu'
      ]
    });
  }
  const chrome = await launchChrome();
  const protocol = await CDP({
    port: chrome.port
  });

  const {
    DOM,
    Network,
    Page,
    Emulation,
    Runtime
  } = protocol;

  await Promise.all([Network.enable(), Page.enable(), Runtime.enable(), DOM.enable()]);

  Page.navigate({url: 'https://www.chromestatus.com/'});

  Page.loadEventFired(async () => {
    const result = await Runtime.evaluate({expression: 'console.log(\'aaa\')'});

    protocol.close();
    chrome.kill(); 
  });

})();

我一直在做这方面的研究;以下是我的一些发现:

评估时:

const result = await Runtime.evaluate({ expression: 'console.log("aaa")' });
结果总是:

{结果:{type:'未定义'}}

但是,以下表达式:

const result = await Runtime.evaluate({expression: 'window.location.toString()'});
返回:

{结果:{类型:'string', 值:'}}

现在,如果我在不调用函数的情况下计算函数:

const result = await Runtime.evaluate({ expression: 'console.log' });
结果设置为:

{结果:{类型:'函数', 类名:“函数”, 描述:'函数日志(){[本机代码]}', objectId:“{”injectedScriptId“:2,“id“:1}}”

因此,我做了进一步的挖掘,发现每次在求值时调用
console.log
,都会触发console对象上的messageAdded事件

因此,我继续启用了Console对象,并向messageAdded事件添加了一个侦听器,现在我可以按预期成功捕获控制台条目

这就是我所做的:

const chromeLauncher = require('chrome-launcher');
const CDP = require('chrome-remote-interface');
const file = require('fs');

(async function() {
  async function launchChrome() {
    return await chromeLauncher.launch({
      chromeFlags: [
        '--headless',
        '--disable-gpu'
      ]
    });
  }
  const chrome = await launchChrome();
  const protocol = await CDP({
    port: chrome.port
  });

  const {
    DOM,
    Network,
    Page,
    Emulation,
    Runtime,
    Console
  } = protocol;

  await Promise.all([Network.enable(), Page.enable(), DOM.enable(), Runtime.enable(), Console.enable()]);

  await Page.navigate({url: 'https://www.chromestatus.com/'});

  // REMARKS: messageAdded is fired every time a new console message is added
  Console.messageAdded((result) => {
    console.log(result);
  });

  Page.loadEventFired(async () => {
    const result = await Runtime.evaluate({ expression: 'console.log("aaa")' });

    // REMARKS: When evaluating console.log, result.result.value is undefined.
    console.log(result);

    protocol.close();
    chrome.kill(); 
  });

})();

/* Output from listening on messageAdded:
{ message: 
   { source: 'console-api',
     level: 'log',
     text: 'aaa',
     url: '',
     line: 1,
     column: 9 } }
*/
我从你那里得到了细节

从文件中:

Console.messageAdded

添加新控制台消息时发出。
希望这有帮助

对于那些希望以一种不太复杂的方式从页面获取数据的人,我推荐。它有一个比chrome远程接口更清晰的高级API。在我看来,最好的特性是它能够接受javascript函数而不是字符串进行计算

假设我们想在给定页面的上下文中从API获取一些数据

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com/');

  let result = await page.evaluate(async () => {
    // here comes the code which gets executed in browser
    return await fetch('index.html').then(response => response.text());
  });

  console.log(result);

  await browser.close();
})();

上帝之母。为什么会这么复杂。谢谢@惠普。哈哈,我完全明白你的意思。当然可以,很乐意帮忙!别忘了赏金P