如何在Selenium webdriver中选择所有列的第一个单元格(tds)?

Dav*_*ave 5 selenium xpath webdriver

我正在使用Selenium 2.12.使用WebDriver API,假设我有一个表示table(<table>)的WebElement .使用该元素,如何选择第一列中的所有td?我假设这里有一个xpath表达式.

为了更好地理解表结构,如果我从tableElement WebElement获取HTML ...

String html = (String)((JavascriptExecutor)driver).executeScript("return arguments[0].innerHTML;", tableElt); 
Run Code Online (Sandbox Code Playgroud)

我得到了下面的混乱.需要注意的关键是有6个tr和16个td ......

<thead><tr><th colspan="1" class="GCSPOWVGE GCSPOWVEE GCSPOWVEF GCSPOWVFF"><div style="padding-left: 17px;position:relative;zoom:1;"><div style="left:0px;margin-top:-4px;position:absolute;top:50%;line-height:0px;"><img onload='this.__gwtLastUnhandledEvent="load";' src="http://localhost:9080/cme-productplus-web/productplus/clear.cache.gif" style="width: 11px; height: 7px; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAHCAYAAADebrddAAAAiklEQVR42mNgwALyKrumFRf3iDAQAvmVXVVAxf/zKjq341WYV95hk1fZ+R+MK8C4HqtCkLW5FZ2PQYpyK6AaKjv/5VV1OmIozq3s3AFR0AXFUNMrO5/lV7WKI6yv6mxCksSGDyTU13Mw5JV2qeaWd54FWn0BRAMlLgPZl/NAuBKMz+dWdF0H2hwCAPwcZIjfOFLHAAAAAElFTkSuQmCC) no-repeat 0px 0px;" border="0"></div><div>GUID</div></div></th><th colspan="1" class="GCSPOWVGE GCSPOWVEF">Fung Ratio</th><th colspan="1" class="GCSPOWVGE GCSPOWVEF">Fung type</th><th colspan="1" class="GCSPOWVGE GCSPOWVEF">Fung Date Offset</th><th colspan="1" class="GCSPOWVGE GCSPOWVEF  GCSPOWVOE">Days To Retain</th></tr></thead><colgroup><col><col><col><col><col></colgroup><tbody><tr onclick="" class="GCSPOWVAE"><td class="GCSPOWVPD GCSPOWVBE GCSPOWVCE"><div style="outline:none;" tabindex="0">      DSSUAQR6IE6E    </div></td><td class="GCSPOWVPD GCSPOWVBE"><div style="outline:none;">      10      </div></td><td class="GCSPOWVPD GCSPOWVBE"><div style="outline:none;">              </div></td><td class="GCSPOWVPD GCSPOWVBE"><div style="outline:none;">      </div></td><td class="GCSPOWVPD GCSPOWVBE GCSPOWVME"><div style="outline:none;">            </div></td></tr><tr onclick="" class="GCSPOWVAF"><td class="GCSPOWVPD GCSPOWVBF GCSPOWVCE"><div style="outline:none;">      ETTUAQR6IE6E    </div></td><td class="GCSPOWVPD GCSPOWVBF"><div style="outline:none;">      30      </div></td><td class="GCSPOWVPD GCSPOWVBF"><div style="outline:none;">              </div></td><td class="GCSPOWVPD GCSPOWVBF"><div style="outline:none;">      </div></td><td class="GCSPOWVPD GCSPOWVBF GCSPOWVME"><div style="outline:none;">            </div></td></tr><tr onclick="" class="GCSPOWVAE"><td class="GCSPOWVPD GCSPOWVBE GCSPOWVCE"><div style="outline:none;">      FCCUAQR6IE6E    </div></td><td class="GCSPOWVPD GCSPOWVBE"><div style="outline:none;">      20      </div></td><td class="GCSPOWVPD GCSPOWVBE"><div style="outline:none;">              </div></td><td class="GCSPOWVPD GCSPOWVBE"><div style="outline:none;">      </div></td><td class="GCSPOWVPD GCSPOWVBE GCSPOWVME"><div style="outline:none;">            </div></td></tr></tbody><tbody style="display: none;"><tr><td colspan="5" align="center"><div><div style="width: 100%; height: 100%; padding: 0px; margin: 0px; display: none;"><div style="width: 100%; height: 100%; display: none;"></div></div><div style="width: 100%; height: 100%; padding: 0px; margin: 0px; display: none;"><div class="GCSPOWVPE" style="width: 100%; height: 100%; display: none;"><img class="gwt-Image" onload='this.__gwtLastUnhandledEvent="load";' src="http://localhost:9080/cme-productplus-web/productplus/clear.cache.gif" style="width: 43px; height: 11px; background: url(data:image/gif;base64,R0lGODlhKwALAPEAAP///0tKSqampktKSiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAKwALAAACMoSOCMuW2diD88UKG95W88uF4DaGWFmhZid93pq+pwxnLUnXh8ou+sSz+T64oCAyTBUAACH5BAkKAAAALAAAAAArAAsAAAI9xI4IyyAPYWOxmoTHrHzzmGHe94xkmJifyqFKQ0pwLLgHa82xrekkDrIBZRQab1jyfY7KTtPimixiUsevAAAh+QQJCgAAACwAAAAAKwALAAACPYSOCMswD2FjqZpqW9xv4g8KE7d54XmMpNSgqLoOpgvC60xjNonnyc7p+VKamKw1zDCMR8rp8pksYlKorgAAIfkECQoAAAAsAAAAACsACwAAAkCEjgjLltnYmJS6Bxt+sfq5ZUyoNJ9HHlEqdCfFrqn7DrE2m7Wdj/2y45FkQ13t5itKdshFExC8YCLOEBX6AhQAADsAAAAAAAAAAAA=) no-repeat 0px 0px;" border="0"></div></div></div></td></tr></tbody><tfoot style="display: none;"><tr><th colspan="5" class="GCSPOWVFE GCSPOWVDE  GCSPOWVNE"></th></tr></tfoot>
Run Code Online (Sandbox Code Playgroud)

