繁体   English   中英

单击列表中找到的所有元素<WebElement>

[英]Clicking all elements found in List<WebElement>

我正在尝试单击动态表行中锚标记内的 i 标记中的 class 属性找到的元素的所有实例。 具体来说,它是包含多个单元格的一行,在最后一个单元格中有一系列 4 个链接,带有 X 或 O。如果正方形是 X,则可以单击它,并在短暂等待后变为 O。链接写成如下:

<a class="foobar"><i class="dontNeedToClick"><i></a>
<a class="foobar"><i class="dontNeedToClick"><i></a>
<a class="foobar"><i class="needToClick"><i></a>
<a class="foobar"><i class="dontNeedToClick"><i></a>

当needToClick 元素被单击时,该类将更改为dontNeedToClick 元素。在包含数千个O 的数据库中,只有不到一百个X 可供滚动,因此自动单击它们会节省大量时间。 我可以成功计算元素出现在表中的实例,但是当我使用 .findElements() 将元素放入 List 对象并尝试遍历它时,我得到 ElementNotVisibleException。

到目前为止,这是我的示例代码:

// get the count of thumbs down accounts
    int elementsCount= driver.findElements(By.className("needToClick")).size();
    System.out.println("Amount of elements: " + elementsCount);

// loop and click through all elements found

    for (int x = 0; x < elementCount; x++) {
        List<WebElement> elements = driver.findElements(By.className("needToClick"));
        WebElement client = elements.get(x);
        client.click();
        Thread.sleep(5000);
    }

我试过使用 Iterator 并得到同样的异常。

        Iterator<WebElement> clickElement = elements.iterator();
        while (clickElement.hasNext()) {
            clickElement.next().click();
        }

我也尝试过使用 foreach 循环。

    List<WebElement> thumbsDown = driver.findElements(By.className(expectedClass));

    for(WebElement element : thumbsDown) {
        element.click();
    }

我会使用 xpath,但我对动态表的经验不是很丰富,并且无法找到一种方法来获取包含我正在寻找的元素的行以及与它相关的其他元素,并且想出了一种不太优雅的方法,例如因为只需通过类名查找所有元素就足够了。 将不胜感激任何帮助。

确保您尝试单击的元素可见。 如果您不关心可见性,请使用 javascipt 单击:

JavascriptExecutor js = (JavascriptExecutor) driver;
WebDriverWait wait = new WebDriverWait(driver, 5);

List<WebElement> elements = driver.findElements(By.className("needToClick"));
elements.forEach(e -> {
    js.executeScript("arguments[0].click();", e);
    wait.until(ExpectedConditions.attributeToBe(e,"class", "dontNeedToClick"));
    //if element have not only dontNeedToClick class use attributeContains
    //wait.until(ExpectedConditions.attributeContains(e,"class", "dontNeedToClick"));
});

检查您是否可以单击一个元素并更改类:

driver.findElement(By.className("needToClick")).click();

如果不尝试 xpath:

driver.findElement(By.xpath("//a[i[@class='needToClick']]"));
//or
driver.findElement(By.xpath("//a[i[contains(@class,'needToClick')]]"));

是否在遍历列表或尝试生成列表时抛出异常?

如果是前者,您需要做的是在每次点击后重新生成列表 - 即使您加载了一个完全相同的新页面,硒也会将新页面上的元素视为“不同”而您不会能够使用您在旧页面上找到的任何元素。 (编辑:我再次查看了你的循环,看起来你做的这部分是对的。我猜你需要等待页面完全加载)

如果是后者,那么您可能需要等待页面加载,并确保您尝试查找的元素都存在。 在 selenium 中,您可以设置显式或隐式超时,但我个人更喜欢time.sleep(however many seconds)因为 selenium 可能会“说”它在完全加载所有 javascript 之前已加载。

希望这可以帮助!

我认为您必须使用 xpath,因为我在<i>标签中看到了您的元素

像这样

//a[@class='foobar']//i[contains(@class,'Click')]

代码

 List<WebElement> elements = driver.findElements(By.xpath("//a[@class='foobar']//i[contains(@class,'Click')]"));
 for (WebElement tempEle : elements) {
  tempEle.click();
}

您还可以在 For each 循环中使用if with break来查找特定元素

如果要选择列表列表的每个元素,只需使用 foreach 循环:

for(WebElement e : List<WebElement>){
   e.doThings();
}
   int elementsCount= driver.findElements(By.className("needToClick")).size();
System.out.println("Amount of elements: " + elementsCount);

    List<WebElement> elements = driver.findElements(By.className("needToClick"));

for (int x = 0; x < elementCount; x++) {
    WebElement client = elements.get(x);
    Thread.sleep(5000);

客户端点击(); }

列表元素 = driver.findElements(By.className("needToClick")); element.get(0).click(); 它将适用于网络列表元素上的点击事件

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM