如何更快地从 Selenium WebElement 获取值?
How can I get values from Selenium WebElement more than faster?
这是我从 Selenium WebElement 获取值的测试代码。
import java.util.List;
import org.apache.commons.lang3.ObjectUtils.Null;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class Scan extends WebDriverException {
private long start = 0;
private WebDriver driver = null;
public static void main(String[] args) {
Scan scan = new Scan();
scan.driver = new FirefoxDriver();
scan.driver.get("https://en.wikipedia.org/");
scan.scanAllElements();
scan.driver.quit();
}
public void scanAllElements() {
// get all elements
List<WebElement> elms = driver.findElements(By.xpath("//*"));
System.out.println("elms size:" + elms.size());
// start timer
this.start = System.currentTimeMillis();
// scan all elements and get some value.
for (WebElement elm : elms) {
elm.getTagName();
elm.getAttribute("class");
elm.getAttribute("id");
elm.getAttribute("href");
elm.getText();
elm.getSize();
elm.getLocation();
}
// check the time
stopTimer(elms.size());
}
public void stopTimer(int elmsSize) {
long end = System.currentTimeMillis();
long ms = end - this.start;
long sec = ms / 1000;
long min = sec / 60;
System.out.println("--- Speed Test ---");
System.out.println(ms + " ms");
System.out.println(sec + " s");
System.out.println(min + " min " + (sec % 60) + " s ");
System.out.println("1 loop average time:" + (ms / elmsSize) + " ms");
}
}
结果是this.It需要很长时间。我想让它快点。
elms size:1031
--- Speed Test ---
123468 ms
123 s
2 min 3 s
each loop average time:119 ms
我做了什么
1.Skip一些元素
如果值不是我想要的。跳过使用 (continue) 获取另一个获取值。
2.filter 通过 xpath
此示例获取所有元素 (//*)。所以当我得到它时我过滤了元素,这是个好方法。但是我还有几百个元素,我需要尽量减少处理时间。
3.Multithread
我测试了 Runnable Callable Stream。
Runnable 和 Callable 解决了速度问题。处理时间变为大约 40%。但是很多元素变成了空!!
Stream 最小化只有 10% 的时间而且还有一些元素是空的。
如果你有什么办法可以更快地得到它,请告诉我!!
您可以使用 Javascript,下面的代码将几乎立即 return 具有标签名称、id、href、class 键的地图 ArrayList:
ArrayList<Maps> list = (ArrayList) ((JavascriptExecutor) driver).executeScript("return [...document.querySelectorAll(\"*\")].map(e=>{return {tagName:(e.tagName==undefined?null:e.tagName),class:(e.className==undefined?null:e.className),id:(e.id==undefined?null:e.id),href:(e.href==undefined?null:e.href)}})");
您只需添加 js 代码即可获取位置和大小。对于文本,您可以使用 textContent。
在执行脚本之前确保页面已加载。
这是我从 Selenium WebElement 获取值的测试代码。
import java.util.List;
import org.apache.commons.lang3.ObjectUtils.Null;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class Scan extends WebDriverException {
private long start = 0;
private WebDriver driver = null;
public static void main(String[] args) {
Scan scan = new Scan();
scan.driver = new FirefoxDriver();
scan.driver.get("https://en.wikipedia.org/");
scan.scanAllElements();
scan.driver.quit();
}
public void scanAllElements() {
// get all elements
List<WebElement> elms = driver.findElements(By.xpath("//*"));
System.out.println("elms size:" + elms.size());
// start timer
this.start = System.currentTimeMillis();
// scan all elements and get some value.
for (WebElement elm : elms) {
elm.getTagName();
elm.getAttribute("class");
elm.getAttribute("id");
elm.getAttribute("href");
elm.getText();
elm.getSize();
elm.getLocation();
}
// check the time
stopTimer(elms.size());
}
public void stopTimer(int elmsSize) {
long end = System.currentTimeMillis();
long ms = end - this.start;
long sec = ms / 1000;
long min = sec / 60;
System.out.println("--- Speed Test ---");
System.out.println(ms + " ms");
System.out.println(sec + " s");
System.out.println(min + " min " + (sec % 60) + " s ");
System.out.println("1 loop average time:" + (ms / elmsSize) + " ms");
}
}
结果是this.It需要很长时间。我想让它快点。
elms size:1031
--- Speed Test ---
123468 ms
123 s
2 min 3 s
each loop average time:119 ms
我做了什么
1.Skip一些元素
如果值不是我想要的。跳过使用 (continue) 获取另一个获取值。
2.filter 通过 xpath
此示例获取所有元素 (//*)。所以当我得到它时我过滤了元素,这是个好方法。但是我还有几百个元素,我需要尽量减少处理时间。
3.Multithread
我测试了 Runnable Callable Stream。
Runnable 和 Callable 解决了速度问题。处理时间变为大约 40%。但是很多元素变成了空!!
Stream 最小化只有 10% 的时间而且还有一些元素是空的。
如果你有什么办法可以更快地得到它,请告诉我!!
您可以使用 Javascript,下面的代码将几乎立即 return 具有标签名称、id、href、class 键的地图 ArrayList:
ArrayList<Maps> list = (ArrayList) ((JavascriptExecutor) driver).executeScript("return [...document.querySelectorAll(\"*\")].map(e=>{return {tagName:(e.tagName==undefined?null:e.tagName),class:(e.className==undefined?null:e.className),id:(e.id==undefined?null:e.id),href:(e.href==undefined?null:e.href)}})");
您只需添加 js 代码即可获取位置和大小。对于文本,您可以使用 textContent。
在执行脚本之前确保页面已加载。