selenium webdriver进行元素定位时,通过seleniumAPI官方介绍,获取页面元素的方式一共有以下八种方式,现按照常用→不常用的顺序分别介绍一下。
官方api地址:https://seleniumhq.github.io/selenium/docs/api/java/index.html
一、By.Id()
在HTML中,ID属性--唯一标识一个元素的属性。selenium中,ID被作为首选的识别属性,因为这是最快的识别策略。
以百度主页为例,搜索框的HTML示例代码如下,其ID为kw;
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
搜索框的ID是"kw"。
<input type="submit" id="su" value="百度一下" class="bg s_btn">
百度一下按钮的id是"su"。
在WebDriver中通过ID查找元素的java示例代码如下:
1 import org.openqa.selenium.By;
2 import org.openqa.selenium.WebDriver;
3 import org.openqa.selenium.chrome.ChromeDriver;
4 import org.testng.annotations.Test;
5 public class findElementByID {
6 @Test
7 public void test() {
8 WebDriver driver = new ChromeDriver(); //打开chrome浏览器
9 driver.get("http://www.baidu.com"); //输入网址
10 driver.findElement(By.id("kw")).sendKeys("selenium"); //搜索框输入"selenium"
11 driver.findElement(By.id("su")).click(); //点击百度一下,进行搜索
12 driver.quit(); //关闭浏览器
13 }
14 }
示例代码详解:
1、指定WebDriver 为ChromeDriver。
2、打开百度主页。
3、通过ID为kw来查找搜索框,其中findElement()方法通过By.id()在页面上查找指定的ID元素,并将查找的结果执行sendkeys操作,输入要搜索的值。
4、在搜索框中输入字符串"selenium"。
5、通过ID为su来查找搜索按钮,并执行click点击操作。
6、触发搜索按钮的提交操作,进行搜索。
7、关闭浏览器,结束测试。
二、By.Name()
在HTML中,name属性和ID属性功能基本相同,只是name属性不一定是唯一的。在selenium中,如果没有ID的话,首先考虑的就是name属性。
以豆瓣网的主页搜索框为例子,其搜索框的HTML代码如下:
<input type="text" maxlength="60" size="12" placeholder="书籍、电影、音乐、小组、小站、成员" name="q" autocomplete="off">
搜索框的name是"q"。
在WebDriver中通过Name查找元素的java示例代码如下:
1 import org.openqa.selenium.By;
2 import org.openqa.selenium.WebDriver;
3 import org.openqa.selenium.WebElement;
4 import org.openqa.selenium.chrome.ChromeDriver;
5 import org.testng.annotations.Test;
6 public class findElementByName {
7 @Test
8 public void test() {
9 WebDriver driver = new ChromeDriver(); //打开chrome浏览器
10 driver.get("http://www.douban.com"); //输入网址
11 WebElement serch=driver.findElement(By.name("q")); //生成WebElement实例对象serch
12 serch.sendKeys("find element by name"); //搜索框输入"find element by name"
13 serch.submit(); //进行搜索
14 driver.quit(); //关闭浏览器
15 }
16 }
示例代码详解:
1、指定WebDriver 为ChromeDriver。
2、打开豆瓣主页。
3、通过Name为q来调用findElemet()方法找到豆瓣主页的搜索框元素,并保存到WebElement实例对象中代码如下:
WebElement search = driver.findElement(By.name("q"));
4、在搜索框中输入字符串find element by name 。
5、通过submit(),进行搜索。
6、结束测试,关闭浏览器。
注意:submit和click的区别。Click方法只适用于button,而submit可以用于提交表单。
三、By.Xpath()
这个方法是非常强大的元素查找方式,使用这种方法几乎可以定位到页面上的任意元素。在正式开始使用XPath进行定位前,我们先了解下什么是XPath。XPath是XML Path的简称,由于HTML文档本身就是一个标准的XML页面,所以我们可以使用XPath的语法来定位页面元素。
Xpath通过路径来定位控件,分为绝对路径和相对路径。绝对路径以单/号表示,相对路径则以//表示。当xpath的路径以/开头时,表示让Xpath解析引擎从文档的根节点开始解析。当xpath路径以//开头时,则表示让xpath引擎从文档的任意符合的元素节点开始进行解析。而当/出现在xpath路径中时,则表示寻找父节点的直接子节点,当//出现在xpath路径中时,表示寻找父节点下任意符合条件的子节点。弄清这个原则,就可以理解其实xpath的路径可以绝对路径和相对路径混合在一起来进行表示,想怎么玩就怎么玩。
假设我们现在以下图所示HTML代码为例,要引用对应的对象,XPath语法如下:
绝对路径写法(只有一种),写法如下:
引用页面上的form元素(即源码中的第3行):/html/body/form
下面是相对路径的引用写法:
查找页面根元素://
查找页面上所有的input元素://input
查找页面上第一个form元素内的直接子input元素(即只包括form元素的下一级input元素)://form/input
查找页面上第一个form元素内的所有子input元素(只要在form元素内的input都算,不管还嵌套了多少个其他标签,使用相对路径表示,双//号)://form//input
查找页面上第一个form元素://form
查找页面上id为loginForm的form元素://form[@id='loginForm']
查找页面上具有name属性为username的input元素://input[@name='username']
查找页面上id为loginForm的form元素下的第一个input元素://form[@id='loginForm']/input[1]
查找页面具有name属性为contiune并且type属性为button的input元素://input[@name='continue'][@type='button']
查找页面上id为loginForm的form元素下第4个input元素://form[@id='loginForm']/input[4]
以百度主页为例,搜索框的HTML示例代码如下,其xpath为//*[@id=''kw]。
在WebDriver中通过Xpath查找元素的java示例代码如下:
1 import org.openqa.selenium.By;
2 import org.openqa.selenium.WebDriver;
3 import org.openqa.selenium.WebElement;
4 import org.openqa.selenium.chrome.ChromeDriver;
5 import org.testng.annotations.Test;
6 public class findElementByXpath {
7 @Test
8 public void test() {
9 WebDriver driver = new ChromeDriver(); //打开chrome浏览器
10 driver.get("http://www.baidu.com"); //输入网址
11 WebElement serch=driver.findElement(By.xpath("//*[@id='kw'")); //生成WebElement实例对象serch
12 serch.sendKeys("find element by xpath"); //搜索框输入"find element by xpath"
13 serch.submit(); //进行搜索
14 driver.quit(); //关闭浏览器
15 }
16 }
示例代码详解:
1、指定WebDriver 为ChromeDriver。
2、打开百度主页。
3、通过Xpath为//*[@id=''kw]来调用findElemet()方法找到百度主页的搜索框元素,并保存到WebElement实例对象中代码如下:
WebElement search = driver.findElement(By.xpath("//*[@id=''kw]"));
4、在搜索框中输入字符串find element by xpath。
5、通过submit(),进行搜索。
6、结束测试,关闭浏览器。
四、By.tagName()
通过TagName来查找元素的方式与之前的通过ID或者Name查找元素的方式略有不同。其原因是同一个页面上具有相同的TagName的元素就会返回多个结果,因此建议在使用TagName为查找元素的条件时,使用findElements()来替代findElement()函数。
以126为例,TagName为input的HTML事例代码如下:
通过TagName为script的元素个数的示例代码如下
在WebDriver中查找TagName为input的元素个数的java示例代码如下:
1 import java.util.List;
2
3 import org.openqa.selenium.By;
4 import org.openqa.selenium.WebDriver;
5 import org.openqa.selenium.WebElement;
6 import org.openqa.selenium.chrome.ChromeDriver;
7 import org.testng.annotations.Test;
8
9 public class findElementByTagName {
10 @Test
11 public void test() {
12 WebDriver driver = new ChromeDriver(); // 打开chrome浏览器
13 driver.get("http://www.126.com"); // 输入网址
14 List<WebElement> allInputs = driver.findElements(By.tagName("input")); // 生成WebElement实例对象allInputs
15 System.out.println(allInputs.size()); // 输出tagName为input的个数
16 driver.quit(); // 关闭浏览器
17 }
18 }
示例代码详解:
1、指定WebDriver 为ChromeDriver。
2、通过TagName为input来调用findElements()方法,找到126主页上所有的input元素并保存到WebElement实例对象列表中,代码如下:
List<WebElement> allInputs= driver.findElements(By.tagName("input"));
3、打印126主页上TagName为input的元素的数量
4、结束测试,关闭浏览器。
从html中我们可以看到,文本框和密码框的元素标签都是input,此时单靠tagName无法准确地得到我们想要的元素,需要结合type属性才能过滤出我们要的元素。
示例代码如下:
1 import java.util.List;
2
3 import org.openqa.selenium.By;
4 import org.openqa.selenium.WebDriver;
5 import org.openqa.selenium.WebElement;
6 import org.openqa.selenium.chrome.ChromeDriver;
7 import org.testng.annotations.Test;
8
9 public class findElementByTagName {
10 @Test
11 public void test() {
12 WebDriver driver = new ChromeDriver(); // 打开chrome浏览器
13 driver.get("http://www.126.com"); // 输入网址
14 List<WebElement> allInputs = driver.findElements(By.tagName("input")); // 生成WebElement实例对象allInputs
15 System.out.println(allInputs.size()); // 输出tagName为input的个数
16 for (WebElement e : allInputs) { // 循环
17 if (e.getAttribute("type").equals("text")) { // 判断
18 e.sendKeys("abcde"); // 输入"abcde"
19 }
20 }
21 driver.quit(); // 关闭浏览器
22 }
23 }
五、By.className()
className属性是利用元素的css样式表所引用的伪类名称来进行元素查找的方法。
以淘宝主页搜索框为例,其HTML如下:
通过className获取搜索框的java代码如下:
1 import org.openqa.selenium.By;
2 import org.openqa.selenium.WebDriver;
3 import org.openqa.selenium.WebElement;
4 import org.openqa.selenium.chrome.ChromeDriver;
5 import org.testng.annotations.Test;
6
7 public class findElementByclassName {
8 @Test
9 public void test() {
10 WebDriver driver = new ChromeDriver(); // 打开chrome浏览器
11 driver.get("http://www.taobao.com"); // 输入网址
12 WebElement e = driver.findElement(By.className("search-combobox-input")); // 实例化对象
13 e.sendKeys("find element by className"); // 输入find element by className
14 e.submit(); //搜索
15 driver.quit(); // 关闭浏览器
16 }
17 }
示例代码详解:
1、指定WebDriver 为ChromeDriver。
2、打开淘宝主页。
3、通过className为search-combobox-input来调用findElemet()方法找到淘宝主页的搜索框元素,并保存到WebElement实例对象中。
4、在搜索框中输入字符串find element by className。
5、通过submit(),进行搜索。
6、结束测试,关闭浏览器。
六、By.CssSelector()
CssSelector,Selenium官网的Document里极力推荐使用CSS locator,而不是XPath来定位元素,原因是CSS locator比XPath locator速度快,特别是在IE下面(IE没有自己的XPath 解析器(Parser))他比xpath更高效更准确更易编写,因为前端开发人员就是用CSS Selector设置页面上每一个元素的样式,无论那个元素的位置有多复杂,他都能定位到,那我们使用CSS Selector肯定也能非常精准的定位到页面Elements。
css定位可以分为四类:id、class、tagName、其他属性、路径。
1 #id方式
两种方式,可以在前面加上tag名称,也可以不加
driver.findElement(By.cssSelector("#id_value")) 相当于使用id语法的driver.findElement(By.id("id_value"))
driver.findElement(By.cssSelector("tag_name#id_value")) 相当于使用xpath语法的driver.findElement(By.xpath("//tag_name[@id='id_value']"))
以百度主页为例,搜索框的HTML示例代码如下,
通过CssSelector的#id方式的java代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.annotations.Test; public class FindElemenByCssSelector { @Test public void test() { WebDriver driver = new ChromeDriver(); // 打开chrome浏览器 driver.get( "http://www.baidu.com" ); // 输入网址 WebElement e = driver.findElement(By.cssSelector( "#kw" )); // 实例化对象 e.sendKeys( "find element by CssSelector" ); // 输入find element by CssSelector driver.findElement(By.cssSelector( "input#su" )).click(); // 点击百度一下 driver.quit(); // 关闭浏览器 } } |
示例代码详解:
实例化对象一行,使用CssSelector中的#id方式
点击百度一下那一行,使用CssSelector中的tagName#id方式
2 class方式
两种方式,前面加上tag名称,也可以不加。如果不加tag名称时,点不能省略。
driver.findElement(By.cssSelector(".class_value"))
driver.findElement(By.cssSelector("tag_name.class_value"))
有的class_value比较长,而且中间有空格时,不能把空格原样写进去,那样不能识别。这时,空格用点代替,前面要加上tag_name。
如下driver.findElement(By.cssSelector("tag_name.class_value1.calss_value2.class_value3"))
以百度主页为例,搜索框的HTML示例代码如下
通过CssSelector的.class方式的java代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.annotations.Test; public class FindElemenByCssSelector { @Test public void test() { WebDriver driver = new ChromeDriver(); // 打开chrome浏览器 driver.get( "http://www.baidu.com" ); // 输入网址 WebElement e = driver.findElement(By.cssSelector( ".s_ipt" )); // 实例化对象 e.sendKeys( "find element by CssSelector" ); // 输入find element by CssSelector driver.findElement(By.cssSelector( "input.bg.s_btn" )).click(); // 点击百度一下 driver.quit(); // 关闭浏览器 } } |
示例代码详解:
其中实例化一行,使用.class方式获取对象
点击百度一下一样,使用tagName.class_value1.class_value2方式获取对象。
3 tagName方式
driver.findElement(By.cssSelector("input")
其中tagName是input
4 根据元素属性
1)精准匹配:
[A] driver.findElement(By.cssSelector("input[name=username]"));属性名=属性值,id,class,等都可写成这种形式
[B] driver.findElement(By.cssSelector("input[type='submit'][value='Login']"));多属性
2)模糊匹配:(正则表达式匹配属性)
[A] ^= driver.findElement(By.cssSelector(Input[id ^='ctrl']));匹配到id头部 如ctrl_12
[B] $= driver.findElement(By.cssSelector(Input[id $='ctrl']));匹配到id尾部 如a_ctrl
[C] *= driver.findElement(By.cssSelector(Input[id *= 'ctrl']));匹配到id中间如1_ctrl_12
5 子元素方式
<form id="form" class="fm" name="f">
<span id="s_kw_wrap" class="bg s_ipt_wr quickdelete-wrap">
<input id="kw" class="s_ipt" type="text" autocomplete="off" maxlength="100" name="wd">
</span>
<span id="s_btn_wr" class="btn_wr s_btn_wr bg">
<input id="su" class="btn self-btn bg s_btn" type="submit" value="百度一下">
</span>
</form>
以上代码是百度首页搜索输入框和按钮的html,下面讲解以此为例
1)子元素 A>B
WebElement input= driver.findElement(By.cssSelector("form>span>input"));//搜索输入框
2)后代元素 A空格B
WebElement input= driver.findElement(By.cssSelector("form input"));//搜索输入框
3)第一个后代元素 :first-child
WebElement span= driver.findElemet(By.cssSelector("form :first-child"));//冒号前有空格,定位到form下所有级别的第一个子元素
可定位到三个元素:<span id="s_kw_wrap".../> <input id="kw"..../> <input id="su"........./>
WebElement span= driver.findElemet(By.cssSelector("form input:first-child"));//冒号前无空格,定位到form下所有级别的第一个input元素
可定位到两个元素:<input id="kw"..../> <input id="su"........./>
WebElement span= driver.findElemet(By.cssSelector("form>span:first-child"));//冒号前无空格,定位到form直接子元素中的第一个span元素
可定位到一个元素:<span id="s_kw_wrap".../>
4)最后一个子元素 :last-child [类同:first-child]
WebElement userName = driver.findEleme(By.cssSelector("form :last-child"));//冒号前有空格,定位到form下所有级别的第一个子元素
5)第2个子元素 :nth-child(N) [类同:first-child]
WebElement userName = driver.findElemet(By.cssSelector("form#form :nth-child(2)"));//冒号前有空格,定位到form下所有级别的第二个子元素
七、By.linkText()
这个方法比较直接,即通过超文本链接上的文字信息来定位元素,这种方式一般专门用于定位页面上的超文本链接。
以百度主页为例,搜索框的HTML示例代码如下
通过linkTest方式的java代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.annotations.Test; public class FindElemenByCssSelector { @Test public void test() { WebDriver driver = new ChromeDriver(); // 打开chrome浏览器 driver.get( "http://www.baidu.com" ); // 输入网址 WebElement a= driver.findElement(By.linkText( "新闻" )); a.click(); } } |
八、By.partialLinkText()
这个方法是上一个方法的扩展。当你不能准确知道超链接上的文本信息或者只想通过一些关键字进行匹配时,可以使用这个方法来通过部分链接文字进行匹配。代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.annotations.Test; public class FindElemenByCssSelector { @Test public void test() { WebDriver driver = new ChromeDriver(); // 打开chrome浏览器 driver.get( "http://www.baidu.com" ); // 输入网址 WebElement a= driver.findElement(By.partialLinkText( "新" )); a.click(); } } |
参考文档:http://www.cnblogs.com/qingchunjun/p/4208159.html