我是靠谱客的博主 矮小雨,这篇文章主要介绍selenium的三种等待方式,现在分享给大家,希望可以做个参考。

1.为什么要设置元素等待?

当我们在网页中定位元素的时候,有可能打开了网页但元素未加载出来,这个时候定位元素就会找不到。因此,我们需要设置元素等待,等指定元素已被加载出来后,再去定位元素就不会出现定位失败的现像。

2.元素等待的三种方式

2.1强制等待

强制等待是使用sleep设置固定的线程休眠时间。sleep(n)意味着不管浏览器是否加载完成,都要强制等待n秒,n秒后才能执行后边的代码。

示例代码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from selenium import webdriver from time import sleep class TestWait: def setup(self): self.driver = webdriver.Chrome() self.driver.get('https://ceshiren.com') self.driver.maximize_window() def teardown(self): self.driver.quit() def test_wait(self): #强制等待 sleep (3) self.driver.find_element_by_xpath('//*[@class="active"]').click()

强制等待影响脚本执行速度,因此不太建议使用这种方法。如果使用,设置的等待时间最好不要超过3秒,sleep我更多的是来调试代码。

2.2隐式等待

隐式等待比强制等待更智能,会在每个页面加载的时候自动等待,不用每一次都调用等待方法。

隐式等待是使用implicitly_wait(n)来设置等待时间,如果在n秒内加载完成,则继续向下执行;如果没有,就以轮询的方式不断的加载,直到n秒时没有加载完成就抛出异常。

隐式等待又叫全局等待,也就是说不针对页面的某一个元素,而是针对全局元素,隐式等待只需要声明一次,声明之后对整个drvier的生命周期都有效,一般在打开浏览器后进行声明。

示例代码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from selenium import webdriver class TestWait: def setup(self): self.driver = webdriver.Chrome() self.driver.get('https://ceshiren.com') self.driver.maximize_window() #隐式等待:全局的,默认每隔0.5秒扫一次 self.driver.implicitly_wait(3) def test_wait(self): #点击“热门” self.driver.find_element_by_xpath('//*[@class="active"]').click() #点击“最新” self.driver.find_element_by_xpath('//*[@class="ember-view"]').click() def teardown(self): self.driver.quit()

因为是针对全局元素的,所以需要等待整个页面加载完成时,才会执行下一步。这就有一个弊端:如果我需要的那个元素早就加载完成了,只是有个别元素加载特别慢(例如图片,JS文件),但我仍要等待页面全部加载完成才能继续执行,增加了不必要的等待时间,有什么办法可以解决这个问题呢?WebDriver提供了一种更加智能的等待方式:显示等待。

2.3显示等待

显示等待的原理:要等到指定的某一个元素出现或者某一个条件满足,才去执行下一步,等不到就一直轮询检测,直到超时抛出异常,这里作用的是特定的元素或条件,而不是全局元素,可以把它看成局部变量。

显示等待和隐式等待最大的区别就是作用域不同,隐式等待作用的是全局元素,整个WebDriver生命周期内生效,只声明一次即可;显示等待作用的是特定元素,因此需要在每个等待的元素之前进行声明。

显示等待使用WebDriverWait()类和expected_conditions()类。

WebDriverWait()一般和until()和until_not()方法结合使用:

  • WebDriverWait(driver,timeout,poll_frequency=POLL_FREQUENCY, ignored_exceptions=None).until(method,message=’’))
    • driver:驱动
    • timeout:超时时间
    • poll_frequency:轮询时间,默认0.5秒
    • ignored_exceptions:超时后的抛出的异常信息,默认抛出NoSuchElementExeception异常。
    • method: 在等待期间,每隔一段时间调用这个传入的方法,直到返回值不是False
    • message: 如果超时,抛出TimeoutException,将message传入异常

该方法意思为:在设置的timeout时间内,每隔poll_frequency(默认0.5秒)去检测一下当前页面,判断元素是否存在或者条件是否满足,如果结果为Ture则执行下一步,如果不存在则继续轮询检测,直到超时抛出异常。

until_not与until正好相反:当某个元素不存在或者某个条件不成立时,继续执行,我一般用until比较多一些,没有用过until_not。

expected_conditions():达到某种条件时,返回Ture或者False
常用的条件有:

  • presence_of_element_located:判断某个元素是否存在,并不代表该元素可见
  • visibility_of_element_located:判断某个元素是否可见

示例代码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions class TestWait: def setup(self): self.driver = webdriver.Chrome() self.driver.get('https://ceshiren.com') self.driver.maximize_window() def test_wait(self): self.driver.find_element_by_xpath('//*[@class="active"]').click() # 设置元素等待实例,最多等10秒,每0.5秒查看条件是否成立 # 判断“新建话题”是否存在 WebDriverWait(self.driver,10).until(expected_conditions.presence_of_all_elements_located((By.XPATH,'//*[@class="d-button-label"]'))) self.driver.find_element_by_xpath('//*[@class="d-button-label"]').click() def teardown(self): self.driver.quit()

显示等待也可以自定义等待条件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait class TestWait: def setup(self): self.driver = webdriver.Chrome() self.driver.get('https://ceshiren.com') self.driver.maximize_window() def test_wait(self): self.driver.find_element_by_xpath('//*[@class="active"]').click() #显示等待:也可以自己写条件 #设置等待 wait = WebDriverWait(self.driver,10,0.5) #使用匿名函数 wait.until(lambda diver:self.driver.find_element_by_xpath('//*[@class="d-button-label"]')) self.driver.find_element_by_xpath('//*[@class="d-button-label"]').click() def teardown(self): self.driver.quit()

显示等待是一种比较智能的等待方式,可以增加脚本的健壮性。在定位元素的时候,推荐使用显示等待。

最后

以上就是矮小雨最近收集整理的关于selenium的三种等待方式的全部内容,更多相关selenium内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(66)

评论列表共有 0 条评论

立即
投稿
返回
顶部