问题 Selenium webdriver:查找具有相似id的所有元素


我有这个xpath: //*[@id="someId::button"]

按下它会显示值的下拉列表。

现在,我知道列表中的所有元素都有这样的id:

//*[@id="someId--popup::popupItemINDEX"]

,其中INDEX是从1到任意数量的数字。

我也知道必须点击的价值。

一个问题是:因为我将始终知道生成下拉列表的按钮的ID,我是否可以获取下拉列表中的所有元素 可重复使用 方法? (我需要与多个下拉列表进行交互)

我想的方式是: 获取初始ID的根,如:

//*[@id="someId 

然后添加其余的: --popup::popupItem。我还需要添加索引,我想我可以使用一个try块(为了得到例外情况,当我给出比预期更大的索引时),如下所示:

 for(int index=1;index<someBiggerThanExpectedNumber;index++){
     try{
         WebElement aux= driver.findElement(By.xpath(builtString+index+"\"]"));
         if(aux.getText().equals(myDesiredValue))
             aux.click();
     }catch(Exception e){}
 }

请注意,我使用的是webdriver api和java。

我想知道这是否有效,如果有更简单的方法,我可以得到最初的信息。


3492
2018-05-22 08:08


起源



答案:


根据经验,如果可能,尝试通过一个查询选择更多元素。逐个搜索许多元素将变得非常缓慢。

如果我很了解您的需求,那么这样做的好方法就是使用

driver.findElement(By.id("someId::button")).click();
driver.findElement(By.xpath("//*[contains(@id, 'someId--popup::popupItem') " +
    "and text()='" + myDesiredValue + "']"))
    .click();

有关XPath的更多信息,请参阅 规范。如果你可以跳过废话,这是一个非常好的阅读!

找到并单击一个文本等于您所需值的元素,其ID包含“someId - popup :: popupItem”。

List<WebElement> list = driver.findElements(By.xpath("//*[contains(@id, 'someId--popup::popupItem')]"));

它找到所有在其ID中包含“someId - popup :: popupItem”的元素。然后,您可以遍历列表并查找所需的元素。

你知道吗你可以打电话 findElement() 在...上 WebElement 只搜索它的孩子?   - driver.findElement(By.id("someId")).findElements(By.className("clickable"))

如果不深入了解底层HTML,我想我无法提供最好的方法,但我有一些想法。


12
2018-05-22 08:58



尝试查找所有元素都不起作用,因为列表是临时生成的,除了id部分之外,所有其他属性始终具有不同的值,即使值是相同的。我首先需要按下拉按钮才能访问/查看元素。感谢您寻找元素的孩子! - CosminO
我还是不能真正看到问题。单击下拉按钮,然后查找所有显示的元素? - Petr Janeček
//*[contains(@id, 'someId--popup::popupItem') and text()='myDesiredValue'] 选择一个ID包含“someId - popup :: popupItem”的元素,以及哪个文本值等于您想要的值。 ...当然,点击下拉按钮后。 - Petr Janeček
(另外,我编辑了答案,因为 ElementNotVisibleException 部分不是真的需要,我直到现在才意识到这一点) - Petr Janeček
如果我只使用text()部分,它可以找到该项目。所以这是迄今为止最简单的方法。此外,我已经设法以两种方式实现它(我最初想做的那个,这是凌乱的,并使用您的输入)。谢谢您的帮助!我必须接受你的答案,因为它提供了解决方案等等。 - CosminO


答案:


根据经验,如果可能,尝试通过一个查询选择更多元素。逐个搜索许多元素将变得非常缓慢。

如果我很了解您的需求,那么这样做的好方法就是使用

driver.findElement(By.id("someId::button")).click();
driver.findElement(By.xpath("//*[contains(@id, 'someId--popup::popupItem') " +
    "and text()='" + myDesiredValue + "']"))
    .click();

有关XPath的更多信息,请参阅 规范。如果你可以跳过废话,这是一个非常好的阅读!

找到并单击一个文本等于您所需值的元素,其ID包含“someId - popup :: popupItem”。

List<WebElement> list = driver.findElements(By.xpath("//*[contains(@id, 'someId--popup::popupItem')]"));

它找到所有在其ID中包含“someId - popup :: popupItem”的元素。然后,您可以遍历列表并查找所需的元素。

你知道吗你可以打电话 findElement() 在...上 WebElement 只搜索它的孩子?   - driver.findElement(By.id("someId")).findElements(By.className("clickable"))

如果不深入了解底层HTML,我想我无法提供最好的方法,但我有一些想法。


12
2018-05-22 08:58



尝试查找所有元素都不起作用,因为列表是临时生成的,除了id部分之外,所有其他属性始终具有不同的值,即使值是相同的。我首先需要按下拉按钮才能访问/查看元素。感谢您寻找元素的孩子! - CosminO
我还是不能真正看到问题。单击下拉按钮,然后查找所有显示的元素? - Petr Janeček
//*[contains(@id, 'someId--popup::popupItem') and text()='myDesiredValue'] 选择一个ID包含“someId - popup :: popupItem”的元素,以及哪个文本值等于您想要的值。 ...当然,点击下拉按钮后。 - Petr Janeček
(另外,我编辑了答案,因为 ElementNotVisibleException 部分不是真的需要,我直到现在才意识到这一点) - Petr Janeček
如果我只使用text()部分,它可以找到该项目。所以这是迄今为止最简单的方法。此外,我已经设法以两种方式实现它(我最初想做的那个,这是凌乱的,并使用您的输入)。谢谢您的帮助!我必须接受你的答案,因为它提供了解决方案等等。 - CosminO


你尝试过使用过吗? JavascriptExecutor

如果您愿意编写一些JavaScript,那么这将比在java中简单(我认为)

您需要做的就是通过DOM子树进行一些JavaScript爬行,并返回符合条件的DOM元素列表。然后,WebDriver会愉快地将其编组为 List<WebElement> 在java世界里。


3
2018-05-22 08:58



在这个时间点,该项目严重依赖于许多其他辅助类/方法。 - CosminO


这里使用的更安全的方法是

int size=driver.findElements(By.xpath("//*[@id='someId::button']")).size();

Start using Index Now

String builtString="//*[@id='someId::button'][";

for(int index=1;index<=size();index++)
{

try
{

   WebElement aux= driver.findElement(By.xpath(builtString+index+"\"]"));

   if(aux.getText().equals(myDesiredValue))
             aux.click();

}
catch(Exception e){}

}

请让我知道以上基本工作与否。


1



我不喜欢你理解这个问题。 - Andrew Barber