无法使用 Selenium 中的 CSS 选择器选择同级

Posted

技术标签:

【中文标题】无法使用 Selenium 中的 CSS 选择器选择同级【英文标题】:Could not select sibling using CSS Selector in Selenium 【发布时间】:2020-06-25 22:42:11 【问题描述】:

Selenium WebDriver 在尝试使用 CSS 选择器单击下一个同级元素时抛出 InvalidSelectorException。

考虑我的 DOM 看起来像这样:

<div class="checkbox-group">
   <div>     
       <span class="checkbox">::after</span> <!--click on this span makes the checkbox checked-->
       <span class="checkbox-name">Male</span> <!--click on this span doesn't make the checkbox checked-->
   </div>
   <div>
      <span class="checkbox">::after</span>
      <span class="checkbox-name">Female</span>
   </div>
</div>

而我的 Java 代码是:

@FindAll(@FindBy(css=".checkbox-name"))
List<WebElement> checkboxes;

public void selectCheckbox(String value)
    for(WebElement checkbox : checkboxes)
        String text = checkbox.getText();
        if(text.equalsIgnoreCase(value))
            WebElement control = checkbox.findElement(By.cssSelector("+.checkbox"));//Exception thrown here     
            control.click();
        
    

异常抛出:

org.openqa.selenium.InvalidSelectorException: invalid selector: An invalid or illegal selector was specified. 
** Element info: Using=css selector, value=+.checkbox 

【问题讨论】:

抱歉,错字。我已经更新了错误堆栈跟踪。我的问题仍然有效,请您现在看一下。 【参考方案1】:

您可以使用 xpath 中的 text 直接获取该元素,而不是按类 checkbox-name 获取元素并检查它是否包含 String value。 找到该元素后,您可以在 xpath 中使用following-sibling 来访问可点击的span

您只能在一个 xpath 中完成所有这些操作,例如:

public void selectCheckbox(String value)
    WebElement checkBox = driver.findElement(By.xpath("//div[@class='checkbox-group']//span[text()="+value+"]//following-sibling::span"));
    checkBox.click();

【讨论】:

是的,我很清楚following-sibling xpath。但是我的测试是黄瓜测试,其中复选框的名称可能与应用程序中的名称不完全相同。我比较文本,不考虑空格,不区分大小写,忽略特殊字符,然后单击名称匹配。实际上,我的 DOM 在“name”元素之前包含“::after”元素,这阻止了我使用 follow-sibling。【参考方案2】:

在其他人指出这个问题可以使用 xpath 轻松解决之前,让我告诉你我已经有了这个解决方案。但是这个问题的目的是找出为什么即使我的 CSS 选择器正确,selenium 也不起作用。

Xpath 解决方案:

public void selectCheckbox(String value)
    for(WebElement checkbox : checkboxes)
        String text = checkbox.getText();
        if(text.equalsIgnoreCase(value))
            WebElement control = checkbox.findElement(By.xpath("./parent::div/span[@class='checkbox']"));
            control.click();
        
    

【讨论】:

以上是关于无法使用 Selenium 中的 CSS 选择器选择同级的主要内容,如果未能解决你的问题,请参考以下文章

为什么BeautifulSoup无法解析页面的所有元素? (答案:BeautifulSoup中的CSS选择器)

Selenium-python 中的 css 选择器中的括号 [?] 的问题

selenium之css定位小结

使用 Selenium 提取元素的 CSS 选择器

Selenium 中特定类表的 CSS 选择器

在使用 Selenium 的某些元素之后通过 CSS 选择器查找元素