这花了我很多时间.
所以我添加了时间测量,我注意到由于某种原因,时间从一行到另一行增加.
我不明白为什么.
你能告诉我吗?
private void buildTableDataMap() {
WebElement table = chromeWebDriver.findElement(By.id("table-type-1"));
List<WebElement> rows = table.findElements(By.tagName("tr"));
theMap.getInstance().clear();
String item;
for (WebElement row : rows) {
ArrayList<String> values = new ArrayList<>();
List<WebElement> tds = row.findElements(By.tagName("td"));
if(tds.size() > 0){
WebElement last = tds.get(tds.size() - 1);
long time = System.currentTimeMillis();
values.addAll(tds.stream().map(e->e.getText()).collect(Collectors.toList()));
System.out.println(System.currentTimeMillis() - time);
//remove redundant last entry:
values.remove(tds.size() - 1);
callSomeFunc(values, last);
item = tds.get(TABLE_COLUMNS.NAME_COL.getNumVal()).getText();
item = item.replaceAll("[^.\\- /'&A-Za-z0-9]", "").trim();//remove redundant chars
theMap.getInstance().getMap().put(item, values);
}
}
}
伙计们,我继续研究.
首先,Florent的回答对我没有帮助,因为据我所知,它至少给了我一个字符串列表,我不得不解析,我不太喜欢这种解决方案……
所以我发现e.getText()调用从调用到调用的时间越来越长!
我也尝试了e.getAttribute(“innerText”),但没有改变.
无法理解为什么.有什么想法解决?
WebElement last = null;
for (WebElement e : tds){
last = e;
long tm1 = 0, tm2 = 0;
if(Settings.verboseYN) {
tm1 = System.currentTimeMillis();
}
s = e.getText(); //This action increases in time!!!
if(Settings.verboseYN) {
tm2 = System.currentTimeMillis();
}
values.add(s); //a 0 ms action!!!
if(Settings.verboseYN) {
System.out.println("e.getText()) took " + (tm2 - tm1) + " ms...");
}
}
这是getText花费的时间图…
void func(WebElement anchorsElement){
List<WebElement> anchors = anchorsElement.findElements(By.tagName("a"));
for (WebElement a : anchors) {
if (a.getAttribute("class").indexOf("a") > 0)
values.add("A");
else if (a.getAttribute("class").indexOf("b") > 0)
values.add("B");
else if (a.getAttribute("class").indexOf("c") > 0)
values.add("C");
}
}
每个函数只有5次迭代,但每次调用函数都会增加执行时间.
这个也有解决方案吗?
解决方法:
您遇到的问题是由于Selenium的设计方式.让我们来看看如何执行JavaScript或执行操作
tds.get(TABLE_COLUMNS.NAME_COL.getNumVal()).getText();
你有一组对象. selenium驱动程序在浏览器端为每个对象分配一个唯一的ID
所以,当你执行下面的getText()时会发生什么
Your code -> HTTP Request -> browser Driver -> browser ->
|
<---------------------------------------------
现在,如果你有一个400rx10c的表,那么它会占用4000个HTTP调用,即使一个调用需要10ms,我们正在查看40000ms~ = 40sec,这是读取表的一个不错的延迟
所以你要做的就是通过执行一个可以返回2d数组的javascript来获取所有数据.这很简单,我在网站下面找到了一个代码
http://cwestblog.com/2016/08/21/javascript-snippet-convert-html-table-to-2d-array/
function tabletoArray(tbl, opt_cellValueGetter) {
opt_cellValueGetter = opt_cellValueGetter || function(td) { return td.textContent || td.innerText; };
var twoD = [];
for (var rowCount = tbl.rows.length, rowIndex = 0; rowIndex < rowCount; rowIndex++) {
twoD.push([]);
}
for (var rowIndex = 0, tr; rowIndex < rowCount; rowIndex++) {
var tr = tbl.rows[rowIndex];
for (var colIndex = 0, colCount = tr.cells.length, offset = 0; colIndex < colCount; colIndex++) {
var td = tr.cells[colIndex], text = opt_cellValueGetter(td, colIndex, rowIndex, tbl);
while (twoD[rowIndex].hasOwnProperty(colIndex + offset)) {
offset++;
}
for (var i = 0, colSpan = parseInt(td.colSpan, 10) || 1; i < colSpan; i++) {
for (var j = 0, rowSpan = parseInt(td.rowSpan, 10) || 1; j < rowSpan; j++) {
twoD[rowIndex + j][colIndex + offset + i] = text;
}
}
}
}
return twoD;
}
我假设您将上述脚本存储在SCRIPT变量中,然后您可以像下面一样运行它
WebDriver driver = ((RemoteWebElement)table).getWrappedDriver();
Object result = ((JavascriptExecutor)driver).executeScript(SCRIPT + "\n return tabletoArray(arguments[0]);" , table);
这将为您提供数据的2D数组,然后您可以按照自己喜欢的方式处理它
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。