WebDriver元素查找方法摘錄與總結
整理By:果凍迪迪
selenium-webdriver提供了強大的元素定位方法,支持以下三種方法。
• 單個對象的定位方法
• 多個對象的定位方法
• 層級定位
定位單個元素
在定位單個元素時,selenium-webdriver提示了如下一些方法對元素進行定位。
-
By.className(className))
-
By.cssSelector(selector)
-
By.id(id)
-
By.linkText(linkText)
-
By.name(name)
-
By.partialLinkText(linkText)
-
By.tagName(name)
-
By.xpath(xpathExpression)
注意:selenium-webdriver通過findElement()\findElements()等find方法調用"By"對象來定位和查詢元素。
By類只是提供查詢的方式進行分類。findElement返回一個元素對象否則拋出異常,findElements返回符合條
件的元素List,如果不存在符合條件的就返回一個空的list。
使用className進行定位
當所定位的元素具有class屬性的時候我們可以通過classname來定位該元素。
下面的例子定位了51.com首頁上class為"username"的li。
-
import org.openqa.selenium.WebDriver;
-
import org.openqa.selenium.WebElement;
-
import org.openqa.selenium.By;
-
public class ByClassName {
-
public static void main(String[] args) {
-
WebDriver driver = new FirefoxDriver();
-
driver.get("http://www.51.com");
-
WebElement element = driver.findElement(By.className("username"));
-
System.out.println(element.getTagName());
-
}
-
}
-
-
import org.openqa.selenium.WebDriver;
-
import org.openqa.selenium.WebElement;
-
import org.openqa.selenium.By;
-
public class ByClassName {
-
public static void main(String[] args) {
-
WebDriver driver = new FirefoxDriver();
-
driver.get("http://www.51.com");
-
WebElement element = driver.findElement(By.className("username"));
-
System.out.println(element.getTagName());
-
}
-
}
輸出結果:
li
使用id屬性定位
51.com首頁的帳號輸入框的html代碼如下:
<input id="passport_51_user" type="text" value="" tabindex="1" title="用戶名/彩虹號/郵箱"
name="passport_51_user">
在下面的例子中我們用id定位這個輸入框,並輸出其title,借此也可以驗證代碼是否工作正常。
-
import org.openqa.selenium.By;
-
import org.openqa.selenium.WebDriver;
-
import org.openqa.selenium.WebElement;
-
import org.openqa.selenium.firefox.FirefoxDriver;
-
public class ByUserId {
-
/**第 13 / 80 頁
-
* @param args
-
*/
-
public static void main(String[] args) {
-
// TODO Auto-generated method stub
-
WebDriver dr = new FirefoxDriver();
-
dr.get("http://www.51.com");
-
WebElement element = dr.findElement(By.id("passport_51_user"));
-
System.out.println(element.getAttribute("title"));
-
}
-
}
輸出結果:
用戶名/彩虹號/郵箱
使用name屬性定位
51.com首頁的帳號輸入框的html代碼如下:
<input id="passport_51_user" type="text" value="" tabindex="1" title="用戶名/彩虹號/郵箱"
name="passport_51_user">
使用name定位
WebElement e = dr.findElement(By.name("passport_51_user"));
使用css屬性定位
51.com首頁的帳號輸入框的html代碼如下:
<input id="passport_51_user" type="text" value="" tabindex="1" title="用戶名/彩虹號/郵箱"
name="passport_51_user">
使用css定位
WebElement e1 = dr.findElement(By.cssSelector("#passport_51_user"));
使用其他方式定位
在定位link元素的時候,可以使用link和link_text屬性;
另外還可以使用tag_name屬性定位任意元素;
定位多個元素
上面提到findElements()方法可以返回一個符合條件的元素List組。看下面例子。
-
import java.io.File;
-
import java.util.List;
-
import org.openqa.selenium.By;
-
import org.openqa.selenium.WebDriver;
-
import org.openqa.selenium.WebElement;
-
import org.openqa.selenium.firefox.FirefoxBinary;
-
import org.openqa.selenium.firefox.FirefoxDriver;
-
public class FindElementsStudy {
-
/**
-
* @author gongjf
-
*/
-
public static void main(String[] args) {
-
WebDriver driver = new FirefoxDriver();
-
driver.get("http://www.51.com");
-
//定位到所有<input>標簽的元素,然后輸出他們的id
-
List<WebElement> element = driver.findElements(By.tagName("input"));
-
for (WebElement e : element){
-
System.out.println(e.getAttribute("id"));
-
}
-
driver.quit();
-
}
-
}
-
輸出結果:
-
passport_cookie_login
-
gourl
-
passport_login_from
-
passport_51_user
-
passport_51_password
-
passport_qq_login_2
-
btn_reg
-
passport_51_ishidden
-
passport_auto_login
上面的代碼返回頁面上所有input對象。很簡單,沒什么可說的。
層級定位
層級定位的思想是先定位父元素,然后再從父元素中精確定位出其我們需要選取的子元素。
層級定位一般的應用場景是無法直接定位到需要選取的元素,但是其父元素比較容易定位,通過定位父元素再
遍歷其子元素選擇需要的目標元素,或者需要定位某個元素下所有的子元素。
下面的代碼演示了如何使用層級定位class為"login"的div,然后再取得它下面的所有label,並打印出他們的文
本
-
import java.io.File;
-
import java.util.List;
-
import org.openqa.selenium.By;
-
import org.openqa.selenium.WebDriver;
-
import org.openqa.selenium.WebElement;
-
import org.openqa.selenium.firefox.FirefoxBinary;
-
import org.openqa.selenium.firefox.FirefoxDriver;
-
public class LayerLocator {
-
/**
-
* @author gongjf
-
*/
-
public static void main(String[] args) {
-
WebDriver driver = new FirefoxDriver();
-
driver.get("http://www.51.com");
-
//定位class為"login"的div,然后再取得它下面的所有label,並打印出他們的值
-
WebElement element = driver.findElement(By.className("login"));
-
List<WebElement> el = element.findElements(By.tagName("label"));
-
for(WebElement e : el)
-
System.out.println(e.getText());
-
}
-
}
-
輸出結果:
-
帳號:
-
密碼:
-
隱身
-
下次自動登錄
********************************************************************************************************************************************************************以下總結來自博客園(園主:qileilove)**************************************
webdriver提供了豐富的API,有多種定位策略:id,name,css選擇器,xpath等,其中css選擇器定位元素效率相比xpath要高些,使用id,name屬性定位元素是最可靠,效率最高的一種辦法。
1、工具選擇:在我們開發測試腳本的過程中各個瀏覽器給我們也提供了方便定位元素的工具,我比較喜歡使用firefox的firebug工具,也是目前很多開發測試人員比較熱衷的選擇,原因是firefox是唯一能夠集成selenium IDE的瀏覽器,並且firebug給用戶提供了豐富的擴展組件,我們可以根據自己的需要來選擇,一般情況下,使用firebug+firefinder就足夠使用了,firefinder支持xpath以及css選擇器定位元素的功能,很方便幫助我們調試測試腳本
2、元素定位的方法:findElement() 與 findElements()
findElement() 該方法返回基於指定查詢條件的webElement對象,或拋出不符合條件的異常 eg:driver.findElement(By.id("userID"));
findElements() 該方法返回指定查詢條件的WebElement的對象集合,或返回null
3、WebElement對象提供的各種定位元素策略
ID:driver.findElement(By.id(<elementID>)) Name:driver.findElement(By.name(<elementName>)) className:driver.findElement(By.className(<elementClassName>)) tagName:driver.findElement(By.tagName(<htmlTagName>)) linkText:driver.findElement(By.linkText(<linkText>)) partialLinkText:driver.findElement(By.partialLinkText(<partialLinkText>)) css:driver.findElement(By.cssSelector(<cssSelector>)) xpath:driver.findElement(By.xpath(<xpathQuery>)) |
4、webelement類提供了諸多方法,在我們開發腳本過程中如何選擇最可靠,效率最高的方法,使用id,name
是首選,因為他們在html標簽中是唯一的,所以是最可靠的
ID定位:driver.findElement(By.id("username"))
name定位:driver.findElement(By.name("username"))
class定位:driver.findElement(By.className("username"))
多學一招:WebElement類支持查詢子類元素,如果頁面中存在重復元素,但在不同div中,我們可以先定位到其父元素,然后定位其子元素,方法如下:
WebElement hello = driver.findElement(By.id("div1")).findElement(By.lindText("hello"));
5、使用WebElements定位多個相似的元素,比如頁面中存在五個單選按鈕,他們有相同的class屬性,值為:myRadio,我們想對五個按鈕循環操作,我們可以把它們全部取出來放到集合中,然后做循環操作,如下:
List<WebElement> radios = driver.findElements(By.className("myRadio")); for(int i = 0;i<radios.size();i++){ radios.get(i).click(); } |
其他定位方法與操作id,name類似,這里不再贅述,接下來我着重對css選擇器與Xpath描述下
一、WebDriver 的By類中提供了cssSelector()方法,該方法使用有以下幾種形式:
1、使用相對路徑定位元素
如,我們要定為DOM中的input元素,我們可以這樣操作,不考慮其在DOM中的位置,但這樣做存在一定弊端,當DOM中存在多個input元素時,該方法總返回DOM中的第一個元素,這並不是我們所期待的
eg:WebElement username = driver.findElement(By.cssSelector("input"));
另外,為了使用這種方法更准確的定位元素,我們可以結合該元素的其他屬性來實現精確定位的目的
a、結合id來定位,driver.findElement(By.cssSelector("input#username")); 在標簽與id之間使用#連接,如果對css了解的朋友一看就知道為什么會這樣寫了,不了解也沒關系,只要記住這種寫法就OK了
另外該方法也可簡寫為driver.findElement(By.cssSelector("#username")); 有點兒類似於id選擇器
b、使用元素的任何屬性來定位元素
driver.findElement(By.cssSelector("標簽名[屬性名='屬性值']"));
c、匹配部分屬性值
^= driver.findElement(By.cssSelector("標簽名[屬性名^='xxx']")); 匹配屬性值以xxx開頭的元素 $= driver.findElement(By.cssSelector("標簽名[屬性名$='xxx']")); 匹配屬性值以xxx結尾的元素 *= driver.findElement(By.cssSelector("標簽名[屬性名^='xxx']")); 匹配屬性值包含xxx的元素 |
2、使用相對+絕對路徑方法,這里是我自己定義的方法,方便記憶,的確也是這樣來實現的
driver.findElement(By.cssSelector("div#login>input")) 該方法中"div#login>input" 首先通過相對路徑定位到id為login的div元素,然后查找其子元素input(絕對路徑)
二、使用xpath定位元素,相比cssSelector,xpath是我比較常用的一種定位元素的方式,因為它很方便,缺點是,消耗系統性能
1、使用絕對路徑定位元素
driver.findElement(By.xpath("/html/body/div/form/input"))
2、使用相對路徑定位元素
driver.findElement(By.xpath("//input")) 返回查找到的第一個符合條件的元素
3、使用索引定位元素,索引的初始值為1,注意與數組等區分開
driver.findElement(By.xpath("//input[2]")) 返回查找到的第二個符合條件的元素
4、結合屬性值來定位元素
driver.findElement(By.xpath("//input[@id='username']"));
driver.findElement(By.xpath("//img[@alt='flowr']"));
5、使用邏輯運算符,結合屬性值定位元素,and與or
driver.findElement(By.xpath("//input[@id='username' and @name='userID']"));
6、使用屬性名來定位元素
driver.findElement(By.xpath("//input[@button]"))
7、類似於cssSlector,使用部分屬性值匹配元素
starts-with() driver.findElement(By.xpath("//input[stars-with(@id,'user')]")) ends-with driver.findElement(By.xpath("//input[ends-with(@id,'name')]")) contains() driver.findElement(By.xpath("//input[contains(@id,"ernam")]")) |
8、使用任意屬性值匹配元素
driver.findElement(By.xpath("//input[@*='username']"))
9、使用xpath軸來定位元素
這里略了,詳見w3school.com
三、使用innerText定位元素
1、使用cssSelector查找innerText定位元素
driver.findElement(By.cssSelector("span[textContent='新聞']"));
2、使用xpath的text函數
driver.findElement(By.xpath("//span[contains(text(),'hello')]")) 包含匹配
driver.findElement(By.xpath("//span[text()='新聞']")) 絕對匹配