如何让Selenium 2.0等待页面加载?


当前回答

下面是一个Java 8版本的目前被点赞最多的答案:

WebDriverWait wait = new WebDriverWait(myDriver, Duration.ofSeconds(15));
wait.until(webDriver -> "complete".equals(((JavascriptExecutor) webDriver)
    .executeScript("return document.readyState")));
    

其中myDriver是一个WebDriver对象(前面声明过)。

注意:注意这个方法(document.readyState)只检查DOM。

其他回答

对于使用java 8向前的程序员,可以使用下面的代码来使用显式等待等待页面加载。

JavascriptExecutor js = (JavascriptExecutor) driver;  
new WebDriverWait(driver, 10).until(webDriver ->
(js).executeScript("return document.readyState;").equals("complete"));

注意:在我上面的代码中使用Lambda表达式,它只在java 8的后续版本中可用。

对于使用低版本Java(即Java 8以下)的程序员,可以使用:

ExpectedCondition<Boolean> cond = new ExpectedCondition<Boolean>() {
    @Override
    public Boolean apply(WebDriver input) {
        JavascriptExecutor js = (JavascriptExecutor) driver; 
        return js.executeScript("return document.readyState;").equals("complete");
            }
        };
         
    new WebDriverWait(driver, 100).until(cond);

伙计,所有这些答案都需要太多代码。这应该是一个简单的事情,因为它很常见。

为什么不注入一些简单的Javascript与web驱动程序和检查。 这就是我在webscraper课上使用的方法。Javascript是相当基本的,即使你不知道它。

def js_get_page_state(self):
"""
Javascript for getting document.readyState
:return: Pages state. See doc link below.
"""
ready_state = self.driver.execute_script('return document.readyState')
if ready_state == 'loading':
    self.logger.info("Loading Page...")
elif ready_state == 'interactive':
    self.logger.info("Page is interactive")
elif ready_state == 'complete':
    self.logger.info("The page is fully loaded!")
return ready_state

更多信息见“文档”。MDN Web Docs的readyState: https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState

NodeJS答案:

在Nodejs中,你可以通过承诺得到它…

如果您编写了这段代码,您可以确保当您到达then…

driver.get('www.sidanmor.com').then(()=> {
    // here the page is fully loaded!!!
    // do your stuff...
}).catch(console.log.bind(console));

如果您编写了这段代码,您将进行导航,selenium将等待3秒……

driver.get('www.sidanmor.com');
driver.sleep(3000);
// you can't be sure that the page is fully loaded!!!
// do your stuff... hope it will be OK...

来自Selenium Documentation (Nodejs):

这一点。get(url)→Thenable<undefined> 调度命令导航到给定的URL。 返回一个承诺,该承诺将在文档完成加载时得到解决。

一般来说,使用Selenium 2.0时,web驱动程序应该只在确定页面已加载后才将控制权返回给调用代码。如果没有,您可以调用waitforeleement,它循环调用findelement,直到找到它或超时(可以设置超时)。

SeleniumWaiter:

import com.google.common.base.Function;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

public class SeleniumWaiter {

      private WebDriver driver;

      public SeleniumWaiter(WebDriver driver) {
           this.driver = driver;
      }

      public WebElement waitForMe(By locatorname, int timeout){
           WebDriverWait wait = new WebDriverWait(driver, timeout);
           return wait.until(SeleniumWaiter.presenceOfElementLocated(locatorname));
      }

      public static Function<WebDriver, WebElement> presenceOfElementLocated(final By locator) {
            // TODO Auto-generated method stub
            return new Function<WebDriver, WebElement>() {
                 @Override
                 public WebElement apply(WebDriver driver) {
                      return driver.findElement(locator);
                 }
            };
      }
 }

对你来说:

_waiter = new SeleniumWaiter(_driver);

try {
   _waiter.waitForMe(By.xpath("//..."), 10);
} 
catch (Exception e) {
   // Error
}