页面元素可以通过ID、Class名称、标签名称、name、链接的全部文字、部分链接文字、CSS、XPath、jQuery来定位。以下是从官网
https://www.seleniumhq.org/docs/03_webdriver.jsp#selenium-webdriver-api-commands-and-operations
摘抄整理的一些Java定位方法,以便使用查询。
一、By ID
由于页面元素的ID属性在当前网页中是唯一的,所以使用ID值定位可以保证定位的唯一性。
<div id="coolestWidgetEvah">...</div>
WebElement element = driver.findElement(By.id("coolestWidgetEvah"));
二、By Class Name
可以根据class属性值来查找一个或者一组显示效果相同的页面元素。
<html>
<head>
<style type="text/css">
input.spread {font-size: 20pt; }
input.tight {font-size: 10pt; }
</style>
</head>
<body>
<input class="spread" type=text></input>
<input class="tight" type=text></input>
</body>
</html>
WebElement input=driver.findElement(By.className("tight"));
三、By Tag Name
标签名称的定位方式主要用于匹配多个页面元素的情况,将查找到的网页元素对象进行计数、遍历、修改属性等操作。
<a href="http://www.sogou.com">sogou搜索</a><br>
<a href="http://www.baidu.com">baidu搜索</a>
WebElement link= driver.findElement(By.tagName("a"));
List<WebElement> links=driver.findElements(By.tagName("a"));
四、By Name
name在当前网页中可以不唯一,可能会同时定位到多个元素。
<input name="cheese" type="text"/>
WebElement cheese = driver.findElement(By.name("cheese"));
五、By Link Text
使用此方式定位链接要完全匹配链接的显示文字,若无法精确匹配,则无法找到链接。
<a href="http://www.google.com/search?q=cheese">cheese</a>>
WebElement cheese = driver.findElement(By.linkText("cheese"));
六、By Partial Link Text
此方式定位链接只需模糊匹配链接的显示文字即可,常用于匹配页面链接文字不定期发生少量文字变化的情况。使用模糊匹配的方式可以提高链接定位的准确率,也可以用于模糊匹配一组链接的情况。
<a href="http://www.sogou.com">sogou搜索</a><br>
<a href="http://www.baidu.com">baidu搜索</a>
WebElement cheese = driver.findElement(By.linkText("sog"));
List<WebElement> links=driver.findElements(By.partialLinkText("搜索"));
七、By CSS
<div id="food"><span class="dairy">milk</span><span class="dairy aged">cheese</span></div>
WebElement cheese = driver.findElement(By.cssSelector("#food span.dairy.aged"));
八、By XPath
XPath定位和CSS定位相比具备更大的灵活性,在XML文档树中的某个节点既可以向前搜索,也可以向后搜索,而CSS定位只能向前搜索,但XPath的速度会慢一些。
<html>
<body>
<div id="div1">
<input name="div1input"></input>
<a href="http://www.sogou.com">搜狗搜索</a>
<img alt="div1-img1" src="http://www.sogou.com/images/logo/new/sogou.png" href="http://www.sogou.com">搜狗图片</img>
<input type="button" name="查询"></>
</div>
<br>
<div name="div2">
<input name="div2input"></input>
<img alt="div2-img1" src="http://www.baidu.com/img/bdlogo.png" href="http://www.baidu.com">百度图片</img>
</div>
</body>
</html>
1.使用绝对路径来定位
在被测试网页中,查找第一个div标签中的按钮。
WebElement button=driver.findElement(By.xpath("/html/body/div/input[@value='查询']"));
使用绝对路径定位的好处在于可以验证网页结构是否发生变化。
2.使用相对路径来定位
在被测试网页中,查找第一个div标签中的按钮。
WebElement button=driver.findElement(By.xpath("//input[@value='查询']"));
表达式中的 // 表示在HTML文档的全部层级位置进行查找
input[@value='查询']表示定位显示“查询”两个字的按钮
3.使用索引号来定位
在被测试网页中,查找第二个div标签中的“查询”按钮。
WebElement button=driver.findElement(By.xpath("//input[2]"));
若在Firefox的Firepath插件中使用“//input[1]”,会发现被测试网页的两个输入框元素均被定位到,这和查找到第一个input元素的预期结果有所偏差。这是因为页面中含有两个div节点,每个div里面均包含input元素,XPath在查找的时候把每个div节点当做相同的起始层级开始查找,所以使用“//input[1]”表达式会同时查找到两个div节点中的第一个input元素。因此在使用序号进行页面定位元素的时候,需要注意网页HTML代码中是否包含多个层级完全相同的代码结构,若包含多个则会定位到多个页面元素。若想使用XPath表达式同时定位多个页面元素,并将定位到的多个元素存储到List对象中,可以参考
List<WebElement> inputs=driver.findElement(By.xpath("//input[1]"));
若页面元素经常被发现新增或减少的情况,不建议使用索引号定位的方式,因为页面变化很可能会让使用索引号的XPath表达式定位失败。
4.使用页面元素的属性值来定位
在定位页面元素时,会遇到各种复杂结构的网页,并且经常出现无法使用ID、name方式定位的情况。若不想使用绝对路径的定位方式,又不清楚用什么来定位,那么推荐使用属性值定位元素的方法。
WebElement img = driver.findElement(By.xpath("//img[@alt='div1-img1']"));
5.使用模糊的属性值来定位
页面元素的属性值会被动态地生成,即每次看到的页面元素值是不一样的,此类页面元素会加大定位难度,使用模糊的属性值定位方式可解决一部分此类难题。XPath函数可实现模糊属性值的定位需求
6.使用XPath的轴(Axis)来定位
使用XPath轴(Axis)方式可依据在文档树中的元素相对位置关系进行定位。先找到一个相对好定位的元素,依据它和要定位元素的相对位置进行定位,可解决一些元素难以定位的问题。
7.使用页面元素的文本来定位
使用text()函数可以定位到包含某些关键字的页面元素。
//查找包含“百度搜索”的链接页面元素,使用的是精确匹配
WebElement a = driver.findElement(By.xpath("//a[text()='百度搜索']"));
//搜索包含“百度”两个字的链接页面元素,实现了根据部分文字内容进行匹配
WebElement a = driver.findElement(By.xpath("//a[contains(text(),'百度')]"));
//在包含“百度”两个字的链接页面元素的前面查找div页面元素
WebElement div = driver.findElement(By.xpath("//a[contains(text(),'百度')]/preceding::div"));
8.XPath语法和CSS3语法的常用表达式比较
九、By jQuery
https://api.jquery.com/
十、表格的定位方法
<!DOCTYPE html>
<html>
<body>
<table width="400" border="1" id="table">
<tr>
<td align="left">消费项目....</th>
<td align="right">一月</th>
<td align="right">二月</th>
</tr>
<tr>
<td align="left">衣服</td>
<td align="right">1000元</td>
<td align="right">500元</td>
</tr>
<tr>
<td align="left">化妆品</td>
<td align="right">3000元</td>
<td align="right">500元</td>
</tr>
<tr>
<td align="left">食物</td>
<td align="right">3000元</td>
<td align="right">650.00元</td>
</tr>
<tr>
<td align="left">总计</th>
<td align="right">7000元</th>
<td align="right">1150元</th>
</tr>
</table>
</body>
</html>>
页面展现如图
1.遍历表格的全部单元格
@Test
public void LocateTable(){
//定位表格的页面元素对象
WebElement table = driver.findElement(By.id("table"));
//把所有tr元素对象存储到list对象中(即把表格中每行的对象存储到一个list中)
List<WebElement> rows = table.findElements(By.tagName("tr"));
assertEquals(5,rows.size());
//使用for循环将表格行对象从rows对象中取出,使用findElement将表格行对象中的所有单元格对象存储到名为cols的List对象中,然后再次使用for循环把每行的单元格文本遍历输出
for(WebElement row:rows){
List<WebElement> cols = row.findElements(By.tagName("td"));
for(WebElement col:cols){
//col.getText()表示获取单元格的文本内容
System.out.print(col.getText()+"\t");
}
System.out.println("");
}
}
2.定位表格中的某个单元格
//定位显示表格的第二行第二列单元格
WebElement cell = driver.findElement(By.xpath("//*[@id='table']/tbody/tr[2]/td[2]"));
表达式中的tr[2]表示第二行,td[2]表示第二列
3.定位表格中的子元素
代码略~~,页面展现如图
//定位到表格中第三行的第二个“面霜”复选框
WebElement cell = driver.findElement(By.xpath("//td[contains(text(),'化妆')]/input[2]"));
//td[contains(text(),'化妆')]表示模糊匹配到包含“化妆”关键字的单元格
/input[2]表示单元格里面的第二个input元素
也可以通过XPath的轴方式来查找:
//td[contains(text(),'化妆')]/descendant::input[2]