Подтвердить что ты не робот

Selenium Webdriver - выборка данных таблицы

Я хочу получить данные из таблиц в пользовательском интерфейсе. Я знаю о циклическом перемещении по строкам и столбцам с использованием "tr" и "td". Но тот, который у меня есть, выглядит примерно так:

<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
 }
}
4b9b3361

Ответ 1

Вы можете искать всех дочерних элементов tr без различия между td и th. Поэтому вместо

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

Я бы использовал

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

Ответ 2

Майби слишком поздно для владельца этого вопроса, но полезно для других.

List<WebElement> 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() будет просто работать

Ответ 4

Вам не нужно перебирать элементы. Вместо этого используйте локатор 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.

Ответ 5

да, он работает на С# с селеном...

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

Ответ 6

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;
    }
}

Ответ 7

В приведенном ниже коде вы можете не только получить строки и столбцы таблицы, но также можете получить порядок, в котором они находятся в браузере, это в основном удобно, если у вас есть вложенные структуры в столбце 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;
        }