【问题标题】:What is the most efficient selector to use with findElement()?与 findElement() 一起使用的最有效选择器是什么?
【发布时间】:2017-04-21 10:49:07
【问题描述】:

在使用 Selenium 网络测试时,有几种方法可以识别 WebElement。

根据我的经验,我使用了以下选择器:

  • 类名 - By.className()
  • CSS 选择器 - By.cssSelector()
  • ID - By.id()
  • 链接文字 - By.linkText()
  • 姓名 - By.name()
  • 标签名称 - By.tagName()
  • XPath - By.xpath()

很明显,当只有一个选项可以用来定位一个元素时,我们必须使用那个,但是当可以使用多种方法时(例如:下面的div),应该如何确定使用哪种方法呢?是否存在比其他选择器更高效的选择器?是否有一些更耐用

<div class="class" id="id" name="name">Here's a div</div>

【问题讨论】:

标签: java selenium selenium-webdriver


【解决方案1】:

我会优先考虑这样的选择器:

  • ID - By.id()
  • 姓名 - By.name()
  • CSS 选择器 - By.cssSelector()
  • XPath - By.xpath()
  • 标签名称 - By.tagName()
  • 链接文字 - By.linkText()

但是,uniq ID 和名称并不总是存在。您还可以使用 CSS 选择器通过 ID #element_id 或名称 [name=element_name] 或 ClassName .element_class 进行定位,因此使用 CSS 选择器而不是 IDNameClassName 可能是个好主意。 Css 比 xPath 快,所以最好尽可能使用它。 xPath 适用于 CSS 选择器无法找到的困难元素定位器。我也不会使用标签名称和链接文本,因为您可以使用 xPath(对于链接文本 //a[text()='link_text'],标签名称 //div)或 CSS 选择器(对于标签名称 div)编写相同的内容。

