【问题标题】:how to find child (not all descendants) elements via an existing element (not xpath)如何通过现有元素(不是xpath)查找子(​​不是所有后代)元素
【发布时间】:2013-08-06 15:45:56
【问题描述】:

我正在尝试查找已找到元素的子元素。我遇到的问题是我似乎只能获取现有元素的所有后代。

例如,给定以下 HTML sn-p(您可能会将其识别为引导下拉菜单)。

<div class="dropdown">
  <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu">
    <li>
      <a tabindex="-1" href="#">Action</a>
    </li>
    <li>
      <a tabindex="-1" href="#">Another action</a>
    </li>
    <li>
      <a tabindex="-1" href="#">Something else here</a>
    </li>
    <li class="divider"></li>
    <li class="dropdown-submenu">
      <a tabindex="-1" href="#">More options</a>
      <ul class="dropdown-menu">
        <li><a tabindex="-1" href="#">Second level link</a></li>
        <li><a tabindex="-1" href="#">Second level link</a></li>
        <li><a tabindex="-1" href="#">Second level link</a></li>
        <li><a tabindex="-1" href="#">Second level link</a></li>
        <li><a tabindex="-1" href="#">Second level link</a></li>
      </ul>
    </li>
  </ul>
</div>

我已经将现有的 WebElement 添加到下拉菜单中

WebElement dropdown = driver.findElementBy(By.cssSelector(".dropdown > .dropdown-menu");

我正在尝试获取最外层菜单的所有子 li 的句柄。最初我是在做以下事情

List<WebElement> menuItems = dropdown.findElements(By.cssSelector(" > li > a");

假设它会导致构建最终选择器

.dropdown > .dropdown-menu > li > a

但是,这会引发异常

Caused by: org.openqa.selenium.remote.ErrorHandler$UnknownServerException: An invalid or illegal string was specified

执行以下操作不会引发异常,但会返回所有后代……而不仅仅是孩子。 menuItems 的数量是 10 而不是 5。

List<WebElement> menuItems = dropdown.findElements(By.cssSelector("li > a");

所以我想我的终极问题是有没有办法使用 By.cssSelector 来获取已经找到的节点的直接子节点?

XPATH 不是一个允许的解决方案。

【问题讨论】:

  • 我不知道这是否可行...试试dropdown.findElements(By.cssSelector(".dropdown &gt; li &gt;a"))
  • @MrTi ...我明天试试。也许 findElements 将自己包含在搜索的上下文中。
  • 如果您在 Chrome 的开发者控制台中运行 $$(".dropdown &gt; .dropdown-menu &gt; li &gt; a") 会发生什么?它会为你运行 CSS 选择器并返回它找到的元素。
  • 为什么 xpath 不是一个允许的解决方案?
  • @Arran ... 在浏览器中使用该选择器就可以了。

标签: java css selenium webdriver selenium-webdriver


【解决方案1】:

稍微改变一下逻辑怎么样?

您有一个名为 dropdownWebElement,但它在 DOM 中定义为类 dropdown-menu。为什么不将dropdown 定义为div.dropdown 而不是ul.dropdown-menu?那么你的问题就可以解决了。

WebElement dropdown = driver.findElement(By.cssSelector(".dropdown");
List<WebElement> menuItems = dropdown.findElements(By.cssSelector(".dropdown-menu[role='menu'] > li > a");
List<WebElement> subMenuItems = dropdown.findElements(By.cssSelector(".dropdown-submenu li > a");

【讨论】:

  • 我想过类似的事情......例如用它们所在的级别标记菜单,但我在想我正在尝试做的事情应该完全可以使用 webdriver (我的意思是获取已找到元素的直接子级)。
  • @loesak:实际上这听起来像是 Selenium 错误,或者由于设计原因无法实现。可能想检查源代码并查看底层方法。
  • 到目前为止,这是让我解决这个问题的最佳答案,但它并没有完全解决根本问题。为此,我已向 selenium (code.google.com/p/selenium/issues/detail?id=6050) 提交了一个错误。
【解决方案2】:

为什么不把它们结合起来呢?

List<WebElement> menuItems = driver.findElements(By.cssSelector(".dropdown > .dropdown-menu  > li > a");

【讨论】:

  • 也许我忘了提,但元素的抓取属于不同的类。下拉菜单 WebElement 被传递。当我需要下拉项目时,我对如何找到下拉菜单一无所知。
猜你喜欢
  • 2015-11-10
  • 1970-01-01
  • 2014-03-21
  • 2020-05-03
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 2020-11-05
  • 1970-01-01
相关资源
最近更新 更多