Java 使用硒访问 <td> 值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18581522/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
accessing <td> value with selenium
提问by killernerd
Using selenium i'm trying to read out a dynamically generated table, i got down to the right elements (using the findElement
method) but using getText()
on them returns nothing.
使用 selenium 我试图读出一个动态生成的表,我得到了正确的元素(使用该findElement
方法),但getText()
在它们上使用什么都不返回。
Probably because getText()
looks for quotation marks when returning "text" and can't find any between the <td>
tags. Some suggestions were to use xpaths but since the tables are generated dynamically the location of the value i need also changes.
可能是因为getText()
在返回“text”时查找引号,并且在<td>
标签之间找不到任何引号。一些建议是使用 xpaths,但由于表是动态生成的,因此我需要的值的位置也会发生变化。
here's the table i'm trying to get 3 data points from:
这是我试图从中获取 3 个数据点的表格:
<table cellpadding="0" cellspacing="0" class="fleetinfo">
<tbody><tr>
<th colspan="2">Schepen:</th>
</tr>
<tr>
<td>Groot vrachtschip:</td>
<td class="value">
40 </td>
</tr>
<tr>
<td colspan="2"> </td>
</tr>
<tr>
<th colspan="2">Lading:</th>
</tr>
<tr>
<td>Metaal:</td>
<td class="value">
536.062 </td>
</tr>
<tr>
<td>Kristal:</td>
<td class="value">
289.008 </td>
</tr>
<tr>
<td>Deuterium:</td>
<td class="value">
92.750 </td>
</tr>
</tbody></table>
the ones i'm interested in are the ones inside the <td class="value">
tags but as i said before, using getText()
on them returns null.
我感兴趣的是<td class="value">
标签内的那些,但正如我之前所说,getText()
对它们使用返回空值。
Any idea on how i can acces those values?
关于如何访问这些值的任何想法?
edit: here's how i'm doing it now
编辑:这就是我现在的做法
private int getMetalFromFleet(WebElement fleet)
{
int ret=0;
WebElement streak = fleet.findElement(By.className("starStreak"));
List<WebElement>fleetDetails = streak.findElements(By.tagName("tr"));
for(WebElement detail : fleetDetails)
{
List<WebElement> tabel = detail.findElements(By.tagName("td"));
if(tabel.size() != 2)
continue;
if(tabel.get(0).getText().equalsIgnoreCase("metaal:"))
{
ret = Integer.parseInt(tabel.get(1).getText());
break;
}
}
return ret;
}
edit: here's the relevant bit of html
编辑:这是html的相关位
<div id="fleet9965869" class="fleetDetails detailsOpened" data-mission-type="4" data-return-flight="false" data-arrival-time="1378241688">
<span class="timer tooltip" title="03.09.2013 22:54:48" id="timer_9965869">58m 48s</span>
<span class="absTime">22:54:48 Klok</span>
<span class="mission neutral textBeefy">Plaatsen</span>
<span class="allianceName"></span>
<span class="originData">
<span class="originCoords tooltip" title="killernerd"><a href="http://uni107.ogame.nl/game/index.php?page=galaxy&galaxy=5&system=213">[5:213:8]</a></span>
<span class="originPlanet">
<figure class="planetIcon planet tooltip js_hideTipOnMobile" title="planeet"></figure>k7 </span>
</span>
<span class="marker01"></span>
<span class="marker02"></span>
<span class="fleetDetailButton">
<a href="#bl9965869" rel="bl9965869" title="Vlootdetails" class="tooltipRel tooltipClose fleet_icon_forward">
</a>
</span>
<span class="reversal reversal_time" ref="9965869">
<a class="icon_link tooltipHTML" href="http://uni107.ogame.nl/game/index.php?page=movement&return=9965869" title="Roep terug:| 04.09.2013<br>01:54:05">
<img src="http://gf2.geo.gfsrv.net/cdna2/89624964d4b06356842188dba05b1b.gif" height="16" width="16">
</a>
</span>
<span class="starStreak">
<div style="position: relative;">
<div class="origin fixed">
<img class="tooltipHTML" height="30" width="30" src="http://gf1.geo.gfsrv.net/cdnf0/af41c52dc08208b4463f4a4608e88c.png" title="" alt="">
</div>
<div class="route fixed">
<a href="#bl9965869" rel="bl9965869" title="Vlootdetails" class="tooltipRel tooltipClose basic2 fleet_icon_forward" id="route_9965869" style="margin-left: 220px;"></a>
<div style="display:none;" id="bl9965869">
<div class="htmlTooltip">
<h1>Vlootdetails:</h1>
<div class="splitLine"></div>
<table cellpadding="0" cellspacing="0" class="fleetinfo">
<tbody><tr>
<th colspan="2">Schepen:</th>
</tr>
<tr>
<td>Groot vrachtschip:</td>
<td class="value">
960 </td>
</tr>
<tr>
<td colspan="2"> </td>
</tr>
<tr>
<th colspan="2">Lading:</th>
</tr>
<tr>
<td>Metaal:</td>
<td class="value">
8.173.484 </td>
</tr>
<tr>
<td>Kristal:</td>
<td class="value">
6.325.966 </td>
</tr>
<tr>
<td>Deuterium:</td>
<td class="value">
7.474.821 </td>
</tr>
</tbody></table>
</div> </div>
</div>
<div class="destination fixed">
<img class="tooltipHTML" height="30" width="30" src="http://gf2.geo.gfsrv.net/cdnaa/af0b356fdbecc1cfc47130e990fa66.png" title="Aankomsttijd:| 03.09.2013<br>22:54:48" alt="">
</div>
</div>
</span><!-- Starstreak -->
<span class="destinationData">
<span class="destinationPlanet">
<span>
<figure class="planetIcon planet tooltip js_hideTipOnMobile" title="planeet"></figure>Hoelbrak </span>
</span>
<span class="destinationCoords tooltip" title="killernerd"><a href="http://uni107.ogame.nl/game/index.php?page=galaxy&galaxy=1&system=2">[1:2:6]</a></span>
</span>
<span class="nextTimer tooltip" title="04.09.2013 03:52:31" id="timerNext_9965869">5u 56m 31s</span>
<span class="nextabsTime">03:52:31 Klok</span>
<span class="nextMission friendly textBeefy">Keer terug</span>
<span class="openDetails">
<a href="javascript:void(0);" class="openCloseDetails" data-mission-id="9965869" data-end-time="1378241688">
<img src="http://gf3.geo.gfsrv.net/cdnb6/577565fadab7780b0997a76d0dca9b.gif" height="16" width="16">
</a>
</span>
</div>
the values i need are the numeric values under "Metaal", "kristal" and "deuterium".
我需要的值是“Metaal”、“kristal”和“deuterium”下的数值。
采纳答案by killernerd
I found some kind of an answer after digging through a ton of programming sites.
Apparently items that have the style="display:none";
flag set like this will be seen as "hidden" by selenium.
在挖掘了大量编程站点后,我找到了某种答案。显然,具有style="display:none";
像这样设置标志的项目将被硒视为“隐藏”。
This is, unfortunately, a feature and not a bug of some sort as selenium "tries to emulate the user" and will therefore hide information that is not explicitely visible.
不幸的是,这是一个功能而不是某种错误,因为 selenium “试图模拟使用r”,因此将隐藏不明确可见的信息。
"The user can't see it so neither can selenium" is their thought progress.
“用户看不到它,硒也看不到”是他们的思想进步。
Here is the source.
这是来源。
This, unfortunately, does not solve my issue. I can however try to get around this, I'll report back my findings.
不幸的是,这并不能解决我的问题。然而,我可以尝试解决这个问题,我会报告我的发现。
EDIT: It's amusing how different HtmlUnitDriver is from FirefoxDriver. One thing that works on HtmlUnitDriver won't work on FirefoxDriver and vice versa.
编辑:HtmlUnitDriver 与 FirefoxDriver 的不同很有趣。在 HtmlUnitDriver 上工作的一件事在 FirefoxDriver 上不起作用,反之亦然。
EDIT-2: Found a solution! Finally.
EDIT-2:找到解决方案!最后。
Using selenium's JavascriptExecutor
I can directly get the innerHTML from the found element like so:
使用 selenium,JavascriptExecutor
我可以直接从找到的元素中获取 innerHTML,如下所示:
By identifier = By.xpath("*[contains(@class,'starStreak')]//td[contains(text(),'Metaal:')]/following-sibling::td[contains(@class,'value')]");
String script = "return arguments[0].innerHTML";
String outcome = (String) ((JavascriptExecutor) driver).executeScript(script, fleet.findElement(identifier));
It's still annoying as hell that you can't just use getText()
though. It should at least be an option.
尽管如此,它仍然很烦人,你不能只使用getText()
它。它至少应该是一种选择。
回答by Robbie Wareham
I would recommend using xpath in this scenario rather then relying on tagnames;
我建议在这种情况下使用 xpath 而不是依赖标记名;
private int getMetalFromFleet(WebElement fleet)
{
By identifier = By.xpath("td[contains(text(),'Metaal')]/following-sibling::td[contains(@class,'value')]");
return Integer.parseInt(fleet.findElement(identifier).getText());
}
Obviously you will want some error handling in there, but hopefully this gives the idea that those loops are not always required, and Xpath isn't always the bogeyman it is made out to be by some.
显然,您将需要在那里进行一些错误处理,但希望这给出了并不总是需要这些循环的想法,并且 Xpath 并不总是被某些人认为是怪物。
EDIT
编辑
Just in case anyone is confused, it is okay for the XPath to not have leading slashes if the selector is performed on a WebElement rather than the WebDriver object.
以防万一有人感到困惑,如果选择器是在 WebElement 而不是 WebDriver 对象上执行的,那么 XPath 没有前导斜杠是可以的。
You would have to add two leading slashes if this selector was used on the WebDriver object.
如果在 WebDriver 对象上使用此选择器,则必须添加两个前导斜杠。
EDIT AGAIN!
再次编辑!
Xpath may need some tweaking but you should get the idea of the approach. I cannot see "StarStreek" in your html but it was in your code so added it to my xpath.
Xpath 可能需要一些调整,但您应该了解该方法。我在您的 html 中看不到“StarStreek”,但它在您的代码中,因此将其添加到我的 xpath 中。
回答by kch
Got similar problem - i want to click on a row in a table which has given value. Solution (id can be changed to class name etc.):
遇到了类似的问题 - 我想单击表中具有给定值的行。解决方法(id可以改成类名等):
driver.findElement(By.xpath("//table[@id='<yourTableId>']//tr//td[contains(text(),'"+<givenValue>+"')]")).click();