Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/425.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 按类名收集元素,然后单击每个元素-Puppeter_Javascript_Node.js_Google Chrome Devtools_Puppeteer_Headless Browser - Fatal编程技术网

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

Javascript 按类名收集元素,然后单击每个元素-Puppeter,javascript,node.js,google-chrome-devtools,puppeteer,headless-browser,Javascript,Node.js,Google Chrome Devtools,Puppeteer,Headless Browser,使用Puppeter,我希望获得页面上具有特定类名的所有元素,然后循环并单击每个元素 使用jQuery,我可以通过以下方式实现这一点: var elements = $("a.showGoals").toArray(); for (i = 0; i < elements.length; i++) { $(elements[i]).click(); } var elements=$(“a.showGoals”).toArray(); 对于(i=0;i{ 让元素=$('a.showGo

使用Puppeter,我希望获得页面上具有特定类名的所有元素,然后循环并单击每个元素

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

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

for (i = 0; i < elements.length; i++) {
  $(elements[i]).click();
}
var elements=$(“a.showGoals”).toArray();
对于(i=0;i
我如何使用木偶演员来实现这一点

更新 在下面尝试了Chridam的答案,但我无法让它发挥作用(尽管答案很有用,所以感谢你),所以我尝试了以下方法,效果很好:

 await page.evaluate(() => {
   let elements = $('a.showGoals').toArray();
   for (i = 0; i < elements.length; i++) {
     $(elements[i]).click();
   }
});
等待页面。评估(()=>{
让元素=$('a.showGoals').toArray();
对于(i=0;i
使用执行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();
});

要获取所有元素,应该使用方法,该方法与reqular browser API中的
[…document.querySelectorAll]
(在数组中展开)相同

然后,您可以循环浏览它(映射,例如,任何您喜欢的内容),并评估每个链接:

const getThemAll = await page.$$('a.showGoals')
getThemAll.forEach(async link => {
  await page.evaluate(() => link.click())
})
由于您还希望对所获得的内容执行操作,因此我建议使用which,它将执行与上面相同的操作,并在一行中使用数组中的每个元素运行求值函数。例如:

await page.$$eval('a.showGoals', links => links.forEach(link => link.click()))
为了更好地解释上面的行,
$$eval
返回一个链接数组,然后以
链接
作为参数执行回调函数,然后通过
forEach
方法运行每个链接,最后在每个链接中执行
单击
函数

也请检查,它们有很好的示例。

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

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

elements.forEach(async element => {
  await element.click();
});
注意:记住在函数中单击。否则,您将收到以下错误:

SyntaxError:await仅在异步函数中有效

迭代
for
循环与
Array.map()/Array.forEach()中的puppeter异步方法
由于所有puppeter方法都是异步的,因此我们如何迭代它们并不重要。我对最常用的推荐和使用选项进行了比较和评级

为此,我创建了一个React.Js示例页面,其中包含许多React按钮(我称之为lotofreact按钮)。这里(1)我们可以设置页面上要呈现的按钮数量(2)我们可以通过单击黑色按钮将其激活为绿色。我认为这是一个与OP相同的用例,也是浏览器自动化的一个普遍情况(如果我们在页面上做了一些事情,我们预期会发生一些事情)。 假设我们的用例是:

Scenario outline: click all the buttons with the same selector
  Given I have <no.> black buttons on the page
  When I click on all of them
  Then I should have <no.> green buttons on the page
特产
  • 返回另一个数组
  • .map方法内部的并行执行
  • 快速
132按钮场景结果:❌ 持续时间:891毫秒

通过在人头攒动模式下观察浏览器,它看起来可以工作,但是如果我们检查
页面。屏幕截图发生的时间:我们可以看到点击仍在进行中。这是因为默认情况下不能等待
数组.map
。幸运的是,在浏览器未关闭之前,脚本有足够的时间解决所有元素上的所有单击

1320个按钮场景结果:❌ 持续时间:6868毫秒

如果我们增加同一选择器的元素数,我们将遇到以下错误:
未处理PromisejectionWarning:错误:节点不可见或不是HTMLElement
,因为我们已经到达了
等待页面。屏幕截图()
等待浏览器。关闭()
:当浏览器已经关闭时,异步单击仍在进行中


二,。数组.forEach 所有的迭代对象都将被执行,但是forEach将在它们全部完成执行之前返回,这在异步函数的许多情况下都不是理想的行为。就木偶演员而言,这与
Array.map
非常相似,除了:for
Array.forEach
不返回新数组

代码示例
const elHandleArray=等待页面。$$(“按钮”)
elHandleArray.forEach(异步el=>{
等待元素。单击()
})
等待页面。屏幕截图({path:'clicks_foreach.png'})
等待浏览器关闭()
特产
  • .forEach方法内部的并行执行
  • 快速
132按钮场景结果:❌ 持续时间:1058毫秒

通过在人头攒动模式下观察浏览器,它看起来可以工作,但是如果我们检查
页面。屏幕截图发生的时间:我们可以看到点击仍在进行中

1320个按钮场景结果:❌ 持续时间:5111毫秒

如果使用相同的选择器增加元素的数量,我们将遇到以下错误:
未处理PromisejectionWarning:错误:节点不可见或不是HTMLElement
,因为我们已经到达了
等待页面。屏幕截图()
等待浏览器。关闭()
:当浏览器已经关闭时,异步单击仍在进行中


三、 第页$$eval+forEach 性能最好的解决方案是稍微修改一下bside的版本。页面。$$eval()在页面内运行
Array.from(document.querySelectorAll(selector))
,并将其作为第一个参数传递给
pageFunction
。它作为forEach的包装器,因此可以完美地等待它

代码示例
wait page.$$eval('button',elHandles=>elHandles.forEach(el=>el.click())
等待页面。屏幕截图({path:'clicks_eval_foreach.png'})
等待浏览器关闭()
特产
  • 在.forEach方法中使用异步puppeter方法没有副作用
  • .forEach方法内部的并行执行
  • 极快
132按钮场景结果:✅ 持续时间:711毫秒

通过在人头模式下观察浏览器,我们可以看到效果是立竿见影的,