[基于Selenium2+Java的UI自动化(18)]-表格的处理

java

#1

表格对象,是一种很常见的对象,但是这个对象的数据并不固定,是一种动态对象,不同的查询条件,表格的行是动态的,对于表格对象来说,需要特殊处理。

一、表格在HTML中的表现

table: 表格的开始标签;
thead:表格的页眉
tbody:表格的主体
tr:行
td:列

因为表格的标签很特殊,那么在操作表格的单元格对象过程中,我们可以借助标签来操作,比直接定位更方便灵活。

二、操作表格

操作表格对象的步骤:
(1)获取表格对象------->将表格对象作为一个整体;
(2)根据表格对象,获取表格主体(tbody)对象-------->我们的需要的数据大多数都在tbody里边;
(3)根据tbody对象,获取行对象集合(可能存在多个行,所以行对象是一个集合)------->得到行对象;
(4)根据行对象,获取单元格对象集合(多个单元格)--------->获取单元格对象集合;
(5)根据单元格对象的下标,得到具体的单元格;

代码:

package com.automation.table;

import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

/**
 * 类说明:操作表格
 * <br/>
 * @version 1.0
 * 2016年12月7日 下午9:48:16
 */
public class Table {
	private static WebDriver driver = null ;
	private static String chromeDriverDir = "D:\\workspace\\A_Test\\resource\\chromedriver.exe";
	private static WebElement Table = null ;  //声明表格对象
	private static WebElement tBody = null;   //声明tbody对象
	private static List<WebElement> rows = null;    //声明行对象集合
	private static List<WebElement> cells = null;    //声明单元格对象集合
	
	/**
	 * 1.打开网页;
	 */
	public static void openBrowser(){
		System.setProperty("webdriver.chrome.driver", chromeDriverDir);
		driver = new ChromeDriver();
		driver.manage().window().maximize();
		driver.get("file:///C:/Users/Administrator/Desktop/table.html");
	}
	
	/**
	 * 2.得到表格对象
	 */
	public static void getTable(){
		Table = driver.findElement(By.tagName("table"));
	}
	
	/**
	 * 3.根据表格对象,找到子对象tbody
	 */
	public static void getTbody(){
		getTable();
		tBody = Table.findElement(By.tagName("tbody"));
	}
	
	/**
	 * 4. 根据tbody对象,得到所有的行对象集合;
	 */
	public static void getRows(){
		getTbody();
		rows = tBody.findElements(By.tagName("tr"));
	}
	
	/**
	 * 5.获取 行对象的 行数;
	 */
	public static int getRowCount(){
		getTbody();
		return rows.size();
	}
	
	/**
	 * 根据单元格的行号、列号,得到具体的单元格对象;
	 * @param rowNum 从0开始,0代表第一行
	 * @param colNum 从0开始,0代表第一列
	 */
	public static WebElement getCell(int rowNum, int colNum){
		getRows();
		WebElement specificRow = rows.get(rowNum); //根据行下标获取具体的行;
		cells = specificRow.findElements(By.tagName("td")); //根据行,找到所有的列对象集合
		return cells.get(colNum); //根据列号,得到具体的单元格;
	}
	
	/**
	 * 获取指定单元格的内容;
	 * @param cell
	 * @return
	 */
	public static String getCellData(WebElement cell){
		return cell.getText();
	}
	
	public static void main(String[] args){
		openBrowser();
		WebElement cell = getCell(0, 0);
		String cellData = getCellData(cell);
		System.out.println("单元格:第一行、第一列的值为——————>" + cellData);
	}
}

执行结果:

操作表格,只需要得到表格对象就可以了,剩下的就根据标签,一步一步缩小对象:

得到表格对象
---->得到tbody对象
---->得到行对象集合
---->遍历集合,得到具体行对象
---->得到列对象集合
---->遍历列对象集合,根据下标,得到具体的单元格
---->操作单元格对象:获取值、点击等等。

在实际项目中,不同的查询条件,得到的数据也不一样,行数不一样,那么使用以前的定位方式,就不合适了;而采用这种方式,一步一步向下定位,更加灵活;

建议将操作表格的类,封装为一个公共类,以后所有的表格,都能使用。


