关于python+selenium中显示等待WebDriverWait的用法
最近学习selenium自动化, 由于代码执行速度过快,导致元素还没被加载出来,代码就去定位,导致报错,由于我一直使用的
是time.sleep强制等待,虽然不好用,但胜在简单嘛, 但是有时设置的睡眠时间过长,大家懂的,干等是很浪费效率的,所以
打算学习一些显式等待,但是在网上看了很多博主的文章,关于显示等待的until(method)到底传入什么参数,我至今不解。
所以记录下来,以供有需要的人观看。
首先先说明一下 具体使用的参数 :
WebDriverWait(driver,timeout=程序等待时间,poll_frequency=每隔几秒执行until中的方法).until(method='具体来做什么事情')
第一个driver是固定的参数,就是 webdriver.Chrome()的实例化对象,其他参数我在上面都有写,在这里就不描述了。
下面我们来说until中具体需要放什么东西,一开始我的设想是直接放入driver.find_element_by_xpath去定位,后来发现是不行的,然后又定义了一个函数,将driver.find_element_by_xpath放在函数中去执行,也不行,在网上借鉴了各路大神的文章。说要使用expected_conditions as EC这个东西,然后我又去借鉴EC是个什么,发现EC下面的方法可以判断当前页面是否有你所需要的元素,然后EC.text_to_be_present_in_element()里面又需要传一个什么By之类的参数,我又得去查,发现By其实也是一种定位方式,只怪我知识浅薄,之前还不知道,反正看来看去,浪费了大量的时间,觉得有点不值得,去特么的EC,BY :
其实在until中最简单的方式就是传入 匿名函数,until( lambda x:x.find_element_by_xpath() ) ,x后面接定位策略,并不一定是xpath,都可以使用, 只要传入匿名函数,until就可以直接去执行这个函数,但是我之前也是使用了def 函数 为什么不行呢 :
我查看了until中的源代码,其实使用def定义函数也是可以使用的,那么到底应该如何去使用呢 :
首先你定义函数的时候需要设置不定长默认参数 *args。因为在源码中,会将driver对象传入到我们的函数中,其次需要将定位策略return 出来,不然源码接受不到参数,会一直去定位它,然后定义好func之后将func索引传入给until,以下就是我写的代码,供大家参考,也不知道讲没讲清楚,有兴趣的朋友可以看一下:
def func(*args) :
return args[0].find_element_by_xpath("//*[text()='任务大厅']")
WebDriverWait(driver,30,1).until(func)
源码:
def until(self, method, message=''):
while True:
try:
value = method(self._driver)
if value:
return value
通过这段源码可以看出,当我们将func的索引传入until后,即method=func, 在Try下面,until调用了method,并且传入了driver对象,所以实际上是我们定义的函数func(driver),所以我说我们定义的函数需要接受一个参数,然后这个函数需要有一个返回值给value,如果接受不到这个返回值,就会一直去重复执行method函数,直至我们设置的时间结束。