Javascript 按类名收集元素,然后单击每个元素 - Puppeteer

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48673906/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:12:18  来源:igfitidea点击:

Collect elements by class name and then click each one - Puppeteer

javascriptnode.jsgoogle-chrome-devtoolspuppeteerheadless-browser

提问by Richlewis

Using Puppeteer, I would like to get all the elements on a page with a particular class name and then loop through and click each one.

使用 Puppeteer,我想获取页面上具有特定类名的所有元素,然后循环并单击每个元素。

Using jQuery, I can achieve this with:

使用 jQuery,我可以通过以下方式实现:

var elements = $("a.showGoals").toArray();

for (i = 0; i < elements.length; i++) {
  $(elements[i]).click();
}

How would I achieve this using Puppeteer?

我将如何使用 Puppeteer 实现这一目标?

Update

更新

Tried out Chridam's answer below, but I couldn't get it to work (though the answer was helpful, so thanks due there), so I tried the following and this works:

在下面尝试了 Chridam 的答案,但我无法让它发挥作用(尽管答案很有帮助,所以感谢那里),所以我尝试了以下方法并且有效:

 await page.evaluate(() => {
   let elements = $('a.showGoals').toArray();
   for (i = 0; i < elements.length; i++) {
     $(elements[i]).click();
   }
});

回答by chridam

Use page.evaluateto execute JS:

使用page.evaluate执行JS:

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
    const page = await browser.newPage();
    await page.evaluate(() => {
        let elements = document.getElementsByClassName('showGoals');
        for (let element of elements)
            element.click();
    });
    // browser.close();
});

回答by bsides

To get all elements, you should use page.$$method, which is the same as [...document.querySelectorAll](spread inside an array) from reqular browser API.

要获取所有元素,您应该使用page.$$方法,该方法[...document.querySelectorAll]与 reqular 浏览器 API 中的(在数组内传播)相同。

Then you could loop through it (map, for, whatever you like) and evaluate each link:

然后你可以循环遍历它(map,for,任何你喜欢的)并评估每个链接:

const getThemAll = await page.$$('a.showGoals')
getThemAll.map(link => {
  await page.evaluate(() => link.click())
})

Since you also want to do actions with the things you got, I'd recommend using page.$$evalwhich will do the same as above and run an evaluation function afterwards with each of the elements in the array in one line. For example:

由于您还想对您得到的东西执行操作,我建议使用page.$$evalwhich 将执行与上述相同的操作,然后在一行中对数组中的每个元素运行评估函数。例如:

const clickThemAll = await page.$$eval('a.showGoals', links => links.map(link => link.click())

To explain the line above better, $$evalreturns an array of links, then it executes a function with the links as an argument then it runs through every link via map method.

为了更好地解释上面的行,$$eval返回一个链接数组,然后它以链接为参数执行一个函数,然后通过 map 方法遍历每个链接。

Check the official documentationtoo, they have good examples there.

也请查看官方文档,那里有很好的示例。

回答by Grant Miller

page.$$() / elementHandle.click()

page.$$() / elementHandle.click()

You can use page.$$()to create an ElementHandlearray based on the given selector, and then you can use elementHandle.click()to click each element:

您可以使用基于给定选择器page.$$()创建ElementHandle数组,然后您可以使用elementHandle.click()单击每个元素:

const elements = await page.$$('a.showGoals');

elements.forEach(async element => {
  await element.click();
});

Note:Remember to awaitthe click in an asyncfunction. Otherwise, you will receive the following error:

SyntaxError: await is only valid in async function

注意:请记住awaitasync函数中单击。否则,您将收到以下错误:

语法错误:await 仅在异步函数中有效