Selenium 等待元素加载

48

我应该如何编写Selenium函数来等待仅具有类标识符的表格?使用Python时,我非常困难地学习使用Selenium的Python Webdriver函数。

14个回答

58

来自Selenium文档PDF

import contextlib
import selenium.webdriver as webdriver
import selenium.webdriver.support.ui as ui

with contextlib.closing(webdriver.Firefox()) as driver:
    driver.get('http://www.google.com')
    wait = ui.WebDriverWait(driver,10)
    # Do not call `implicitly_wait` if using `WebDriverWait`.
    #     It magnifies the timeout.
    # driver.implicitly_wait(10)  
    inputElement=driver.find_element_by_name('q')
    inputElement.send_keys('Cheese!')
    inputElement.submit()
    print(driver.title)

    wait.until(lambda driver: driver.title.lower().startswith('cheese!'))
    print(driver.title)

    # This raises
    #     selenium.common.exceptions.TimeoutException: Message: None
    #     after 10 seconds
    wait.until(lambda driver: driver.find_element_by_id('someId'))
    print(driver.title)

3
您能否更新Selenium文档PDF的URL?它似乎已经“消失”了。 - Toran Billups
1
@ToranBillups:不幸的是,它似乎不再出现在官方网站上了。这似乎是我所提到的内容的副本:http://scholar.harvard.edu/files/tcheng2/files/selenium_documentation_0.pdf。搜索“WebDriverWait”。[在线文档](http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp#explicit-and-implicit-waits)类似,可能更加更新。 - unutbu

21
Selenium 2的Python绑定有一个新的支持类expected_conditions.py,可以执行各种操作,例如测试元素是否可见。它在这里可用:available here. 注意:上面的文件截至2012年10月12日在主干中,但尚未包含在最新的下载中(仍为2.25版本)。在新的Selenium版本发布之前,您可以将此文件保存到本地并像下面这样导入它。
为了使生活变得更加简单,您可以将一些预期条件方法与Selenium的“等待直到”逻辑结合起来,创建一些非常方便的函数,类似于Selenium 1中可用的功能。例如,我将其放入名为SeleniumTest的基类中,该类扩展了我的所有Selenium测试类。
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
import selenium.webdriver.support.expected_conditions as EC
import selenium.webdriver.support.ui as ui

@classmethod
def setUpClass(cls):
    cls.selenium = WebDriver()
    super(SeleniumTest, cls).setUpClass()

@classmethod
def tearDownClass(cls):
    cls.selenium.quit()
    super(SeleniumTest, cls).tearDownClass()

# return True if element is visible within 2 seconds, otherwise False
def is_visible(self, locator, timeout=2):
    try:
        ui.WebDriverWait(driver, timeout).until(EC.visibility_of_element_located((By.CSS_SELECTOR, locator)))
        return True
    except TimeoutException:
        return False

# return True if element is not visible within 2 seconds, otherwise False
def is_not_visible(self, locator, timeout=2):
    try:
        ui.WebDriverWait(driver, timeout).until_not(EC.visibility_of_element_located((By.CSS_SELECTOR, locator)))
        return True
    except TimeoutException:
        return False

然后你可以像下面这样在测试中轻松使用它们:

def test_search_no_city_entered_then_city_selected(self):
    sel = self.selenium
    sel.get('%s%s' % (self.live_server_url, '/'))
    self.is_not_visible('#search-error')

请注意,其中一些等待似乎是内置的:https://selenium-python.readthedocs.io/waits.html - mlissner

7

我使用过以下两种方法:

  • time.sleep(seconds)(暂停指定的秒数)
  • webdriver.Firefox.implicitly_wait(seconds)(隐式等待指定的秒数,如果元素不可用,则在DOM中轮询一段时间)

第一个方法很明显 - 只需等待几秒钟即可完成某些操作。

对于所有我的Selenium脚本,当我在笔记本电脑上运行它们时,使用带有几秒钟范围(1到3)的sleep()方法就可以了,但是在我的服务器上等待时间范围更广,所以我也使用implicitly_wait()方法。我通常使用implicitly_wait(30),这已经足够了。

隐式等待是告诉WebDriver,在查找元素或元素时,在DOM中轮询一定的时间,如果它们不立即可用。默认设置为0。一旦设置,隐式等待将设置为WebDriver对象实例的生命周期。


3

由于Python的Selenium驱动程序不支持wait_for_condition函数,因此我为Python实现了以下内容。

def wait_for_condition(c):
for x in range(1,10):
    print "Waiting for ajax: " + c
    x = browser.execute_script("return " + c)
    if(x):
        return
    time.sleep(1)

用作

等待 ExtJS Ajax 请求不再挂起:

wait_for_condition("!Ext.Ajax.isLoading()")

一个JavaScript变量被设置。
wait_for_condition("CG.discovery != undefined;")

etc.


哇哦!这个像冠军一样成功了:wait_for_condition("$().active == 0") - mattmc3

2

您可以在循环中使用短暂的睡眠,并将其传递给您的元素ID:

def wait_for_element(element):
     count = 1
     if(self.is_element_present(element)):
          if(self.is_visible(element)):
              return
          else:
              time.sleep(.1)
              count = count + 1
     else:
         time.sleep(.1)
         count = count + 1
         if(count > 300):
             print("Element %s not found" % element)
             self.stop
             #prevents infinite loop

这基本上就是WebdriverWait的作用 :) - m3nda

1
使用适当的XPath定位器与Wait Until Page Contains Element。例如,考虑以下HTML代码:
<body>
  <div id="myDiv">
    <table class="myTable">
      <!-- implementation -->
    </table>
  </div>
</body>

...您可以输入以下关键字:

Wait Until Page Contains Element  //table[@class='myTable']  5 seconds

除非我漏掉了什么,否则没有必要为此创建一个新函数。


1
如果有帮助的话...
在Selenium IDE中,我添加了以下内容: 命令:waitForElementPresent 目标://table[@class='pln']
然后我执行了“文件>导出测试用例为Python2(Web Driver)”,它给了我这个...
def test_sel(self):
    driver = self.driver
    for i in range(60):
        try:
            if self.is_element_present(By.XPATH, "//table[@class='pln']"): break
        except: pass
        time.sleep(1)
    else: self.fail("time out")

1
更简单的解决方案:
    from selenium.webdriver.common.by import By    
    import time

    while len(driver.find_elements(By.ID, 'cs-paginate-next'))==0:
        time.sleep(100)

1
希望这有所帮助。
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By   


driver = webdriver.Firefox()
driver.get('www.url.com')

try:
    wait = driver.WebDriverWait(driver,10).until(EC.presence_of_element_located(By.CLASS_NAME,'x'))
except:
    pass

0
如果我不知道关于Selenium命令的某些内容,我会使用带有Firefox的Selenium Web IDE RC。您可以在组合框中选择并添加命令,完成测试用例后,您可以将测试代码导出为不同的语言,如Java、Ruby、Python、C#等。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接