单击在列表<webelement>

时间:2018-08-20 00:47:59

标签: java selenium selenium-webdriver

我试图单击在动态表行的定位标记中的i标记中的class属性中找到的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少于100个,因此自动单击它们可以节省大量时间。我可以成功计算元素出现在表中的实例,但是当我使用.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,但是我对动态表没有很丰富的经验,并且无法找到一种方法来获取包含我要查找的元素和与之相关的其他元素的行,并得出一个小于仅用类名查找所有元素的优雅方法就足够了。不胜感激。

6 个答案:

答案 0 :(得分:1)

确保尝试单击的元素可见。如果您不关心可见性,请单击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')]]"));

答案 1 :(得分:0)

在遍历列表时或尝试生成列表时会引发异常吗?

如果是前者,您需要做的是在每次单击后重新生成列表-即使您加载的页面完全相同,硒也会在新页面上将元素视为“不同”,并且将无法使用您在旧页面上找到的任何元素。 (编辑:我再次浏览了您的循环,看来您在做这部分工作是正确的。我想您需要等待页面完全加载)

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

希望这会有所帮助!

答案 2 :(得分:0)

我认为您必须使用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循环中将ifbreak结合使用来填充特定元素

答案 3 :(得分:0)

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

for(WebElement e : List<WebElement>){
   e.doThings();
}

答案 4 :(得分:0)

   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);

client.click();     }

答案 5 :(得分:-1)

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