使用Selenium Webdriver检测一段时间后是否找不到元素

时间:2019-11-04 13:36:21

标签: java selenium-chromedriver webdriverwait

我每隔几秒钟就会多次连接到一个网站,有时该网站只是进入巨大的加载阶段,大约需要5分钟才能停止加载。当它最终停止时,它将引发预期的ElementNotFoundException,然后我捕获并从最后一点重新开始该过程。但是,我希望能够检测到此加载阶段并尽快处理它,而不是等待5分钟才能结束。我尝试使用一种FluentWait实现和一种WebDriverWait实现,但到目前为止都没有效果。这是我尝试过的两个实现:

FluentWait:

private static WebElement fluentWait(final By locator, WebDriver driver) {
    Wait<WebDriver> wait = new FluentWait<>(driver)
            .withTimeout(10, TimeUnit.SECONDS)
            .pollingEvery(2, TimeUnit.SECONDS);
            //.ignoring(NoSuchElementException.class);

    return wait.until((Function<WebDriver, WebElement>) driver1 -> {
        assert driver1 != null;
        return driver1.findElement(locator);
    });
    }

WebDriverWait:

new WebDriverWait(driver,5).until(ExpectedConditions.presenceOfElementLocated(new By.ByCssSelector(someSelector)));

P.S:我正在使用Selenium Webdriver,特别是ChromeDriver()。这是网站进入巨大加载阶段时的外观图->

screenshot

2 个答案:

答案 0 :(得分:1)

这没什么好担心的。您可以检查以下链接,希望对您有所帮助。

Selenium -- How to wait until page is completely loaded

Wait for page load in Selenium

答案 1 :(得分:0)

根据您的问题,我正在收集您是否要让代码等待特定的时间和超时(如果执行之前还没有完成?)?

如果您要这样做,我认为最好的方法是实现一个使用执行程序等待结果的简单类。执行器支持超时,并且能够返回一个值,或者如果执行时间太长,则可以引发异常。

为此,我编写了一个简单的类:

public class TimedWait<T> {
    public T run(Callable<T> run, long timeoutMs) throws TimeoutException, ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        return executor.invokeAny(Collections.singletonList(run), timeoutMs, TimeUnit.MILLISECONDS);
    }
}

这将使用我提到的超时,并在指定的超时后运行提供的Callable,然后引发异常。

下面是它如何工作的示例(出于示例目的,我确实进行了一些快速而肮脏的异常处理,您可能需要清理一下以避免尝试捕获过度使用)

public void run() {
    try {
        String result = new TimedWait<String>().run(() -> {
            Thread.sleep(500);
            return "Some Result";
        }, 1000L);
        System.out.println(result);

        String timeOut = new TimedWait<String>().run(() -> {
            Thread.sleep(1500);
            return "This will time out";
        }, 1000L);
        System.out.println(timeOut);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

由于在此示例中,第一输出的延迟小于超时,因此将打印结果。对于第二个输出,延迟大于超时,从而导致异常。

输出为:

Some Result
java.util.concurrent.TimeoutException