Selenium 等待元素

48 投票
14 回答
101842 浏览
提问于 2025-04-17 04:24

我该如何用Python写一个Selenium的函数,让它等待一个只有类名的表格出现呢?我在学习使用Selenium的Python webdriver功能时遇到了很多困难。

14 个回答

7

我在使用以下方法时有过不错的体验:

  • time.sleep(秒数)
  • webdriver.Firefox.implicitly_wait(秒数)

第一个方法很简单,就是让程序等几秒钟,等一些事情完成。

在我所有的Selenium脚本中,使用sleep()让程序暂停1到3秒在我的笔记本上运行得很好,但在我的服务器上,等待的时间范围更大,所以我也会使用implicitly_wait()。我通常设置implicitly_wait(30),这个时间其实已经足够了。

隐式等待就是告诉WebDriver在找元素的时候,如果元素没有马上出现,就在一定时间内反复检查页面。默认情况下,这个时间是0秒。一旦设置了隐式等待,这个时间就会一直有效,直到WebDriver对象被销毁。

21

Selenium 2的Python绑定里新增了一个叫做expected_conditions.py的支持类,可以用来做很多事情,比如检查一个元素是否可见。这个文件可以在这里找到。

注意:上面的文件在2012年10月12日的主干版本中,但在最新的下载版本2.25中还没有包含。在新的Selenium版本发布之前,你可以先把这个文件保存在本地,然后像我下面所做的那样在你的代码中引入它。

为了让事情变得简单一些,你可以把这些期望条件的方法和Selenium的wait until逻辑结合起来,创建一些非常实用的函数,这些函数类似于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')
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)

撰写回答