(無悠) #2

赞一个,:+1:这个稍微好理解一些!:smiley:


(Mr.G) #3

突然醒悟,这样可以获得表格的行数。差点用JS获取行数
List rows = tBody.findElements(By.tagName(“tr”));
rows.size();


(书生) #4

我想问一下如果查询记录很多被分页了这样也行吗?


#5

对于分页的数据,这样是不可以获取其他页的数据,建议先获取页数,然后翻页后再次遍历;


#6

是的,对于处理动态表格来说,行数很重要;
不过我现在遇到麻烦了,对于表格内部嵌套表格怎么处理,你有研究吗?可以讨论一下;


(Mr.G) #7

类似下面这种嵌套?

test
姓名 性别 年龄 职业
张三 20 歌手
李四 25 编辑
张三 20 演员
姓名 性别 年龄 职业
小俊 30 经理
小刘 22 销售
小王 25 司机
小欣 18 文员

对应代码,先获取到table内嵌table的对象,再获取tr对象集合。或者先获取外层table再获内嵌table对象集合一层一层处理。
package com.automation.testng;

import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class Test {
public static void main(String[] args) {
FirefoxDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.get(“file:///D:/table.html”);

	//获取表格主体对象
	WebElement Table_1 = driver.findElement(By.id("table_1"));
	//获取行对象集合
	List<WebElement> rows_1 = Table_1.findElements(By.tagName("tr"));
	//获取行对象的行数;
	System.out.println(rows_1.size());
	
	//获取表格主体对象
	WebElement Table_2 = driver.findElement(By.id("table_2"));
	//获取行对象集合
	List<WebElement> rows_2 = Table_2.findElements(By.tagName("tr"));
	//获取行对象的行数;
	System.out.println(rows_2.size());

}
}


(Mr.G) #9

HTML代码,刚代码直接被编译了:joy:


<!DOCTYPE HTML>
<html>
<head>
	<meta charset="utf-8">
	<title>test</title>
</head>
<body>
	<table>
		<tbody>
			<tr>
				<table id="table_1" border="1">
					<thead>
						<tr>
							<td>姓名</td>
							<td>性别</td>
							<td>年龄</td>
							<td>职业</td>
						</tr>
					</thead>
					<tbody>
						<tr>
							<td>张三</td>
							<td>男</td>
							<td>20</td>
							<td>歌手</td>
						</tr>
						<tr>
							<td>李四</td>
							<td>男</td>
							<td>25</td>
							<td>编辑</td>
						</tr>
						<tr>
							<td>张三</td>
							<td>女</td>
							<td>20</td>
							<td>演员</td>
						</tr>
					</tbody>
				</table>
			</tr>
			<tr>
				<table id="table_2" border="1">
					<thead>
						<tr>
							<td>姓名</td>
							<td>性别</td>
							<td>年龄</td>
							<td>职业</td>
						</tr>
					</thead>
					<tbody>
						<tr>
							<td>小俊</td>
							<td>男</td>
							<td>30</td>
							<td>经理</td>
						</tr>
						<tr>
							<td>小刘</td>
							<td>男</td>
							<td>22</td>
							<td>销售</td>
						</tr>
						<tr>
							<td>小王</td>
							<td>男</td>
							<td>25</td>
							<td>司机</td>
						</tr>
						<tr>
							<td>小欣</td>
							<td>女</td>
							<td>18</td>
							<td>文员</td>
						</tr>
					</tbody>
				</table>
			</tr>
		</tbody>
	</table>

</body>
</html>

#10

我目前也是这么处理的,先找到外层table,然后找内层table,不过感觉好麻烦,因为外层/内层table都是动态的,而且所有的table没有id属性,name也是相同的,晕了!:unamused:

不过找不到更好的方式之前,先这样弄吧。。。


(冰河) #11

本主题现在是横幅主题。它将出现在每页的顶部,除非用户将其隐藏。


(冰河) #12

本主题已经不再是横幅主题。它将不在每个页面的顶部显示。


(冰河) #13

(西蜀风云) #14

楼主 感觉你有很长时间没更新java自动化的blog了,期待你的新文章:grinning::grinning:


#15

好的,感谢提醒,一定把后续的补起来