使用Selenium从表中注入行

时间:2017-04-20 12:06:53

标签: java html selenium optimization selenium-webdriver

我遇到了一个问题,它与Selenium webdriver的使用有关。 想象一下,我有一个HTML表,它有<head><body>,表体由200行组成。

我需要做的是将<th>中的每个<head>映射到与此tbody//tr//th对应的单元格列表(<th>)。

例如,如果我们有表:

<table>
    <head>
        <tr>
            <th>Title 1</th>
            <th>Title 2</th>
            <th>Title 3</th>
        </tr>
    </head>
    <body>
        <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
        </tr>
        <tr>...199 more such rows...</tr>
    </body>
</table>

我希望收到的结果是HashMap<WebElement, List<WebElement>>,其中key是列标题,value是与列索引对应的单元格列表(body//tr//td)。

我已经实现了这个,但是当表中有很多行时,我遇到了时间开销的问题。

以下是我如何做到这一点:

@FindBy(xpath = ".//table)
WebElement table;

@FindBy(xpath = ".//table//head")
WebElement tableHeader;

Map<WebElement, List<WebElement>> columnCells = new HashMap<>();
List<WebElement> tableTitles = tableHeader.findElements(By.xpath("./*"));
List<WebElement> tableRows = table.findElements(By.xpath(".//tbody/*"));

for (int i = 0; i < tableTitles.size(); i++) {
    WebElement columnTitle = tableTitles.get(i);
    List<WebElement> correspondingCells = new ArrayList<>();
    for (WebElement tableRow : tableRows) {
        List<WebElement> cells = tableRow.findElements(By.xpath("./*"));
        correspondingCells.add(cells.get(i));
    }
    columnCells.put(columnTitle, chosenCells);
}

正如我所提到的,如果表包含~200行,则此初始化大约需要15秒。问题出在第二个for循环中,因为访问WebDriver一次花费大约6-8毫秒。 有人可以帮我优化这个表的初始化吗?也许有一种方法根本不涉及WebDriver?

2 个答案:

答案 0 :(得分:1)

您可以使用索引通过xpath以更简单的方式执行此操作。

假设您在表格中N columns 200 plus rows

  1. 获取所有元素并准确设置for循环。

  2. 使用带有来自for循环的索引的xpath(比如说i)来获取所有td - driver.findElements(By.xpath("//table/tbody/tr/td[i+1]"));返回可以放入集合中的元素列表。

  3. 确保在查询之前执行加1逻辑,因为xpath索引从1开始。

答案 1 :(得分:1)

即使不关心它究竟是如何工作的,它几乎可以确定耗时的部分就是这条线

Map<WebElement, List<WebElement>> columnCells

你是否连续获得所有细胞并且除了一个之外扔掉所有细胞。切换循环肯定会快得多。您可以使用所有单元格并将它们分配到适当的列表中。

考虑从番石榴中用ListMultimap替换for (WebElement tableRow : tableRows) { List<WebElement> cells = tableRow.findElements(By.xpath("./*")); for (int i = 0; i < tableTitles.size(); i++) { columnCells.put(tableTitles.get(i), cells.get(i)); // using Multimap } } 。仅这一点无助于提高速度,但它使代码更简单。

Multimap使优化的循环比原始循环更短:

select a.id, a.name, b.id, b.name, c.id, c.name from A a, B b, C c 
where b.a=a and c.a=a