在一个非常大的网页表上,通常是数百行和多列,我们如何才能快速找到特定的值?理想情况下,我想指定列名,仅查找该列的单元格数据并检索指定的单元格值。
我的代码很慢,它从表中的所有单元格中获取所有数据,然后验证它们中的每一个以查找指定的值。这会花费相当多的时间。
public static void selectColumnValue(String tableXpath, String columnValue){
String str, found = "false";
// String colValue = null;
WebElement table = driver.findElement(By.xpath(tableXpath));
List<WebElement> rows=table.findElements(By.xpath(tableXpath+"/tbody/tr"));
for(WebElement row:rows)
{
List<WebElement> cols =row.findElements(By.xpath("td"));
for(WebElement col:cols)
{
str=col.getText().trim();
//System.out.println(str);
if(str.matches(columnValue))
{
//List<WebElement> vals=row.findElements(By.xpath("td"));
col.click();
found="true";
}
}
if(found.matches("true")){
break;
} } }
几行的HTML如下:
<table id="T536870949" class="BaseTable" title="" style="top: 16px;">
<colgroup cols="5">
<col style="width: 139px;"/>
<col style="width: 140px;"/>
<col style="width: 139px;"/>
<col style="width: 140px;"/>
<col style="width: 119px;"/>
</colgroup>
<tbody>
<tr class="hiddentablehdr">
<th scope="col">Device Name</th>
<th scope="col">Site ID</th>
<th scope="col">Monitoring SSA</th>
<th scope="col">Manufacturer</th>
<th scope="col">Model</th>
</tr>
<tr class="" arrow="0" tabindex="0">
<td class="BaseTableCellOdd BaseTableCellOddColor BaseTableStaticText" scope="row" style="width: 139px;" title="001000">
<nobr class="dp " style="text-align: right; width: 139px;">
</td>
<td class="BaseTableCellOdd BaseTableCellOddColor BaseTableStaticText" style="width: 140px;">
<nobr class="dp " style="text-align: right; width: 140px;">
<span style="float:left;">NTA001</span>
</nobr>
</td>
<td class="BaseTableCellOdd BaseTableCellOddColor BaseTableStaticText" style="width: 139px;" title="0019839">
<nobr class="dp " style="text-align: right; width: 139px;">
<span style="float:left;">0019839</span>
</nobr>
</td>
<td class="BaseTableCellOdd BaseTableCellOddColor BaseTableStaticText" style="width: 140px;">
<nobr class="dp " style="text-align: right; width: 140px;">
<span style="float:left;">unknown</span>
</nobr>
</td>
<td class="BaseTableCellOdd BaseTableCellOddColor BaseTableStaticText" style="width: 119px;">
</tr>
<tr class="" arrow="1" tabindex="0">
<td class="BaseTableCell BaseTableCellColor BaseTableStaticText" scope="row" style="width: 139px;" title="001001">
<nobr class="dp " style="text-align: right; width: 139px;">
<span style="float:left;">001001</span>
</nobr>
</td>
<td class="BaseTableCell BaseTableCellColor BaseTableStaticText" style="width: 140px;" title="001">
<nobr class="dp " style="text-align: right; width: 140px;">
<span style="float:left;">001</span>
</nobr>
</td>
<td class="BaseTableCell BaseTableCellColor BaseTableStaticText" style="width: 139px;" title="0019839">
<nobr class="dp " style="text-align: right; width: 139px;">
<span style="float:left;">0019839</span>
</nobr>
</td>
<td class="BaseTableCell BaseTableCellColor BaseTableStaticText" style="width: 140px;">
<nobr class="dp " style="text-align: right; width: 140px;">
<span style="float:left;">DMI</span>
</nobr>
</td>
<td class="BaseTableCell BaseTableCellColor BaseTableStaticText" style="width: 119px;">
<nobr class="dp " style="text-align: right; width: 119px;">
<span style="float:left;">Manufacturer=xyz</span>
</nobr>
</td>
</tr>
........
答案 0 :(得分:1)
您可以搜索您感兴趣的元素的完整xpath,而不是循环所有元素,例如:
String searchedXpath = tableXpath + "/tbody/tr/td[span='" + columnValue + "']/span";
try {
WebElement col = driver.findElement(By.xpath(searchedXpath ));
System.out.println("Value Found: " + col.getText());
}
catch (NoSuchElementException e) {
System.out.println("No such value in the table");
}
当然条件[span ='“+ columnValue +”']可以调整为你认为正确的(例如[contains(span,columnValue)])
答案 1 :(得分:0)
我不知道这会加快你的代码的数量(如果有的话),但是我已根据你的理想要求完全编写它,你可以给出列名并从该列中检索数据。我把它写在w3school上的一张桌子上。你可以为你的桌子改变它。
public class SimpleTests {
public static WebDriver driver;
public static String implicitwait="1";
public static void main(String[] args) {
openBrowser();
navigate("http://www.w3schools.com/html/html_tables.asp");
String columnValue = "94";
int columIndex = columnNum("Points"); // get column index.
int numOfRow = driver.findElements(By.xpath("//tbody/tr")).size(); // get total number of rows
boolean found = false;
//for each row starting from 2nd, check your column for desired value.
int i=2;
for(;i<numOfRow;i++){
WebElement columVals = driver.findElement(By.xpath("//tbody/tr["+i+"]/td["+columIndex+"]"));
String tmp = columVals.getText();
if (tmp.equals(columnValue)){
found = true;
break;
}
}
System.out.println("Element found: "+found+" > with xpath: "+"//tbody/tr["+i+"]/td["+columIndex+"]");
driver.quit();
}
public static int columnNum (String column){
column = "Points";
List<WebElement> FstRow = driver.findElements(By.xpath("//tbody/tr[1]/th"));
int i = 1;
for(WebElement element : FstRow){
String tmp = element.getText();
if (!tmp.equals(column)){
i++;
}
else{
break;
}
}
return i;
}
public static void openBrowser(){
System.setProperty("webdriver.firefox.bin", "C:/Program Files (x86)/Mozilla Firefox/FF16/firefox.exe");
FirefoxProfile firefoxProfile = new FirefoxProfile();
firefoxProfile.setPreference("capability.policy.default.Window.QueryInterface", "allAccess");
firefoxProfile.setPreference("capability.policy.default.Window.frameElement.get","allAccess");
driver = new FirefoxDriver(firefoxProfile);
driver.manage().window().maximize();
long implicitWaitTime=Long.parseLong(implicitwait);
driver.manage().timeouts().implicitlyWait(implicitWaitTime, TimeUnit.SECONDS);
}
public static void navigate(String mmpUrl){
driver.navigate().to(mmpUrl);
}
}
希望这可以帮助你:)