可悲的是,这两种表达方式都没有产生正确的结果.

        // This returns zero td's
        final List<WebElement> tds = tableElt.findElements(By.xpath("/tr/td[1]"));

        ...

        // This returns 238 td's (I think that's everything in my document)
        final List<WebElement> tds = tableElt.findElements(By.xpath("//td[1]"));
Run Code Online (Sandbox Code Playgroud)

Dim*_*hev 6

    // This returns 238 td's (I think that's everything in my document)               
    final List<WebElement> tds = tableElt.findElements(By.xpath("//td[1]"));
Run Code Online (Sandbox Code Playgroud)

这与XPath W3c规范完全一致,是XPath中最常见的FAQ之一.

//伪运算符的优先级(优先级)小于运算符的优先级[].

因此,//SomeName[1]选择所有名称为其父级SomeName的第一SomeName个子元素的元素- 并且可能存在许多此类元素.

如果要SomeName在XML文档中选择第一个元素,则需要使用括号显式覆盖默认运算符优先级:

(//SomeName)[1]
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您只需td要给定元素的第一个后代 - 因此除了上述更正之外,您必须将表达式更正为相对 - 而不是绝对.绝对XPath表达式(/始终评估为具有文档节点的aditional context节点).

用途:

(.//td)[1]
Run Code Online (Sandbox Code Playgroud)

如果需要td选择当前节点的所有后代,请使用:

.//td
Run Code Online (Sandbox Code Playgroud)

甚至更好:

.//descendant::td
Run Code Online (Sandbox Code Playgroud)


Way*_*ett 5

使用的确切表达式取决于文档的实际结构。

在最一般的情况下——从表中选择所有第一列单元格——您可以使用以下表达式:

<path_to_table>//td[1]
Run Code Online (Sandbox Code Playgroud)

例如,在本文档中:

<table>
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
    </tr>
    <tr>
        <td>a</td>
        <td>b</td>
        <td>c</td>
        <td>d</td>
    </tr>
    <tr>
        <td>i</td>
        <td>ii</td>
        <td>iii</td>
        <td>iv</td>
    </tr>
</table>
Run Code Online (Sandbox Code Playgroud)

这个表达式:

/table//td[1]
Run Code Online (Sandbox Code Playgroud)

给出:

<td>1</td>
<td>a</td>
<td>i</td>
Run Code Online (Sandbox Code Playgroud)

请注意,我使用的是后代或自身轴 ( //),因为 HTML 表允许可选的分组元素(例如<tbody>),这些元素可能存在也可能不存在。但是,这也将包括嵌套表中的第一列单元格。考虑这个输入:

<table>
    <tr>
        <td>1</td>
        <td><table><td>test</td></table></td>
        <td>3</td>
        <td>4</td>
    </tr>
    <tr>
        <td>a</td>
        <td>b</td>
        <td>c</td>
        <td>d</td>
    </tr>
    <tr>
        <td>i</td>
        <td>ii</td>
        <td>iii</td>
        <td>iv</td>
    </tr>
</table>
Run Code Online (Sandbox Code Playgroud)

与上面相同的表达式返回:

<td>1</td>
<td>test</td>
<td>a</td>
<td>i</td>
Run Code Online (Sandbox Code Playgroud)

如果您对具体的表结构了解更多,那么您可以编写更具体的表达式。例如,对于先前的输入,此表达式:

/table/tr/td[1]
Run Code Online (Sandbox Code Playgroud)

...仅返回最外层表格中的单元格:

<td>1</td>
<td>a</td>
<td>i</td>
Run Code Online (Sandbox Code Playgroud)