javascript - 如何使用 chrome-remote-interface Node js 获取多个 DOM 元素?

标签 javascript node.js chrome-remote-debugging

我只是想用 chrome-remote-interface 构建一个爬虫,但我不知道如何获取多个 dom 元素,例如特定目标 id、类。

例如:

price = document.getelementbyid('price')

name= document.getelementbyid('name')

代码

    const CDP = require('chrome-remote-interface');
    CDP((client) => {
      // Extract used DevTools domains.
      const {Page, Runtime} = client;

      // Enable events on domains we are interested in.
      Promise.all([
        Page.enable()
      ]).then(() => {
        return Page.navigate({url: 'http://example.com'})
      });

      // Evaluate outerHTML after page has loaded.
      Page.loadEventFired(() => {
        Runtime.evaluate({expression: 'document.body.outerHTML'}).then((result) => {
//How to get Multiple Dom elements
          console.log(result.result.value);
          client.close();
        });
      });
    }).on('error', (err) => {
      console.error('Cannot connect to browser:', err);
    });

更新

const CDP = require('chrome-remote-interface');

CDP((client) => {
  // Extract used DevTools domains.
  const {DOM,Page, Runtime} = client;

  // Enable events on domains we are interested in.
  Promise.all([
    Page.enable()
  ]).then(() => {
    return Page.navigate({url: 'https://someDomain.com'});
  })
  Page.loadEventFired(() => {
    const expression = `({
            test: document.getElementsByClassName('rows')),
        })`
    Runtime.evaluate({expression,returnByValue: true}).then((result) => {
      console.log(result.result) // Error
      client.close()
    })
  })
}).on('error', (err) => {
  console.error('Cannot connect to browser:', err);
});

错误

{ type: 'object',
  subtype: 'error',
  className: 'SyntaxError',
  description: 'SyntaxError: Unexpected token )',
  objectId: '{"injectedScriptId":14,"id":1}' }

其实我想迭代元素列表,但我不知道哪里出了问题

最佳答案

您无法将 DOM 对象从浏览器上下文移动到 Node.js 上下文,您所能做的就是传递一个属性或任何可以被视为 JSON 对象的内容。在这里,我假设您对计算出的 HTML 感兴趣。

可能的解决方案是:

const CDP = require('chrome-remote-interface');

CDP((client) => {
    // Extract used DevTools domains.
    const {Page, Runtime} = client;

    // Enable events on domains we are interested in.
    Promise.all([
        Page.enable()
    ]).then(() => {
        return Page.navigate({url: 'http://example.com'});
    });

    // Evaluate outerHTML after page has loaded.
    Page.loadEventFired(() => {
        const expression = `({
            name: document.getElementById('name').outerHTML,
            price: document.getElementById('price').outerHTML
        })`;
        Runtime.evaluate({
            expression,
            returnByValue: true
        }).then(({result}) => {
            const {name, price} = result.value;
            console.log(`name: ${name}`);
            console.log(`price: ${price}`);
            client.close();
        });
    });
}).on('error', (err) => {
    console.error('Cannot connect to browser:', err);
});

关键点是使用returnByValue: true返回一个JSON对象。


更新:您的表达式中有错误,...('rows')), 中存在尾随 )。但即使你修复了它,你仍然会遇到错误的情况,因为你试图传递 DOM 对象数组(请参阅此答案的第一段)。同样,如果您只想要外部 HTML,您可以执行以下操作:

// Evaluate outerHTML after page has loaded.
Page.loadEventFired(() => {
    const expression = `
        // fetch an array-like of DOM elements
        var elements = document.getElementsByTagName('p');
        // create and return an array containing
        // just a property (in this case `outerHTML`)
        Array.prototype.map.call(elements, x => x.outerHTML);
    `;
    Runtime.evaluate({
        expression,
        returnByValue: true
    }).then(({result}) => {
        // this is the returned array
        const elements = result.value;
        elements.forEach((html) => {
             console.log(`- ${html}`);
        });
        client.close();
    });
});

关于javascript - 如何使用 chrome-remote-interface Node js 获取多个 DOM 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45500146/

相关文章:

javascript - jQuery 用户界面 : button to open link in new window

javascript - HTML 附加在 JSON 数据的末尾,我如何将它们分开?

javascript - 使用node.js和mysql进行简单的注册/登录

android - 从我的 android 应用程序向 chrome 发送/接收消息

node.js - 在 headless 模式下运行时是否可以远程跟踪 chromium 的 GUI?

javascript - JS : Click h1 to set display to none at another div

javascript - 如何在 jQuery Mobile 中更改选项卡时捕获事件

http - 尝试浏览器 ID 时出现 "node.js: throw e;//process.nextTick error,"

javascript - FlatBuffers 未定义

google-chrome - 如何使 Chrome 始终使用远程调试端口标志启动