selenium的三种等待时间学习

在面试自动化职位的时候,经常会有问题涉及到你对于自动化中的三种等待时间的提问。很多时候我们在做项目中直接使用time.sleep(3)这句代码去等待3秒或者更长的时间。或者在定位不到元素时候也是直接上述代码去等待知道页面加载完全以至于定位元素成功。做出这些举动往往因为对于等待时间的不会使用导致。

1、 强制等待sleep()
开题中使用的等待就是这种方法,这种方法的坏处就是严重影响程序的执行速度。在程序执行的开始,不管打开浏览器加载是否完毕,一定都会等待这些时间,时间一到继续执行后面的代码。

from selenium import webdriver
from time import sleep
url='https://mail.163.com/'
driver = webdriver.Chrome()
driver.get(url=url)
sleep(3)
driver.maximize_window()
sleep(3)
print(driver.current_window_handle)

上述代码中共设置了2次强制等待时间。1、在打开浏览器开始就设置好强制等待3秒再最大化浏览器。2、最大化浏览器之后再等待3秒之后打印当前的handle。

2、 隐性等待implicitly_time()
设置一个最长等待时间,在整个driver的生命周期一直生效,只需设置一次即可。在遇到这行代码时候,如果浏览器在规定时间之内全部元素加载完毕那么就可以立即开始执行下行代码;如果规定时间之内还没有加载出来也要执行下行代码,这样就等着报错提示罢了。

from selenium import webdriver
from time import sleep
url='https://mail.163.com/'
driver = webdriver.Chrome()
driver.get(url=url)
driver.implicitly_wait(3)
driver.maximize_window()
print(driver.current_window_handle)

代码表示只需设置一次,整个周期就可以生效。其次执行到该行代码,程序会一直等待到整个页面加载完毕才会执行下一步(无论在规定时间之内与否,规定时间之内加载完毕最好,规定时间之内没加载完毕也执行下行代码)。坏处就是,比如执行到第10行代码时,遇到这个隐性等待语句,而此刻我们需要的元素也已经出来了,但是还有一些插件或者js之类还没加载完毕,我们还需要在规定的等待时间之内将插件或者js加载出来再去执行下行代码。如果我们想要立即执行下行代码,不管其他行需要的js没有加载出来,就需要使用显性等待。

3、 显性等待WebDriverWait()
灵活的等待时间,当代码执行到该语句时候,如果driver所需要的定位已经出现那么就不用等待,立即执行下一步,如果没出现那就等待,直到超出设置的等待时间,抛出TimeOutException或者元素定位不到等原因。
其次隐形等待和显性等待可以搭配使用,程序中使用的等待时间取决于二者的最长等待时间。比如显性设置5秒,隐形设置10秒,此刻10>5,那么最长等待时间为隐形的10秒。反之也成立。
使用显性等待使用的WebDriverWait()需要导包

from selenium.webdriver.support.wait import WebDriverWait

(1)查看WebDriverWait()的源码发现存在四个参数。
WebDriverWait(driver,timeout,poll_frequency,ignored_exceptions)分别表示1、驱动,就是代码开始使用的driver;2、等待时间,由自己设置;3、检测的间隔时间,默认是0.5秒;4、超时后的异常信息,默认抛出NoSuchElementException.
(2)使用显性等待通常需要配合unit()和unit_not()方法。这样就能够根据设置的条件灵活的等待,即如果条件成立执行下一步,不成立就抛出异常。
Unit()方法存在2个参数,1、method,在等待时间之内,每隔一段时间调用这个方法,直到返回的结果不是False。2、message,如果超时,抛出TimeoutException。第一个参数method需要的是可执行方法,而不是前面的定位元素的代码,所以

WebDriverWait(driver,10,1).until(driver.find_element_by_xpath("//div[@class='loginUrs']/iframe"))

该代码是错误的案例。
然而这个方法是需要可以调用的,即这个方法需要有__call__()方法,否则报错提醒。这里可以使用selenium自带的一些方法来调用。那么需要先导包。

from selenium.webdriver.support import expected_conditions as EC
具体有的方法如下:
selenium.webdriver.support.expected_conditions(模块)
这两个条件类验证title,验证传入的参数title是否等于或包含于driver.title
title_is
title_contains
这两个人条件验证元素是否出现,传入的参数都是元组类型的locator,如(By.ID, 'kw')
顾名思义,一个只要一个符合条件的元素加载出来就通过;另一个必须所有符合条件的元素都加载出来才行
presence_of_element_located
presence_of_all_elements_located
这三个条件验证元素是否可见,前两个传入参数是元组类型的locator,第三个传入WebElement
第一个和第三个其实质是一样的
visibility_of_element_located
invisibility_of_element_located
visibility_of
这两个人条件判断某段文本是否出现在某元素中,一个判断元素的text,一个判断元素的value
text_to_be_present_in_element
text_to_be_present_in_element_value
这个条件判断frame是否可切入,可传入locator元组或者直接传入定位方式:id、name、index或WebElement
frame_to_be_available_and_switch_to_it
这个条件判断是否有alert出现
alert_is_present
这个条件判断元素是否可点击,传入locator
element_to_be_clickable
这四个条件判断元素是否被选中,第一个条件传入WebElement对象,第二个传入locator元组
第三个传入WebElement对象以及状态,相等返回True,否则返回False
第四个传入locator以及状态,相等返回True,否则返回False
element_to_be_selected
element_located_to_be_selected
element_selection_state_to_be
element_located_selection_state_to_be
最后一个条件判断一个元素是否仍在DOM中,传入WebElement对象,可以判断页面是否刷新了
staleness_of

上面这些就是可以搭配unit()使用的一些方法。具体如下所示:

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait#显性等待的包
from selenium.webdriver.support import expected_conditions as EC#调用可执行方法的一些内容
from time import sleep

url='https://mail.163.com/'
driver = webdriver.Chrome()
driver.get(url=url)
driver.implicitly_wait(3)
driver.maximize_window()
# WebDriverWait(driver,10,1).until(driver.find_element_by_xpath("//div[@class='loginUrs']/iframe"))#错误,需要可执行方法
print(WebDriverWait(driver, 10, 1).until(#等待10,每隔1秒查看一下
    EC.element_to_be_clickable(driver.find_element_by_xpath("//div[@class='loginUrs']/iframe"))))
print(driver.current_window_handle)

你可能感兴趣的:(selenium,selenium,定位,python,软件测试)