2012-05-17 212 views
12

我想從UI中的表格中獲取數據。我知道使用「tr」和「td」循環遍歷行和列。但是,我有表是這樣的:Selenium Webdriver - 獲取表格數據

<table> 
<tbody> 
    <tr><td>data</td><th>data</th><td>data</td><td>data</td></tr> 
    <tr><td>data</td><th>data</th><td>data</td><td>data</td></tr> 
    <tr><td>data</td><th>data</th><td>data</td><td>data</td></tr> 
</tbody> 
</table> 

我怎樣才能讓我的代碼一般,讓「TH」在中間發生可以處理。 目前,我使用此代碼:

// Grab the table 
WebElement table = driver.findElement(By.id(searchResultsGrid)); 

// Now get all the TR elements from the table 
List<WebElement> allRows = table.findElements(By.tagName("tr")); 
// And iterate over them, getting the cells 
for (WebElement row : allRows) { 
List<WebElement> cells = row.findElements(By.tagName("td")); 
for (WebElement cell : cells) { 
// And so on 
} 
} 

回答

14

你可以尋找tr元素的所有兒童沒有td和th區分。因此,而不是

List<WebElement> cells = row.findElements(By.tagName("td")); 

我會用

List<WebElement> cells = row.findElements(By.xpath("./*")); 
8

Mayby爲時已晚了這一問題的所有者,但對於其他的幫助。

List<WebElement> cells = row.findElements(By.xpath(".//*[local-name(.)='th' or local-name(.)='td']")); 
0

是,它正在爲C#與硒...

IList<IWebElement> cells = row.findElements(By.xpath(".//*[local-name(.)='th' or local-name(.)='td']")); 
3
// Grab the table 
WebElement table = driver.findElement(By.id("searchResultsGrid")); 

// Now get all the TR elements from the table 
List<WebElement> allRows = table.findElements(By.tagName("tr")); 
// And iterate over them, getting the cells 
for (WebElement row : allRows) { 
    List<WebElement> cells = row.findElements(By.tagName("td")); 
    for (WebElement cell : cells) { 
     System.out.println("content >> " + cell.getText()); 
    } 
} 

使用cell.getText()只會工作

0
IWebElement table = driver.FindElement(By.Id("id")); 
List<IWebElement> allRows = new List<IWebElement> (table.FindElements(By.TagName("tr"))); 

foreach (var Row in allRows) 
{ 
    List<IWebElement> cells = new List<IWebElement>(Row.FindElements(By.TagName("td"))); 
    foreach (var cel in cells) 
    { 
     string test = cel.Text; 
    } 
} 
+0

它在C# –

2

你不通過元素需要循環。相反,使用ByChained定位器。

如果你的表是這樣的:

<table> 
    <tbody> 
    <tr><th>Col1</th><th>Col2</th><th>Col3</th></tr> 
    <tr><td>data</td><td>data</td><td>data</td></tr> 
    <tr><td>data</td><td>data</td><td>data</td></tr> 
    <tr><td>data</td><td>data</td><td>data</td></tr> 
    </tbody> 
</table> 

的定位是這樣的:

By tableBodyLocator = By.xpath(".//table/tbody"); 
By headerRowLocator = By.xpath(".//tr[position()=1]"); 
By dataRowsLocator = By.xpath(".//tr[not(position()=1)]"); 

By headerRowLocator = new ByChained(tableBodyLocator, headerRowLocator); 
List<WebElement> weHeaders = driver.findElement(headerRowLocator) 
     .findElements(By.xpath(".//th"); 
List<WebElement> allRowData = driver.findElements(tableBodyLocator, dataRowsLocator); 

WebElement row1Data = allRowData.get(0); 
WebElement row2Data = allRowData.get(1); 

etc. 
0

下面的代碼,你不僅可以得到表格的行和列,但你也可以得到它們在瀏覽器中的順序,如果你在TD列中有一個嵌套結構,那麼這很方便。

public DataTable StoreHtmlTableToDataTable(IWebElement tblObj,bool isFirstRowHeader = true) 
     { 
      DataTable dataTbl = new DataTable(); 
      int rowIndex = 0; 

      try 
      {    
       //_tblDataCollection = new List<TableDataCollection>(); 

       var tblRows = ((IJavaScriptExecutor)DriverContext.Driver).ExecuteScript("return arguments[0].rows; ", tblObj); 

       if (tblRows != null) 
       { 
        //Iterate through each row of the table 
        foreach (IWebElement tr in (IEnumerable)tblRows) 
        {       
         int colIndx = 0; 
         DataRow dtRow = dataTbl.NewRow(); 
         // Iterate through each cell of the table row 
         var tblCols = ((IJavaScriptExecutor)DriverContext.Driver).ExecuteScript("return arguments[0].cells; ", tr); 
         foreach (IWebElement td in (IEnumerable)tblCols) 
         { 
          //add the header row of the table as the datatable column hader row 
          if (rowIndex == 0) 
          { 
           dataTbl.Columns.Add("Col" + colIndx.ToString(), typeof(string)); 
          } 

          dtRow["Col"+colIndx.ToString()] = td.Text; 

          //loop through any child or nested table structures if you want using the same approach for example links,radio buttons etc inside the cell 

          //Write Table to List : This part is not done yet       
          colIndx++; 
         } 
         dataTbl.Rows.Add(dtRow); 
         rowIndex++; 
        } 

       } 


      } 
      catch (Exception) 
      { 
       throw; 
      } 

      //if first row is the header row then assign it as a header of the datatable 
      if (isFirstRowHeader) 
      { 
       dataTbl = this.AssignDataTableHeader(dataTbl); 
      } 

      return dataTbl; 
     } 
相關問題