Java 通过多个类名查找div元素?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21713280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 10:13:23  来源:igfitidea点击:

Find div element by multiple class names?

javacssseleniumselenium-webdriver

提问by membersound

<div class="value test" />I'd like to identify that web element. It only has this two classes defined. I cannot do the following as classNamedoes not take a space separated value. What are alternatives?

<div class="value test" />我想识别该网络元素。它只定义了这两个类。我不能执行以下操作,因为className不使用空格分隔值。什么是替代品?

@FindBy(className = "value test")
@CacheLookup
private WebElement test;

采纳答案by Yi Zeng

I don't think barak manos's answer has fully explained it.

我认为 barak manos 的回答没有完全解释它。

Imagine we have few elements as the followings:

想象一下,我们有以下几个元素:

  1. <div class="value test"></div>
  2. <div class="value test "></div>
  3. <div class="first value test last"></div>
  4. <div class="test value"></div>
  1. <div class="value test"></div>
  2. <div class="value test "></div>
  3. <div class="first value test last"></div>
  4. <div class="test value"></div>

How XPath matches

XPath 如何匹配

  • Match only 1 (exact match), barak's answer

    driver.findElement(By.xpath("//div[@class='value test']"));
    
  • Match 1, 2 and 3 (match class contains value test, class order matters)

    driver.findElement(By.xpath("//div[contains(@class, 'value test')]"));
    
  • Match 1, 2, 3 and 4 (as long as elements have class valueand test)

    driver.findElement(By.xpath("//div[contains(@class, 'value') and contains(@class, 'test')]"));
    
  • 仅匹配 1(完全匹配),巴拉克的回答

    driver.findElement(By.xpath("//div[@class='value test']"));
    
  • 匹配 1、2 和 3(匹配类包含value test,类顺序很重要)

    driver.findElement(By.xpath("//div[contains(@class, 'value test')]"));
    
  • 匹配 1、2、3 和 4(只要元素具有类valuetest

    driver.findElement(By.xpath("//div[contains(@class, 'value') and contains(@class, 'test')]"));
    

Also, in cases like this, Css Selector is always in favor of XPath (fast, concise, native).

此外,在这种情况下,Css Selector 总是支持 XPath(快速、简洁、原生)。

  • Match 1

    driver.findElement(By.cssSelector("div[class='value test']"));
    
  • Match 1, 2 and 3

    driver.findElement(By.cssSelector("div[class*='value test']"));
    
  • Match 1, 2, 3 and 4

    driver.findElement(By.cssSelector("div.value.test"));
    
  • 第一场

    driver.findElement(By.cssSelector("div[class='value test']"));
    
  • 匹配 1、2 和 3

    driver.findElement(By.cssSelector("div[class*='value test']"));
    
  • 匹配 1、2、3 和 4

    driver.findElement(By.cssSelector("div.value.test"));
    

回答by barak manos

Try this:

尝试这个:

test = driver.findElement(By.xpath("//div[@class='value test']"));

回答by DebanjanB

Class By.ByClassName

类 By.ByClassName

Class By.ByClassNameis defined in By.javaas follows:

By.ByClassName中定义By.java如下:

/**
 * Find elements based on the value of the "class" attribute. If an element has multiple classes, then
 * this will match against each of them. For example, if the value is "one two onone", then the
 * class names "one" and "two" will match.
 *
 * @param className The value of the "class" attribute to search for.
 * @return A By which locates elements by the value of the "class" attribute.
 */
public static By className(String className) {
  return new ByClassName(className);
}


This usecase

这个用例

So as per the defination you can't pass multiple classes i.e. valueand testas arguments to @FindBy(className = "..."). Sending multiple classes will raise an error as:

因此,根据定义,您不能将多个类 ievaluetest作为参数传递给@FindBy(className = "..."). 发送多个类将引发如下错误:

invalid selector: Compound class names not permitted


Solution

解决方案

There are multiple approaches to solve this usecase as follows:

有多种方法可以解决此用例,如下所示:

  • If the element is uniquely identified only through the classnamevalueyou can use:

    @FindBy(className = "value")
    @CacheLookup
    private WebElement test;
    
  • If the element is uniquely identified only through the classnametestyou can use:

    @FindBy(className = "test")
    @CacheLookup
    private WebElement test;
    
  • If both the classnames, valueand testare mandatory to identify the element, you can use css-selectorsas follows:

    @FindBy(css  = ".value.test")
    @CacheLookup
    private WebElement test;
    
  • As an alternative you can also use xpathas follows:

    @FindBy(xpath   = "//*[@class='value test']")
    @CacheLookup
    private WebElement test;
    
  • 如果元素仅通过 唯一标识,则classnamevalue可以使用:

    @FindBy(className = "value")
    @CacheLookup
    private WebElement test;
    
  • 如果元素仅通过 唯一标识,则classnametest可以使用:

    @FindBy(className = "test")
    @CacheLookup
    private WebElement test;
    
  • 如果classnames,valuetest都必须用于标识元素,则可以使用css-selectors如下:

    @FindBy(css  = ".value.test")
    @CacheLookup
    private WebElement test;
    
  • 作为替代方案,您还可以使用xpath,如下所示:

    @FindBy(xpath   = "//*[@class='value test']")
    @CacheLookup
    private WebElement test;
    


tl; dr

tl; 博士

Invalid selector: Compound class names not permitted error using Selenium

无效的选择器:使用 Selenium 时不允许复合类名错误