Как получить значения из Selenium WebElement более чем быстро? - PullRequest
0 голосов
/ 24 сентября 2018

Это мой тестовый код для получения значения из 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");

    }

}

Результат таков. Это занимает много времени.Я хотел бы сделать это быстро.

elms size:1031
--- Speed Test ---
123468 ms
123 s
2 min 3 s 
each loop average time:119 ms

Что я сделал.

1. Пропустите некоторые элементы

Если значение не то, что я хочу.Пропустить получение других значений с помощью (продолжить).

2.filter по xpath

В этом примере получаются все элементы (// *).Поэтому я отфильтровал элементы, когда получил, что было хорошим способом.Но у меня есть еще несколько сотен элементов, и мне нужно минимизировать время процесса.

3. Многопоточность

Я протестировал Runnable Callable Stream.

Runnable и Callable решили проблему скорости.Время процесса стало около 40%.Но многие элементы обнулились !!

Поток минимизирует только 10% времени, а некоторые элементы обнуляются.

Если у вас есть идея получить его более чем быстро, пожалуйста, скажите мне!!

1 Ответ

0 голосов
/ 25 сентября 2018

Вы можете использовать Javascript, код ниже вернет ArrayList of Map с именем тега, id, href, ключами класса почти мгновенно:

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.
Перед выполнением скрипта убедитесь, что страница загружена.

...