# 9N WebDriver – 定位元素:第 4a 部分(通過 xpath)
> 原文: [https://javabeginnerstutorial.com/selenium/9n-webdriver-locating-elements-4a/](https://javabeginnerstutorial.com/selenium/9n-webdriver-locating-elements-4a/)
歡迎回來,我們今天將討論 XPath 策略。 這也是一種先進且有效的定位策略(`cssSelectors`也是!)。 雖然有效,但有時可能會造成混淆。 因此,讓我們深入研究如何理解我們經常被誤解的朋友,并一勞永逸地提出好的代碼。
當所有希望都喪失了時,拯救自己的唯一機會就是轉向 XPath 策略。 因為在大多數情況下,我們將測試現有的東西并且無法修改。 我們并不總是能夠控制頁面以添加一些 ID,從而使自動化成為一項更簡單的任務。 因此,請停止咆哮并認真對待!
*準備開始*
**XPath** (XML 路徑語言):根據 [w3schools](https://www.w3schools.com/xml/xpath_intro.asp) 的說法,XPath 是一種“路徑式”語言,用于標識和瀏覽 XML 文檔中的各種元素和屬性。
因此,XPath 提供了用于定位 HTML 文檔中任何元素的語法。
**注意:**
*如果到目前為止,您從未接觸過 XPath,請在繼續進行操作之前先了解 XPath 術語。 特別是,節點和這些節點之間的關系即父級,子級,同級,祖先,后代。*
如果您已經知道這些術語,并且希望略微刷一下,請參考下圖。 禮貌: [w3schools](https://www.w3schools.com/xml/dom_intro.asp)

現在是當今的主要任務**:通過 XPath 策略定位元素!** 在這篇文章中,我們將研究以下技術,
1. 捷徑
2. 絕對 XPath 和相對 XPath
3. 使用標簽和屬性
4. 使用兩個條件
5. 使用`contains()`
6. 查找多個元素
讓我們從最簡單的動機開始。
### 1.捷徑:
是否想以簡單的方式在網頁上找到任何元素的 XPath? 做完了。是否希望幾乎每次都處于完美的工作狀態? 也做完了。 馬上完成所有這些操作呢? 它讓您涵蓋了搖滾明星! 您只需要“Firebug”! 它可以作為 Firefox 瀏覽器的附加組件使用。
食譜來了:
1. 點擊 Firebug 圖標或按“`F12`”。
2. 檢查其 XPath 是必需的元素。
3. 相應的代碼將在 Firebug 面板的“HTML”部分中突出顯示。
4. 右鍵點擊突出顯示的代碼,然后選擇“復制 XPath”
5. 瞧! 您已將準備好的烘焙 XPath 復制到剪貼板!
瞥見我們剛才所說的話,

如果您希望獲得有關 Firebug 的詳細信息,[請在處查看](https://javabeginnerstutorial.com/selenium/7n-ide-using-firebug/)。
### 2.現在對于**長短**:
為了從頭提出 XPath,我們首先需要了解可用的兩種 Xpath。 它們是絕對 XPath 和相對 XPath。
| **絕對 XPath** | **相對 XPath** |
| --- | --- |
| 它以單個正斜杠(`/`)開頭。 | 它以雙正斜杠(`//`)開頭。 |
| `/`指示 XPath 引擎參考根節點搜索元素。 | `//`指示 XPath 引擎在 DOM 結構中的任何位置搜索匹配的元素。 |
| 與相對的 XPath 相比,元素標識更快。 | 由于僅指定了部分路徑,因此需要花費更多時間來標識元素。 |
| 即使對 HTML DOM 結構進行了最細微的更改(例如添加標簽或刪除標簽),絕對 XPath 也會失敗。 | 相對 XPath 較短,更改的可能性較小,從而使其更可靠。 |
| 例如,`/html/head/body/div[2]/form/input` | 例如`//input[@name="username"]` |
有了這些基本知識,就讓我們開始吧!
### 3.使用標簽和屬性:
可以使用其 HTML 標簽,其屬性(例如 ID,名稱,類,標題,值,`href`,`src`等)及其相應的值來定位特定的 Web 元素。
**語法**:`driver.findElement(By.xpath("//tag_name[@attribute='value']"));`
**解釋**:標識 XPath 指向的元素。 “`//`”標識指定的節點,“`@`”符號用于選擇與給定值匹配的指定屬性。
**示例**:讓我們在 Gmail 帳戶注冊頁面上找到名字文本框。
右鍵點擊“名字”文本框,然后選擇檢查元素,以獲取相應的 HTML 代碼,如下所示,
```java
<input value="" name="FirstName" id="FirstName" spellcheck="false"
class="form-error" aria-invalid="true" type="text">
```
我們可以看到“`input`”標簽具有一個“`name`”屬性,其值為“`FirstName`”。
*代碼:*(可以使用以下任一選項)
```java
driver.findElement(By.xpath("//input[@name='FirstName']"));
driver.findElement(By.xpath("//input[@id='FirstName']"));
driver.findElement(By.xpath("//input[@class='form-error']"));
```
如果您希望使用絕對路徑,
```java
driver.findElement(By.xpath("/html/body/div[1]/div[2]/div/div[1]/div/form/div[1]/fieldset/label[1]/input"));
```
表單標簽有許多子`div`標簽。 在我們的情況下,我們希望選擇第一個`div`標簽。 可以將其指定為“`div[1]`”。 這些方括號`[]`中的數字表示要選擇的確切同級。
### 4.使用兩個條件
如果多個標簽具有相同的屬性值怎么辦? 或者,如果您希望僅在元素與指定條件都匹配時才定位它,該怎么辦?
**語法**:`driver.findElement(By.xpath("//tag_name[@attribute1='value1'][@attribute2='value2']"))`
**說明**:標識具有指定`tag_name`的元素,這些元素的屬性與給定值匹配。
**示例**:讓我們在 Gmail 帳戶注冊頁面上找到“確認密碼”文本框。
右鍵點擊“創建密碼”和“確認密碼”文本框,然后選擇檢查元素以獲取相應的 HTML 代碼,如下所示,
```java
<input name="Passwd" id="Passwd" type="password">
<input name="PasswdAgain" id="PasswdAgain" type="password">
```
請注意,兩個文本框的“`class`”屬性值均相同,但“`id`”和“`name`”的值均不同。 因此,為了找到“確認密碼”文本框,讓我們同時提及其“`class`”和“`id`”值。
*代碼:*
```java
driver.findElement(By.xpath("//input[@type='password'][@id='PasswdAgain']"));
```
### 5.使用`contains()`:
如今,大多數屬性值(例如“`id`”,“`src`”,“`href`”等)都是使用恒定的前綴或后綴動態生成的。
想象一個網頁每天都有變化的圖像。 其`src`可以是“`Image_random-generated-key_date.jpg`”。 在這種情況下,我們可以通過 XPath 使用在其`src`屬性中包含“`Image`”值的“`img`”標記定位圖像。 因此,通過指定屬性的部分值,我們可以找到元素。
**語法**:`driver.findElement(By.xpath("//tag_name[contains(@attribute, 'value')]]"))`
**說明**:標識具有指定`tag_name`的元素,該元素的屬性與給定的部分值相匹配。
**示例**:讓我們在 Gmail 帳戶注冊頁面上找到“下一步”按鈕。
右鍵單擊按鈕并檢查元素以獲取相應的 HTML 代碼,如下所示,
*代碼:*
```java
driver.findElement(By.xpath("//div[contains(@class,'button')]/input"));
```
注意,該 XPath 標識`div`元素,該`div`元素包含帶有部分值`button`的`class`屬性(`<div class="form-element nextstep-button">`),然后找到其子“`input`”標簽(即“提交”按鈕)。
### 6.查找多個元素
您可能會遇到希望查找具有特定類或名稱的所有元素并對它們執行某些操作的情況。 星號(`*`)符號可助我們一臂之力!
**示例**:讓我們在 Gmail 帳戶注冊頁面上找到所有類值為“`goog-inline-block`”的元素。
*代碼:*
```java
driver.findElements(By.xpath("//*[contains(@class,'goog-inline-block')]"));
```
這將找到在其“`class`”屬性中包含值“`goog-inline-block`”的所有標簽。
明確指出要使用“`findElements`”,以便將所有已標識的 Web 元素添加到列表中。 如果使用“`findElement`”,它將僅返回所標識的第一個元素。
**概覽**
讓我們來看一個測試案例,該案例實現了迄今為止本文中涵蓋的所有技術,
*場景*
1. 打開 Firefox 瀏覽器。
2. 導航到 Google 帳戶創建頁面
3. 使用絕對 XPath 找到“名字”文本框
4. 輸入“`testFirst`”作為名字
5. 使用標簽和“`id`”屬性找到“姓氏”文本框(當然是相對的 XPath!)
6. 輸入“`testLast`”作為姓氏
7. 使用兩個條件(類型和 ID 屬性)找到“確認密碼”文本框
8. 輸入“`Pass1234!`”作為確認密碼
9. 使用星號將所有包含在其“`class`”屬性中值“`goog-inline-block`”的元素定位
10. 將找到的元素總數打印到控制臺
11. 將第一個標識的元素的標題值打印到控制臺
12. 使用`contains()`找到“下一步”按鈕
13. 將其“`name`”屬性的值打印到控制臺
14. 驗證 Eclipse IDE 控制臺的輸出屏幕和 JUnit 窗格是否成功
此方案的 JUnit 代碼是,
```java
package com.blog.junitTests;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class ElementLocatorTest4 {
//Declaring variables
private WebDriver driver;
private String baseUrl;
@Before
public void setUp() throws Exception{
// Selenium version3 beta releases require system property set up
System.setProperty("webdriver.gecko.driver", "E:\\ Softwares\\Selenium\\geckodriver-v0.10.0-win64\\geckodriver.exe");
// Create a new instance for the class FirefoxDriver
// that implements WebDriver interface
driver = new FirefoxDriver();
// Implicit wait for 5 seconds
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
// Assign the URL to be invoked to a String variable
baseUrl = "https://accounts.google.com/SignUp";
}
@Test
public void testPageTitle() throws Exception{
// Open baseUrl in Firefox browser window
driver.get(baseUrl);
// Locate 'First Name' text box by absolute XPath
// assign it to a variable of type WebElement
WebElement firstName = driver.findElement(By.xpath("/html/body/div[1]/div[2]/div/div[1]"
+ "/div/form/div[1]/fieldset/label[1]/input"));
// Clear the default placeholder or any value present
firstName.clear();
// Enter/type the value to the text box
firstName.sendKeys("testFirst");
// Locate 'Last Name' text box by relative XPath: using tag and id attribute
WebElement lastName = driver.findElement(By.xpath("//input[@id='LastName']"));
lastName.clear();
lastName.sendKeys("testLast");
// Locate 'Confirm your password' text box by XPath: using two conditions
WebElement confirmPwd = driver.findElement(By.xpath("//input[@type='password'][@id='PasswdAgain']"));
confirmPwd.clear();
confirmPwd.sendKeys("Pass1234!");
//Locate all elements with class 'goog-inline-block' by relative XPath: using asterisk symbol
List<WebElement> dropdowns = driver.findElements(By.xpath("//*[contains(@class,'goog-inline-block')]"));
// Prints to the console, the total number of elements located
System.out.println("Total elements containing the class 'goog-inline-block' are= " + dropdowns.size());
// Prints first identified element's title value to console
System.out.println("Value of the dropdown's 'title' attribute = " + dropdowns.get(0).getAttribute("title"));
// Locate 'Next step' button by XPath: contains() and child element
WebElement submitBtn = driver.findElement(By.xpath("//div[contains(@class,'button')]/input"));
// Prints submitBtn's 'name' attribute's value to the console
System.out.println("Value of the button's 'name' attribute = " + submitBtn.getAttribute("name"));
}
@After
public void tearDown() throws Exception{
// Close the Firefox browser
driver.close();
}
}
```
*執行結果:*
這段代碼將作為本文討論的每種技術的一部分進行解釋。
在 JUnit 窗口中,綠色條顯示測試用例已成功執行。 控制臺窗口顯示沒有任何錯誤。 它還顯示帶有星號的 Web 元素總數,以及下拉菜單和按鈕的屬性值。

下圖顯示了成功執行測試腳本后獲得的 Firefox 輸出。

休息一下伙計! 我們的下一篇文章將是定位元素策略的最后一篇。 所以不要錯過! 很快見,祝您愉快!
- JavaBeginnersTutorial 中文系列教程
- Java 教程
- Java 教程 – 入門
- Java 的歷史
- Java 基礎知識:Java 入門
- jdk vs jre vs jvm
- public static void main(string args[])說明
- 面向初學者的 Java 類和對象教程
- Java 構造器
- 使用 Eclipse 編寫 Hello World 程序
- 執行順序
- Java 中的訪問修飾符
- Java 中的非訪問修飾符
- Java 中的數據類型
- Java 中的算術運算符
- Java 語句初學者教程
- 用 Java 創建對象的不同方法
- 內部類
- 字符串構建器
- Java 字符串教程
- Java 教程 – 變量
- Java 中的變量
- Java 中的局部變量
- Java 中的實例變量
- Java 引用變量
- 變量遮蓋
- Java 教程 – 循環
- Java for循環
- Java 教程 – 異常
- Java 異常教程
- 異常處理 – try-with-resources語句
- Java 異常處理 – try catch塊
- Java 教程 – OOPS 概念
- Java 重載
- Java 方法覆蓋
- Java 接口
- 繼承
- Java 教程 – 關鍵字
- Java 中的this關鍵字
- Java static關鍵字
- Java 教程 – 集合
- Java 數組教程
- Java 集合
- Java 集合迭代器
- Java Hashmap教程
- 鏈表
- Java 初學者List集合教程
- Java 初學者的Map集合教程
- Java 初學者的Set教程
- Java 初學者的SortedSet集合教程
- Java 初學者SortedMap集合教程
- Java 教程 – 序列化
- Java 序列化概念和示例
- Java 序列化概念和示例第二部分
- Java 瞬態與靜態變量
- serialVersionUID的用途是什么
- Java 教程 – 枚舉
- Java 枚舉(enum)
- Java 枚舉示例
- 核心 Java 教程 – 線程
- Java 線程教程
- Java 8 功能
- Java Lambda:初學者指南
- Lambda 表達式簡介
- Java 8 Lambda 列表foreach
- Java 8 Lambda 映射foreach
- Java 9
- Java 9 功能
- Java 10
- Java 10 獨特功能
- 核心 Java 教程 – 高級主題
- Java 虛擬機基礎
- Java 類加載器
- Java 開發人員必須知道..
- Selenium 教程
- 1 什么是 Selenium?
- 2 為什么要進行自動化測試?
- 3 Selenium 的歷史
- 4 Selenium 工具套件
- 5 Selenium 工具支持的瀏覽器和平臺
- 6 Selenium 工具:爭霸
- 7A Selenium IDE – 簡介,優點和局限性
- 7B Selenium IDE – Selenium IDE 和 Firebug 安裝
- 7C Selenium IDE – 突破表面:初探
- 7D Selenium IDE – 了解您的 IDE 功能
- 7E Selenium IDE – 了解您的 IDE 功能(續)。
- 7F Selenium IDE – 命令,目標和值
- 7G Selenium IDE – 記錄和運行測試用例
- 7H Selenium IDE – Selenium 命令一覽
- 7I Selenium IDE – 設置超時,斷點,起點
- 7J Selenium IDE – 調試
- 7K Selenium IDE – 定位元素(按 ID,名稱,鏈接文本)
- 7L Selenium IDE – 定位元素(續)
- 7M Selenium IDE – 斷言和驗證
- 7N Selenium IDE – 利用 Firebug 的優勢
- 7O Selenium IDE – 以所需的語言導出測試用例
- 7P Selenium IDE – 其他功能
- 7Q Selenium IDE – 快速瀏覽插件
- 7Q Selenium IDE – 暫停和反射
- 8 給新手的驚喜
- 9A WebDriver – 架構及其工作方式
- 9B WebDriver – 在 Eclipse 中設置
- 9C WebDriver – 啟動 Firefox 的第一個測試腳本
- 9D WebDriver – 執行測試
- 9E WebDriver – 用于啟動其他瀏覽器的代碼示例
- 9F WebDriver – JUnit 環境設置
- 9G WebDriver – 在 JUnit4 中運行 WebDriver 測試
- 9H WebDriver – 隱式等待
- 9I WebDriver – 顯式等待
- 9J WebDriver – 定位元素:第 1 部分(按 ID,名稱,標簽名稱)
- 9K WebDriver – 定位元素:第 2 部分(按className,linkText,partialLinkText)
- 9L WebDriver – 定位元素:第 3a 部分(按cssSelector定位)
- 9M WebDriver – 定位元素:第 3b 部分(cssSelector續)
- 9N WebDriver – 定位元素:第 4a 部分(通過 xpath)
- 9O WebDriver – 定位元素:第 4b 部分(XPath 續)
- 9P WebDriver – 節省時間的捷徑:定位器驗證
- 9Q WebDriver – 處理驗證碼
- 9R WebDriver – 斷言和驗證
- 9S WebDriver – 處理文本框和圖像
- 9T WebDriver – 處理單選按鈕和復選框
- 9U WebDriver – 通過兩種方式選擇項目(下拉菜單和多項選擇)
- 9V WebDriver – 以兩種方式處理表
- 9W WebDriver – 遍歷表元素
- 9X WebDriver – 處理警報/彈出框
- 9Y WebDriver – 處理多個窗口
- 9Z WebDriver – 最大化窗口
- 9AA WebDriver – 執行 JavaScript 代碼
- 9AB WebDriver – 使用動作類
- 9AC WebDriver – 無法輕松定位元素? 繼續閱讀...
- 10A 高級 WebDriver – 使用 Apache ANT
- 10B 高級 WebDriver – 生成 JUnit 報告
- 10C 高級 WebDriver – JUnit 報表自定義
- 10D 高級 WebDriver – JUnit 報告自定義續
- 10E 高級 WebDriver – 生成 PDF 報告
- 10F 高級 WebDriver – 截屏
- 10G 高級 WebDriver – 將屏幕截圖保存到 Word 文檔
- 10H 高級 WebDriver – 發送帶有附件的電子郵件
- 10I 高級 WebDriver – 使用屬性文件
- 10J 高級 WebDriver – 使用 POI 從 excel 讀取數據
- 10K 高級 WebDriver – 使用 Log4j 第 1 部分
- 10L 高級 WebDriver – 使用 Log4j 第 2 部分
- 10M 高級 WebDriver – 以無頭模式運行測試
- Vue 教程
- 1 使用 Vue.js 的 Hello World
- 2 模板語法和反應式的初探
- 3 Vue 指令簡介
- 4 Vue Devtools 設置
- 5 數據綁定第 1 部分(文本,原始 HTML,JavaScript 表達式)
- 6 數據綁定第 2 部分(屬性)
- 7 條件渲染第 1 部分(v-if,v-else,v-else-if)
- 8 條件渲染第 2 部分(v-if和v-show)
- 9 渲染列表第 1 部分(遍歷數組)
- 10 渲染列表第 2 部分(遍歷對象)
- 11 監聽 DOM 事件和事件修飾符
- 12 監聽鍵盤和鼠標事件
- 13 讓我們使用簡寫
- 14 使用v-model進行雙向數據綁定
- 15 表單輸入綁定
- 18 類綁定
- Python 教程
- Python 3 簡介
- Python 基礎知識 - 又稱 Hello World 以及如何實現
- 如何在 Windows 中安裝 python
- 適用于 Windows,Mac,Linux 的 Python 設置
- Python 數字和字符串
- Python 列表
- Python 集
- Python 字典
- Python 條件語句
- Python 循環
- Python 函數
- 面向對象編程(OOP)
- Python 中的面向對象編程
- Python 3 中的異常處理
- Python 3:猜數字
- Python 3:猜數字 – 回顧
- Python 生成器
- Hibernate 教程
- Hibernate 框架基礎
- Hibernate 4 入門教程
- Hibernate 4 注解配置
- Hibernate 4 的實體關系
- Hibernate 4 中的實體繼承模型
- Hibernate 4 查詢語言
- Hibernate 4 數據庫配置
- Hibernate 4 批處理
- Hibernate 4 緩存
- Hibernate 4 審計
- Hibernate 4 的并發控制
- Hibernate 4 的多租戶
- Hibernate 4 連接池
- Hibernate 自舉