Selenium 简明教程

Selenium WebDriver - Finders

Selenium Webdriver 可用于找到具有相同匹配定位符值的元素。在网页上,如果多个元素具有相同定位符值,则只会获取到第一个匹配元素(从页面的右上角开始)的引用。

Selenium Webdriver can be used to locate elements having the same matching locator value. On a web page, if multiple elements are having the same locator value, only the reference to the first matching element (from the right upper corner of the page) is obtained.

findElement Method

findElement() 方法会返回在 DOM 中具有相同定位符值的第一个元素。如果有多个元素具有相同定位符值,则可以使用 id 定位符识别单个元素,因为它始终会在网页上唯一标识一个元素。

The findElement() method return the first element having the same locator value in the DOM. In case, there are multiple elements having the same locator values, we can identify a single element using the id locator since it always uniquely identifies an element on a web page.

Identify Element using the Nested findElement

让我们考虑一个 * HTML* 代码片段的示例,如下图中突出显示的那样,其中元素具有与 li 相同的标记名称。让我们识别具有子元素链接(标记名为“a”)的第一个 li 元素(具有标记名为 ul 的父元素),即 Text Box -

Let us take an example of an HTML code snippet as highlighted in the below image having the elements with the same tagname as li. Let us identify the first li element(with parent element with tagname ul) having a child element link(with tagname ‘a’) as Text Box

selenium finders 1

为了捕获该元素,我们首先唯一地识别了搜索元素的祖先元素(而不是不需要元素的祖先)元素,然后对该对象应用 findElement() 方法。

To get hold of that element, we first uniquely identified the element that is an ancestor to the searched element and not the ancestor of the undesired element, and then applied the findElement() method on that object.

我们可以借助 findElements() 方法获取具有相同定位符值的所有匹配元素。这会返回一个匹配元素列表。如果没有匹配元素,我们将会得到一个大小为 0 的列表。

We can get all the matching elements having the same locator values with the help of the findElements() method. This returns a list of matched elements. In case, there is no matching element, we would get a list with size 0.

嵌套命令的语法 -

Syntax with nested command −

WebDriver driver = new ChromeDriver();

// identify all elements under tagname ul
WebElement elements = driver.findElement(By.id("navMenus"));

// identify first li element under ul then click
WebElement element = elements.findElement(By.xpath("//li[1]/a"));

Example 1

让我们点击 Text Box 链接,并在网页上获取文本 Text Box

Let us click on the Text Box link, and get the text Text Box on the web page.

selenium finders 2

代码实现

Code Implementation

package org.example;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;

public class Finders {
   public static void main(String[] args) throws InterruptedException {

      // Initiate the Webdriver
      WebDriver driver = new ChromeDriver();

      // adding implicit wait of 15 secs
      driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);

      // Opening the webpage
      driver.get("https://www.tutorialspoint.com/selenium/practice/selenium_automation_practice.php");

      // identify element then click
      WebElement l = driver.findElement(By.xpath("//*[@id='headingOne']/button"));
      l.click();

      // identify all elements under tagname ul
      WebElement elements = driver.findElement(By.id("navMenus"));

      // identify first li element under ul then click
      WebElement element = elements.findElement(By.xpath("//li[1]/a"));
      element.click();

      WebElement e = driver.findElement(By.xpath("//*[@id='TextForm']/h1"));
      System.out.println("Text is: " + e.getText());

      // Closing browser
      driver.quit();
   }
}
Text is: Text Box

在上述示例中,我们首先使用嵌套定位符识别元素,然后获取文本并将其作为控制台消息: Text is: Text Box

In the above example, we had first identified the element with nested locators and then obtained the text with the message in the console: Text is: Text Box.

最后,收到了消息 Process finished with exit code 0 ,表示代码成功执行。

Finally, the message Process finished with exit code 0 was received, signifying successful execution of the code.

但是,我们可以使用一种经过优化的技术来使用 xpath 或 css 定位符识别该元素,因为嵌套方法在性能方面并不好。

However, we can use an optimized technique to identify that element using xpath or css locator, since the nested approach would not be good with respect to the performance.

Syntax

WebDriver driver = new ChromeDriver();

// identify element with xpath
WebElement element = driver.findElement(By.xpath("//*[@id='navMenus']/li[1]/a"));

Example 2

package org.example;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;

public class Finder {
   public static void main(String[] args) throws InterruptedException {

      // Initiate the Webdriver
      WebDriver driver = new ChromeDriver();

      // adding implicit wait of 15 secs
      driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);

      // Opening the webpage
      driver.get("https://www.tutorialspoint.com/selenium/practice/selenium_automation_practice.php");

      // identify element then click
      WebElement l = driver.findElement(By.xpath("//*[@id='headingOne']/button"));
      l.click();

      // identify element with xpath
      WebElement element = driver.findElement(By.xpath("//*[@id='navMenus']/li[1]/a"));
      element.click();

