Selenium学习之等待方式

       最近在学习Selenium自动化测试的过程中,发现总是容易出现找不到元素的情况。通常这是因为元素还没加载出来,而我们的代码已经执行导致的,为了解决这个问题,Selenium中提供了三种等待方式:固定等待隐式等待显式等待

(一)time.sleep(固定等待)

这个方法我之前有用到过,在脚本调试的时候,设置这个固定等待,可以方便我们查看调试结果,但在实际使用的时候是不建议的。虽然它可以自定义等待时间,防止网络不好导致页面加载不出来时,太快去调用代码获取元素。但这个方法有个缺点,那就是网络状态良好时,也必须要等待固定的时间,而且需要在我们每一次想设置等待时间的地方都调用这个方法,所以它可能导致整个项目的执行时间无限延长。

打个比方说,我的网络状态良好,但因为设置了固定等待,本来10秒就可以跑完的自动化测试代码,只要哪里写了个time.sleep(30),那最少也得30秒才能跑完,大大浪费了测试时间。

(二)implicitly_wait(隐式等待)

隐式等待是设置一个最长等待时间,比如10秒,如果在10秒内的任何一个时间点,比如5秒的时候网页加载完成了,那么它就会在5秒的时候执行下一步,否则一直要等到10秒过去才会执行下一步。当然如果说10秒过去,还是没加载出来,那么在获取某个未加载完成的元素时,也是会抛出一个异常的。

这个方法还有一个缺点,是因为JavaScript一般都是放在body的最后进行加载,而这个时候页面上的元素都已经加载完毕,我们却还在等待全部页面加载结束。

当然它也是有优点的,不同于time.sleep,它的优势在于只需要在最开始的时候设置一次,就会对整个driver的周期起作用。

(三)WebDriverWait(显式等待)

前面两个等待方式都是比较简单且容易理解的,而WebDriverWait可能就比较难一些。首先在使用显式等待时,必须引入WebDriverWait,代码如下:

from selenium.webdriver.support.wait import WebDriverWait

除此之外,我们还要引入expected_conditions

from selenium.webdriver.support import expected_conditions as EC

查看他的源码,可以发现他有如下几个参数:

  • driver                          WebDriver的实例(如Firefox、Chrome或Remote)

  • timeout                       超时时间,表示超时前等待的时间

  • poll_frequency          轮询频率,调用 until 或 until_not方法中的间隔时间,默认为0.5秒。

  • ignored_exception    忽略异常,调用期间忽略的异常类的iterable结构。默认情况下,它只包含                                                                                NoSuchElementException。

那么,为什么会有poll_frequency这个参数呢?

这是因为显式等待它会有一个轮询机制,也就是每隔固定时间段,默认是0.5秒,会去检查一下是否加载完成了。如果可以了就去走下一步,不可以的话就再等待一个0.5秒,直到时间大于 timeout 设置的时间。

而说到poll_frequency这个参数的设置,就不得不提到until和until_not这两个方法,具体应用方式可以看我下方的代码示例:

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

wait = WebDriverWait(self.driver, 10)
wait.until(EC.title_is('百度一下,你就知道'))#直到 网页标题 显示 对应内容

until和until_not其实是两个循环方法,循环的时间是WebDriverWait实例化中的第三个参数:poll_frequency。大家就可能有疑问了,你上面只设置了两个参数,是的,这是因为driver和timeout这两个参数是必须设置的,而后两个参数则可设置可不设置。如果我们设置了“poll_frequency=2”,那就是说每隔2秒去循环一次,直到满足或者不满足某个条件。“EC”这里相当于对expected_conditions的重命名,在expected_conditions.py文件里面会有多个类,而title_is就是其中之一,像我们在java里面引用方法一样去引用title_is类(网页标题是否显示某某内容),除了这个类以外,EC中还有其他等同于java中方法的类,具体大家可以看一下源码,我后一篇博客会详细解释。

最后要注意的是:

(1)在显式等待中,driver和timeout这两个参数是必须设置的,而后两个参数则可设置可不设置。ignored_exception不设置的话,对于未找到元素的异常信息是不会由报错信息提示的。

(2)显示等待必须配合until和until_not去使用,如果只是对WebDriverWait做了实例化,那么是没有效果的。

(3)当我们既有显式等待,也有隐式等待时,会按照哪个等待时间长来决定最终等待时间。

 

 

你可能感兴趣的:(Selenium学习,Python)