【问题标题】:Is there a way with python-selenium to wait until all elements of a page has loaded?python-selenium 有没有办法等到页面的所有元素都加载完毕?
【发布时间】:2018-05-29 16:25:42
【问题描述】:

我要求通常检查页面的所有元素是否已加载。有没有办法基本上检查?

在具体示例中有一个页面,我单击某个按钮,然后我必须等到单击“下一步”按钮。但是,此“下一步”按钮始终可用、可选择和可点击。那么如何用硒检查页面的“状态”(?)?

提醒一下:这是一个关于硒的问题,而不是相关网页的质量......

【问题讨论】:

  • 您能否将 URL 和您的代码提供给我们,直到您需要等待为止?
  • 不幸的是,它是一个非公开页面。但是我问了一个笼统的问题,应该有个笼统的答案……
  • 一般的答案是你的一般问题没有一般的答案。可以有特定的答案可以构建为特定网站或一组网站的一般答案。
  • No Selenium 不提供等待所有元素的方法,原因很简单,当页面通过 JavaScript 动态构建时,这种状态变得相当主观(请参阅延迟加载,ajax)。 Selenium 默认做的是等待静态 HTML 完全加载 (document.readyState === 'complete')。要等待某些元素被刷新,请使用等待者来等待元素与单击之前的元素不同。

标签: python selenium selenium-webdriver


【解决方案1】:

由于您的问题是关于 python-selenium 是否有办法等到页面的所有元素都加载完毕,所以答案是


另一种方法

基本上,你可以写一行代码(或通过函数实现)来检查'document.readyState' == "complete",如下:

self.driver.execute_script("return document.readyState").equals("complete"))

但是这种方法有一个缺点,它没有考虑到要完成的 JavaScript / AJAX 调用


为什么不

写入上述行等待页面加载默认通过Selenium实现。所以重写同样是一个完整的开销。除非'document.readyState' 等于"complete",否则客户端(即 Web 浏览器)将永远不会将控件返回给 WebDriver 实例。一旦满足这个条件,Selenium 就会执行下一行代码。

值得一提的是,虽然客户端(即Web浏览器)一旦实现'document.readyState' equal to "complete"就可以将控制权返回给WebDriver实例,但并不能保证新HTML DOM上的所有WebElements是否都是呈现、可见可交互可点击

因此,根据我们的要求,如果在达到 'document.readyState' equal to "complete" 时,您必须与之交互的下一个 *WebElement 还不是可交互,那么您必须将 WebDriverWait 与与单个 WebElement 匹配 expected_conditions。以下是一些最常用的 expected_condition:

  • element_to_be_clickable(locator)
  • presence_of_element_located(locator)
  • visibility_of(element)

参考文献

您可以在以下位置找到一些相关讨论:

【讨论】:

  • 这大部分是不正确的。 1. readyState == complete 并不意味着所有元素都已加载。它不考虑任何可能仍在加载的动态加载元素。 2. Selenium 并不总是等待 readyState == 完成。它仅在获取 URL 时这样做……而不是在点击或任何其他触发导航或动态加载的操作时。
  • @JeffC 我想你在这里很困惑。 您要回答的问题:1. 在我的回答中,您在哪里找到 readyState == complete mean all elements are loaded? 2. 向我展示任何支持您的评论的文档Selenium does not always wait for readyState == complete 肯定是关于获取 URL 的问题。 3.动态加载上下文仍然不是问题/答案的一部分。
  • 1.问题是如何……“等到页面的所有元素都加载完毕?”您的回答是肯定的,并且您提供了检查就绪状态的代码 == 完成。 2. 使用硒。您不需要文档就知道是这种情况。编写一个脚本,单击一个按钮,然后单击下一页上的一个按钮,没有等待,也没有隐式等待。它将失败,因为以下元素不存在......那是因为 Selenium 不等待。如果您想要特定的内容,请阅读此github.com/SeleniumHQ/selenium/issues/2626
  • 没有问题在哪里说明了有关获取 URL 的任何内容...它的状态是,“在具体示例中有一个页面,我单击某个按钮,然后我有等到我点击‘下一步’按钮。”这正是我刚刚给出的例子。如果 Selenium 在这种情况下自动等待,为什么 OP 会问这个问题?因为它不等待。它只等待获取 URL。 3.问题中没有任何内容表明动态加载不是问题的一部分……您为什么要假设其他情况?这些天在现代网站上非常普遍。
【解决方案2】:

可靠地确定页面是否已完全加载可能具有挑战性。没有办法知道是否所有元素都像这样加载了。您必须在每个页面中定义一些“锚”点,以便就您所知,如果这些元素已加载,则可以假设整个页面已加载。通常这涉及测试的组合。因此,例如,您可以定义如果以下测试组合通过,则认为页面已加载:

  • JavaScript document.readyState === 'complete'
  • “锚”元素
  • 各种“微调器”(如果存在)消失了。

【讨论】:

  • 所以 webdriver 不能“询问”浏览器?浏览器必须“知道”?还是有什么魔力?
  • 好吧,我猜浏览器“知道”的方式是期待readyState 状态。一旦它变成complete,页面已经完全加载。
  • 完全加载并不意味着页面上的每个元素都完成了它的业务并且可以与之交互。
  • Complete 不适用于动态元素、AJAX 调用等。
  • @EugeneS 你上面的评论,Once it becomes complete, the page has fully loaded. 似乎你不明白完整并不总是意味着完整。
【解决方案3】:

有一个名为document.readyState 的东西,您可以通过 Selenium 执行 JavaScript 脚本来检索它。这不适用于动态加载的内容。它返回以下三种状态之一:

加载中 文档仍在加载中,没有可用的 css 或其他资源

互动 文档已加载,没有可用的 css 或其他资源

完成 文档和css/其他资源都被加载了

您至少在寻找交互式。您可以通过调用execute_script来检索状态:

driver.execute_script("return document.readyState")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-24
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 2011-09-15
    • 1970-01-01
    • 2016-08-02
    相关资源
    最近更新 更多