【讨论】:

    【解决方案2】:

    只为s&gs...

    我对查找 div 的每个标识符方法进行了五次单独的计时,并对查找元素所用的时间进行了平均。

    WebDriver driver = new FirefoxDriver();
    driver.get("file://<Path>/div.html");
    long starttime = System.currentTimeMillis();
    //driver.findElement(By.className("class"));
    //driver.findElement(By.cssSelector("html body div"));
    //driver.findElement(By.id("id"));
    //driver.findElement(By.name("name"));
    //driver.findElement(By.tagName("div"));
    //driver.findElement(By.xpath("/html/body/div"));
    long stoptime = System.currentTimeMillis();
    System.out.println(stoptime-starttime + " milliseconds");
    driver.quit();
    

    它们在下面按平均运行时间排序..

    • CssSelector: (796ms + 430ms + 258ms + 408ms + 694ms) / 5 = ~517.2ms
    • 类名:(670ms + 453ms + 812ms + 415ms + 474ms) / 5 = ~564.8ms
    • 名称:(342ms + 901ms + 542ms + 847ms + 393ms) / 5 = ~605ms
    • ID:(888ms + 700ms + 431ms + 550ms + 501ms)/ 5 = ~614ms
    • Xpath:(835ms + 770ms + 415ms + 491ms + 852ms) / 5 = ~672.6ms
    • 标签名:(998ms + 832ms + 1278ms + 227ms + 648ms) / 5 = ~796.6ms

    阅读@JeffC 的回答后,我决定将By.cssSelector() 与类名、标记名和id 作为搜索词进行比较。同样,结果如下..

    WebDriver driver = new FirefoxDriver();
    driver.get("file://<Path>/div.html");
    long starttime = System.currentTimeMillis();
    //driver.findElement(By.cssSelector(".class"));
    //driver.findElement(By.className("class"));
    //driver.findElement(By.cssSelector("#id"));
    //driver.findElement(By.id("id"));
    //driver.findElement(By.cssSelector("div"));
    //driver.findElement(By.tagName("div"));
    long stoptime = System.currentTimeMillis();
    System.out.println(stoptime-starttime + " milliseconds");
    driver.quit();
    
    • By.cssSelector(".class"): (327ms + 165ms + 166ms + 282ms + 55ms) / 5 = ~199ms
    • By.className("class"): (338ms + 801ms + 529ms + 804ms + 281ms) / 5 = ~550ms
    • By.cssSelector("#id"): (58ms + 818ms + 261ms + 51ms + 72ms) / 5 = ~252ms
    • By.id("id") - (820ms + 543ms + 112ms + 434ms + 738ms) / 5 = ~529ms
    • By.cssSelector("div"): (594ms + 845ms + 455ms + 369ms + 173ms) / 5 = ~487ms
    • By.tagName("div"): (825ms + 843ms + 715ms + 629ms + 1008ms) / 5 = ~804ms

    由此看来,您应该尽可能地使用 css 选择器!

    【讨论】:

      【解决方案3】:

      根据我的经验,我按以下顺序使用这些定位器:

      1. 身份证
      2. 链接文本/部分链接文本
      3. CSS 选择器
      4. XPath

      其他:类名、标签名、名称等都可以使用 CSS 选择器找到。我很少需要一个单一的类名,所以我更喜欢 CSS 选择器,这样我可以使用多个类,但也可以指定一个标签名称,使其更具体,更不容易被破坏。标签名称很少使用...除非我们谈论的是 TABLE 或 TR 或 TD 标签,而这些都可以使用 CSS 选择器完成。我通常发现带有name 的标签也有id 所以我更喜欢id

      我最近发现,正如您在回答中所做的那样,CSS 选择器是最快的。这是有道理的,因为 Selenium 使用浏览器进行搜索,而且 CSS 选择器非常常见,以至于不同的浏览器都针对它们的使用进行了优化。

      linkText/partialLinkText 非常专业,所以我并没有真正计算它们。我尽可能使用它们,这很有意义。我曾考虑过只使用By.cssSelector("#someId"),但我不认为它真的有那么大的不同,而By.id() 在使用Id 时更明显。

      我很少使用 XPath,只有当我无法使用其他定位器完成它时,例如对于来自标签的文本或我无法使用 CSS 选择器完成的一些奇怪的子/后代事物。我发现(并阅读)XPath 支持因浏览器而异,而且速度较慢,因此除非绝对必要,否则我会避免使用它……而且我发现您可以使用 #1-3 定位 99% 的元素。

      id 应该是最持久的。 LinkText 和 partialLinkText 可能相当耐用,具体取决于页面。应用的类和与 CSS 选择器一起使用的 HTML 结构可能最有可能随着页面更新而改变。它实际上取决于更新的大小,是否更改了页面的部分部分。 CSS 选择器和 XPath 都会(通常)受到这些变化的影响。

      最后......只要您不为数百个元素抓取页面,一个页面转换可能比定位器方法之间几百毫秒的差异更重要。

      【讨论】:

        【解决方案4】:

        定位器应具有描述性、独特性且不太可能改变。所以我的优先级如下:

        1. ID - 您将获得所需的确切元素,它可以是描述性的,不会被错误地更改。
        2. - 非常具有描述性,在父元素的上下文中可能是独一无二的。
        3. CSS - 比 XPath 更好的性能 - 请参阅 Dave Haeffner 的 great benchmark
        4. XPath - 具有 CSS 不喜欢的功能 Axis 例如::parentcontains() 之类的函数。

        我会避免使用LinkTextTagName,因为它们往往会由于非常通用的过滤而导致意外失败。

        关于 CSS 和 XPath 的注意事项:也应该避免将它们与 //div/li[1]/*/span[2]div &gt; li:nth-child(1) 之类的东西一起使用,因为它们依赖于渲染并且容易发生变化。

        【讨论】:

        • 我认为 CSS 是并且可能永远会比 XPath 更快,但是这些基准测试确实非常陈旧并且可能不再有效。他正在针对 Chrome 32 进行测试,但当前版本是 54。我希望看到他的测试在当前浏览器上重新运行,看看有多少变化。
        • youtu.be/IjGDxXCaDnE?t=40m20s :) 顺便说一句,我知道在旧版本上,xpath 曾经更快,但不记得我在哪里听到的......
        • 这太好了,谢谢!我想我以前真的看过这个,但已经很久了。
        • 如果您查看您在 45:44 链接的视频,有一个图表显示 XPath 在 IE11 上实际上稍快。
        猜你喜欢
        • 1970-01-01
        • 2011-06-10
        • 2019-09-20
        • 2013-02-12
        • 1970-01-01
        • 2018-08-16
        • 1970-01-01
        • 2021-05-16
        • 1970-01-01
        相关资源
        最近更新 更多