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


当前回答

显式等待或条件等待,直到给定这个条件。

WebDriverWait wait = new WebDriverWait(wb, 60);
wait.until(ExpectedConditions.elementToBeClickable(By.name("value")));

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

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

driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

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

其他回答

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

为什么不注入一些简单的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

在python中,你可以简单地使用:

driver.implicitly_wait(30)

我的方法很简单:

long timeOut = 5000;
    long end = System.currentTimeMillis() + timeOut;

        while (System.currentTimeMillis() < end) {

            if (String.valueOf(
                    ((JavascriptExecutor) driver)
                            .executeScript("return document.readyState"))
                    .equals("complete")) {
                break;
            }
        }

所有这些解决方案在特定情况下都是可行的,但它们至少会遇到以下几个问题中的一个:

它们不够通用——它们想让你提前知道,你要访问的页面的某些特定条件将是真的(例如某些元素将被显示)。 它们会出现竞态条件,即您使用的元素实际上同时出现在旧页面和新页面上。

下面是我尝试的避免这个问题的通用解决方案(在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__))

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

假设你想点击一个文本为“my link”的链接,例如:

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)

对于更多python化的、可重用的、通用的helper,你可以创建一个上下文管理器:

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)

然后你可以在几乎任何硒相互作用中使用它:

with wait_for_page_load(browser):
    browser.find_element_by_link_text('my link').click()

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

更多信息在这里关于它的博客文章

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

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

来源:implicit-waits