Selenium 等待元素
我该如何用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)