小智 130

您还可以使用以下代码检查pageloaded

IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));

 wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));
Run Code Online (Sandbox Code Playgroud)

  • 你会认为这样的东西会被内置.等待页面加载在网络上是很常见的事情. (20认同)
  • 这真的一直都有效吗?也许我从你的代码中遗漏了一些东西,但你正在等待dom处于准备状态.但请注意,如果您的代码执行速度太快,则前一页可能尚未卸载,即使您仍在旧页面上,它也会返回true.您需要做的是等待当前页面卸载然后调用上面的代码.检测页面卸载的一种方法是在当前页面上获取一个webelement并等待它变得陈旧.http://www.obeythetestinggoat.com/how-to-get-selenium-to-wait-for-page-load-after-a-click.html (17认同)
  • 仅供参考 - 即使上述情况仍未保证页面完整 - 只是dom准备好了.任何dojo/jquery可能仍然在页面上动态构建元素,因此您可能需要先等待动态元素,然后才能与它们进行交互. (6认同)
  • 请注意,此方法仅检查DOM.如果您使用Ajax或AngularJS,这将无法工作,因为document.readyState将无法检测到某些异步调用. (3认同)
  • 这是C#代码。这不适用于Java,并且会询问有关* Java *的问题。 (2认同)
  • 对于任何好奇的人,[这里有一个永久链接 (`WaitForPageToLoad.java` L93)](https://github.com/SeleniumHQ/selenium/blob/0e493305c2c7064f2b9517c4c1de91fb1fdb0f64/java/client/src/commandeniumt/thought /WaitForPageToLoad.java#L93) 到 Selenium Java 客户端中的位置,它会自动等待页面加载作为其现有实现的一部分(它确实检查了 `document.readyState`)。 (2认同)

Art*_*tem 87

使用WebDriverWait

另见这里

你可以期待展示一些元素.像C#中的东西:

WebDriver _driver = new WebDriver();
WebDriverWait _wait = new WebDriverWait(_driver, new TimeSpan(0, 1, 0));

_wait.Until(d => d.FindElement(By.Id("Id_Your_UIElement"));
Run Code Online (Sandbox Code Playgroud)

  • 如果我不知道页面上会有哪个元素怎么办? (12认同)
  • @ EmmanuelAngelo.R [TimeSpan](http://msdn.microsoft.com/en-us/library/system.timespan.aspx)是一个.Net数据结构. (3认同)
  • 这将等待加载特定元素而不是整页. (3认同)
  • 这根本不能保证元素将被完全加载,也不能回答问题。怎么会有人对此表示赞同? (2认同)

Sam*_*Sam 35

如果设置驱动程序的隐式等待,然后findElement在预期在加载页面上的元素上调用该方法,则WebDriver将轮询该元素,直到找到该元素或达到超时值.

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)

来源:隐式等待

  • 它不会帮助等待页面加载. (3认同)

Pau*_*eld 34

通常,使用Selenium 2.0时,Web驱动程序只应在确定页面已加载后才将控制权返回给调用代码.如果没有,您可以调用waitforelemement,循环调用findelement直到找到或超时(可以设置超时).

  • 不幸的是,Selenium 2并不会在所有情况下都等待加载页面.例如WebElement:click()不等待,这在属于Javadoc中明确说明.但是,他们没有告诉我如何检查要加载的新页面.`如果点击()导致通过一个事件要加载一个新页面或通过发送一个本地事件做(这是Firefox的一个共同的情况下,IE浏览器在Windows上),那么该方法将不会等待它被加载并调用者应验证是否已加载新页面 (27认同)
  • 我同意:特别是Internet Explorer驱动程序是错误的并且在某些情况下立即返回控制,即使页面仍在加载.在我的情况下,我使用`JavascriptExecutor`添加等待,等待document.readyState为"完成".由于从硒到浏览器的往返行程,我认为竞争条件得到缓解,这种"永远"对我有用.在我希望加载页面时"click()"之后,我明确地等待(使用WebDriverWait)for readystate.] (3认同)
  • 加上保罗的回答.请检查这一点http://stackoverflow.com/questions/5858743/driver-wait-throws-illegalmonitorstateexception/5865445#5865445. (2认同)
  • @Karna:是的,从理论上讲应该始终如此,实际上在大多数情况下都应该这样做。当时使用Selenium突出表明,有时它认为页面已完成加载,但还没有完成。我最近没用过硒,所以可能还是不一定。 (2认同)

all*_*kim 21

Ruby实现:

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until {
    @driver.execute_script("return document.readyState;") == "complete" 
}
Run Code Online (Sandbox Code Playgroud)

  • Python等价物:WebDriverWait(driver,10).until(lambda d:d.execute_script('return document.readyState')=='complete') (17认同)
  • Python使用上面的代码,但不要忘记这一行.. | 来自selenium.webdriver.support.ui导入WebDriverWait (2认同)

小智 17

你可以删除该System.out行.它是为了调试目的而添加的.

WebDriver driver_;

public void waitForPageLoad() {

    Wait<WebDriver> wait = new WebDriverWait(driver_, 30);
    wait.until(new Function<WebDriver, Boolean>() {
        public Boolean apply(WebDriver driver) {
            System.out.println("Current Window State       : "
                + String.valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState")));
            return String
                .valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState"))
                .equals("complete");
        }
    });
}
Run Code Online (Sandbox Code Playgroud)


hwj*_*wjp 13

所有这些解决方案都适用于特定情况,但它们至少会遇到以下几个问题:

  1. 它们不够通用 - 它们希望您提前知道某些特定条件对于您要访问的页面是否正确(例如,将显示某个元素)

  2. 它们对竞争条件持开放态度,您可以使用旧页面上实际存在的元素以及新页面.

这是我尝试避免这个问题的通用解决方案(在Python中):

首先,一个通用的"等待"函数(如果你愿意,可以使用WebDriverWait,我发现它们很难看):

def wait_for(condition_function):
    start_time = time.time()
    while time.time() < start_time + 3:
        if condition_function():
            return True
        else:
            time.sleep(0.1)
    raise Exception('Timeout waiting for {}'.format(condition_function.__name__))
Run Code Online (Sandbox Code Playgroud)

接下来,该解决方案依赖于selenium为页面上的所有元素(包括顶级元素)记录(内部)id号的事实<html>.当页面刷新或加载时,它会获得一个带有新ID的新html元素.

因此,假设您要单击带有文本"我的链接"的链接,例如:

old_page = browser.find_element_by_tag_name('html')

browser.find_element_by_link_text('my link').click()

def page_has_loaded():
    new_page = browser.find_element_by_tag_name('html')
    return new_page.id != old_page.id

wait_for(page_has_loaded)
Run Code Online (Sandbox Code Playgroud)

对于更多Pythonic,可重用的通用助手,您可以创建一个上下文管理器:

from contextlib import contextmanager

@contextmanager
def wait_for_page_load(browser):
    old_page = browser.find_element_by_tag_name('html')

    yield

    def page_has_loaded():
        new_page = browser.find_element_by_tag_name('html')
        return new_page.id != old_page.id

    wait_for(page_has_loaded)
Run Code Online (Sandbox Code Playgroud)

然后你可以在任何硒交互中使用它:

with wait_for_page_load(browser):
    browser.find_element_by_link_text('my link').click()
Run Code Online (Sandbox Code Playgroud)

我认为那是防弹的!你怎么看?

关于它博客文章中的更多信息


小智 11

您还可以使用类:ExpectedConditions显式等待元素显示在网页上,然后才能采取任何操作进一步操作

您可以使用ExpectedConditions该类来确定元素是否可见:

WebElement element = (new WebDriverWait(getDriver(), 10)).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("input#houseName")));
Run Code Online (Sandbox Code Playgroud)

有关ExpectedConditions class Javadoc您可以检查的所有条件的列表,请参阅.


小智 10

Imran的回答重新针对Java 7:

    WebDriverWait wait = new WebDriverWait(driver, 30);

    wait.until(new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver wdriver) {
            return ((JavascriptExecutor) driver).executeScript(
                "return document.readyState"
            ).equals("complete");
        }
    });
Run Code Online (Sandbox Code Playgroud)


小智 10

这是当前最受好评的答案的 Java 8 版本:

WebDriverWait wait = new WebDriverWait(myDriver, 15);
wait.until(webDriver -> ((JavascriptExecutor) myDriver).executeScript("return document.readyState").toString().equals("complete"));
Run Code Online (Sandbox Code Playgroud)

myDriver一个WebDriver对象(早些时候宣布)。

注意:请注意,此方法 ( document.readyState) 仅检查 DOM。

  • `WebDriverWait(drive, long)` 已弃用,因此请使用 `WebDriverWait(drive,uration)` 例如:- `import java.time.Duration; WebDriverWait(驱动程序, Duration.ofSeconds(5));` (2认同)

Tri*_*tan 9

如果要等待加载特定元素,可以使用以下isDisplayed()方法RenderedWebElement:

// Sleep until the div we want is visible or 5 seconds is over
long end = System.currentTimeMillis() + 5000;
while (System.currentTimeMillis() < end) {
    // Browsers which render content (such as Firefox and IE) return "RenderedWebElements"
    RenderedWebElement resultsDiv = (RenderedWebElement) driver.findElement(By.className("gac_m"));

    // If results have been returned, the results are displayed in a drop down.
    if (resultsDiv.isDisplayed()) {
      break;
    }
}
Run Code Online (Sandbox Code Playgroud)

(5分钟入门指南中的示例)

  • 一年后(当前Selenium版本2.23.1),API中没有"RenderedWebElement".但是,`isDisplayed()`方法现在可以在`WebElement`上直接使用. (4认同)
  • 当可以避免轮询时,轮询是可怕的。 (2认同)

sib*_*iba 9

这似乎是WebDriver的严重限制.显然等待一个元素并不意味着页面被加载,特别是DOM可以完全构建(onready状态),JS仍在执行,CSS和图像仍在加载.

我相信最简单的解决方案是在初始化所有内容后在onload事件上设置一个JS变量,然后在Selenium中检查并等待这个JS变量.


Anu*_*tia 7

在此等待中明确等待或有条件等待,直到给出此条件.

WebDriverWait wait = new WebDriverWait(wb, 60);
wait.until(ExpectedConditions.elementToBeClickable(By.name("value")));
Run Code Online (Sandbox Code Playgroud)

这将等待每个web元素60秒.

隐式使用等待页面上每个元素的等待直到给定时间.

driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)

这将等待每个web元素60秒.


Bru*_*yne 7

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

为什么不直接在 webdriver 中注入一些简单的 Javascript 并检查。这是我在 webscraper 类中使用的方法。Javascript 是非常基础的,即使你不知道。

def js_get_page_state(self):        
    """
    Javascript for getting document.readyState
    :return: Pages state.
    
    More Info: https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
    """
    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
Run Code Online (Sandbox Code Playgroud)


小智 5

I'm surprised that predicates weren't the first choice as you typically know what element(s) you will next interact with on the page you're waiting to load. My approach has always been to build out predicates/functions like waitForElementByID(String id) and waitForElemetVisibleByClass(String className), etc. and then use and reuse these wherever I need them, be it for a page load or page content change I'm waiting on.

For example,

In my test class:

driverWait.until(textIsPresent("expectedText");
Run Code Online (Sandbox Code Playgroud)

In my test class parent:

protected Predicate<WebDriver> textIsPresent(String text){
    final String t = text;
    return new Predicate<WebDriver>(){
        public boolean apply(WebDriver driver){
            return isTextPresent(t);
        }
    };
}

protected boolean isTextPresent(String text){
    return driver.getPageSource().contains(text);
}
Run Code Online (Sandbox Code Playgroud)

Though this seems like a lot, it takes care of checking repeatedly for you and the interval for how often to check can be set along with the ultimate wait time before timing out. Also, you will reuse such methods.

在这个例子中,父类定义并启动了WebDriver driverWebDriverWait driverWait.

我希望这有帮助。


小智 5

使用隐式等待页面上每个元素的等待直到给定的时间。

driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)

这将等待页面上的每个元素30秒。

另一个等待是显式等待或条件等待,在此等待中直到给定条件。

WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
Run Code Online (Sandbox Code Playgroud)

在id中,请提供静态元素ID,该ID会在页面加载后立即显示在页面上。


归档时间:

查看次数:

393527 次

最近记录:

5 年,9 月 前