木偶:如何获取节点列表中每个元素的内容?

时间:2018-10-16 02:30:14

标签: javascript node.js google-chrome-devtools puppeteer headless-browser

我正在尝试实现一些非常琐碎的事情:获取元素列表,然后对每个元素的innerText进行操作。

const tweets = await page.$$('.tweet');

据我所知,这将返回一个节点列表,就像浏览器中的document.querySelectorAll()方法一样。

我如何遍历它并得到我所需要的?我尝试了各种东西,例如:

[...tweets].forEach(tweet => {
  console.log(tweet.innerText)
});

2 个答案:

答案 0 :(得分:6)

页面。$$():

您可以结合使用elementHandle.getProperty()jsHandle.jsonValue()从通过innerText获得的ElementHandle中获得page.$$()

const tweets = await page.$$('.tweet');

for (let i = 0; i < tweets.length; i++) {
  const tweet = await (await tweets[i].getProperty('innerText')).jsonValue();
  console.log(tweet);
}

如果您使用forEach()方法进行设置,则可以将循环包装在promise中:

const tweets = await page.$$('.tweet');

await new Promise((resolve, reject) => {
  tweets.forEach(async (tweet, i) => {
    tweet = await (await tweet.getProperty('innerText')).jsonValue();
    console.log(tweet);
    if (i === tweets.length - 1) {
      resolve();
    }
  });
});

page.evaluate():

或者,您可以完全跳过使用page.$$(),而使用page.evaluate()

const tweets = await page.evaluate(() => Array.from(document.getElementsByClassName('tweet'), e => e.innerText));

tweets.forEach(tweet => {
  console.log(tweet);
});

答案 1 :(得分:5)

根据伪造文档hereimport webbrowser market=input("market") ticker=input("Ticket") webbrowser.open(f'https://www.tradingview.com/symbols/{market}-{ticker}/technicals') 不返回节点列表,而是返回ElementHandle的数组承诺。与NodeList完全不同。

有几种方法可以解决此问题。

1。将内置函数用于称为$$

的循环

此方法在页面中运行page.$$eval,并将其作为第一个参数传递给Array.from(document.querySelectorAll(selector))

所以要获取innerText就像下面的

pageFunction

2。将// Find all .tweet, and return innerText for each element, in a array. const tweets = await page.$$eval('.tweet', element => element.innerText); 传递到elementHandle

page.evaluate得到的任何东西都是elementHandle的数组。如果您进行控制台操作,则根据类型将显示await page.$$('.tweet')JShandle

忘了艰难的解释,它更容易演示。

ElementHandle

当然,有多种方法可以解决此问题,格兰特·米勒(Grant Miller)在其他答案中也回答了其中的几种。