webdriver java。大型网络表,如何快速找到特定的价值

时间:2014-01-27 15:47:33

标签: java selenium

在一个非常大的网页表上,通常是数百行和多列,我们如何才能快速找到特定的值?理想情况下,我想指定列名,仅查找该列的单元格数据并检索指定的单元格值。

我的代码很慢,它从表中的所有单元格中获取所有数据,然后验证它们中的每一个以查找指定的值。这会花费相当多的时间。

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>

........

2 个答案:

答案 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);
}
}

希望这可以帮助你:)