      WebElement e = driver.findElement(By.xpath("//*[@id='TextForm']/h1"));
      System.out.println("Text is: " + e.getText());

      // Closing browser
      driver.quit();
   }
}
Text is: Text Box

在上述示例中,我们首先使用 xpath 定位符识别元素,然后获取文本并将作为控制台消息: Text is: Text Box

In the above example, we had first identified the element with xpath locator and then obtained the text with the message in the console: Text is: Text Box.

链接通过一个名为 href 的属性以及一个锚点标记名称来识别。

The links are identified by the anchor tagname with an attribute called href.

现在,让我们讨论一下在下面图片所示的网页中识别链接 Bad Request 。首先,右键单击页面,然后单击 Chrome 浏览器的“检查”按钮。然后,整个页面的相应 HTML 代码将会显示出来。要检查页面上的某个链接,请单击位于 HTML 代码顶部的左上方箭头,如下图中突出显示的那样。

Let us now discuss the identification of link - Bad Request on a webpage shown in the below image. First, right click on the page, then click on the Inspect button in the Chrome browser. Then, the corresponding HTML code for the whole page would be visible. For inspecting a link on a page, click on the left upward arrow, available to the top of the HTML code as highlighted below.

selenium finders 3

一旦我们单击并将箭头指向错误请求超链接,其 HTML 代码就会显示出来,既反映出了锚点标记名称(称为“a”且包含在 <> 中),也反映出了属性 href。

Once, we had clicked and pointed the arrow to the Bad Request hyperlink, its HTML code was visible,reflecting both the anchor tagname(referred to as ‘a’ and enclosed in <>), and href the attribute.

selenium finders 4

让我们考虑上述页面的一个示例,我们首先会使用 findElements() 方法统计链接总数,然后会单击某个特定链接,比如 Bad Request 。在单击该链接后,我们将会得到消息 Link has responded with status 400 and status text Bad Request

Let us take an example of the above page, where we would first count the total number of links using the findElements() method, then we would click on a specific link, say the Bad Request. After clicking on that link, we would get the message Link has responded with status 400 and status text Bad Request.

selenium finders 5

Syntax

WebDriver driver = new ChromeDriver();
List<WebElement> totalLnks = driver.findElements(By.tagName("a") );

Example

package org.example;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

public class TotalLnks {
   public static void main(String[] args) throws InterruptedException {

      // Initiate the Webdriver
      WebDriver driver = new ChromeDriver() ;

      // adding implicit wait of 10 secs
      driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

      // Opening the webpage where we will count the links
      driver.get("https://www.tutorialspoint.com/selenium/practice/links.php" ) ;

      // Retrieve all links using locator By.tagName and storing in List
      List<WebElement> totalLnks = driver.findElements(By.tagName("a") );
      System.out.println( "Total number of links: " + totalLnks.size() ) ;

      // Running loop through list of web elements
      for( int j = 0; j < totalLnks.size(); j ++){
         if( totalLnks.get(j).getText().equalsIgnoreCase("Bad Request") ) {
            totalLnks.get(j).click() ;
            break ;
         }
      }

      // get text
      WebElement t = driver.findElement
         (By.xpath("/html/body/main/div/div/div[2]/div[4]"));
      System.out.println("Text is: " + t.getText());

      // Closing browser
      driver.quit();
   }
}
Total number of links: 42
Text is: Link has responded with status 400 and status text Bad Request

在上述示例中,我们统计了一个网页上的链接总数,并在控制台中收到了消息 - Total number of links: 42 ,然后在执行点击操作后收到了生成的文本 - Text is: Link has responded with status 400 and status text Bad Request

In the above example, we had counted the total number of links on a web page, and received the messages in the console - Total number of links: 42 and then obtained the text generated after performing the the click with the message - Text is: Link has responded with status 400 and status text Bad Request.

findElements Method with No Matching Element

让我们考虑一个示例并实现一段代码,在这种情况下,我们会看到 findElements() 方法返回的列表中可能包含 0 个元素(如果具有给定定位符值元素为 0 个的话)。

Let us take an example and implement a code where we would see that the list returned by the findElements() method may contain 0 element, if there is 0 element with the given locator value.

Example

package org.example;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class FindElement {
   public static void main(String[] args) throws InterruptedException {

      // Initiate the Webdriver
      WebDriver driver = new ChromeDriver();

      // adding implicit wait of 15 secs
      driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);

      // Opening the webpage where we will identify element
      driver.get("https://www.tutorialspoint.com/selenium/practice/links.php");

      // Retrieve all elements using By.class name ul and storing in List
      List<WebElement> total = driver.findElements(By.tagName("input"));
      System.out.println( "Total number of elements with tagname input: " + total.size() ) ;

      //Closing browser
      driver.quit();
   }
}
Total number of elements with tagname input: 0

在上述示例中,我们统计了所有标记名为 input 的元素,并且在控制台中收到了消息 - Total number of elements with tagname input: 0 (因为没有匹配的元素)。

In the above example, we counted all the elements having tagname as input received the messages in the console - Total number of elements with tagname input: 0(since there is no matching element).

findElement Method with No Matching Element

让我们考虑一个示例并实现一段代码,在这种情况下,如果具有给定定位符值元素为 0 个,则 findElement() 方法会返回 NoSuchElement 异常。

Let us take an example and implement a code where we would get a NoSuchElement exception, returned by the findElement() method, if there is 0 element with the given locator value.

Example

package org.example;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;

public class FindElementWithException {
   public static void main(String[] args) throws InterruptedException {

      // Initiate the Webdriver
      WebDriver driver = new ChromeDriver();

      // adding implicit wait of 15 secs
      driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);

      // Opening the webpage where we will identify element
      driver.get("https://www.tutorialspoint.com/selenium/practice/links.php");

      // Retrieve element using By.class name ul
      WebElement e = driver.findElement(By.className("ul"));
      System.out.println( "Element is : " + e);

      // Closing browser
      driver.quit();
   }
}
Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element:
   Unable to locate element: {"method":"css selector","selector":".ul"}
   (Session info: chrome=121.0.6167.160)
For documentation on this error, please visit:
https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception

Process finished with exit code 1

在上述示例中,我们收到了 Process finished with exit code 1 ,表示代码执行失败。此外,我们还得到了 NoSuchElementException(由于网页上没有任何与匹配定位符值相符的元素)。

In the above example, we had received Process finished with exit code 1 signifying unsuccessful execution of the code. Also, we had got the NoSuchElementException(as there is no element on the web page, having the matching locator value).

Difference between findElements and findElement Method

因此 findElement() 和 findElements() 的基本区别如下所示:

Thus the basic difference between the findElement() and findElements() are listed below −

  1. The findElement() method returns a web element, while the findElements() method returns the list of web elements.

  2. In case there is no matching element, the findElement() method will throw NoSuchElementException while the findElements() method will return a list with size 0.

activeElement Method

在网页上的所有元素中,我们可以使用 activeElement() 方法获取焦点所在的元素。

Of all the elements on the web page, we can get the element which is on focus using the activeElement() method.

让我们以以上页面为例,我们首先在输入框中使用 sendKeys() 方法输入文本 Selenium 。然后使用 Selenium activeElement() 方法获取焦点元素的属性值(在将驱动程序上下切换到焦点元素后)。

Let us take an example of the above page, where we would first enter the text Selenium in the input box with the help of the sendKeys() method. Then get the attribute of the element in focus using the activeElement() method(done after switching context of the driver to the element in focus).

selenium finders 6

Example

package org.example;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;

public class HandlingActivesElement {
   public static void main(String[] args) throws InterruptedException {

      // Initiate the Webdriver
      WebDriver driver = new ChromeDriver();

      // adding implicit wait of 15 secs
      driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);

      // launching URL
      driver.get("https://www.tutorialspoint.com/selenium/practice/text-box.php");

      // Identify the input box with xpath locator
      WebElement e = driver.findElement(By.xpath("//*[@id='fullname']"));

      // enter text in input box
      e.sendKeys("Selenium");

      // Get the value of element in focus after switching driver context
      String a = driver.switchTo().activeElement().getAttribute("value");
      System.out.println("Value entered: " + a);

      // Closing browser
      driver.quit();
   }
}
Value entered: Selenium

在上面的示例中,我们首先在输入框中输入文本 Value entered: Selenium ,并且还使用消息在控制台中检索了焦点中当前元素的值 - Chrome is being controlled by automated test software (即输入的值)。

In the above example, we had first entered the text Selenium in the input box, and also retrieved the value of the current element in focus in the console with the message - Value entered: Selenium(which is the value entered).

Conclusion

这就总结了我们对 Selenium Webdriver Finders 教程的全面讲解。我们从描述 findElement 方法开始,使用嵌套的 findElements 识别元素,使用 findElements 方法识别链接,没有匹配元素的 findElements 方法,没有匹配元素的 findElement 方法,findElements 和 findElement 方法之间的差异,activeElement 方法,以及示例来说明如何在 Selenium Webdriver 中使用查找器。这让你对 Selenium Webdriver Finders 有了深入的了解。明智的做法是继续练习你学到的知识,并探索与 Selenium 相关的内容,以加深你的理解并拓展你的视野。

This concludes our comprehensive take on the tutorial on Selenium Webdriver Finders. We’ve started with describing findElement method, identify element using the nested findElement, identify links using the findElements method, findElements method with no matching element, findElement method with no matching element, differences between findElements and findElement method, activeElement Method, and examples to illustrate how to use finders in Selenium Webdriver. This equips you with in-depth knowledge of the Selenium Webdriver Finders. It is wise to keep practicing what you’ve learned and exploring others relevant to Selenium to deepen your understanding and expand your horizons.