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
18from 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
18from 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
21from 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
22from 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内容请搜索靠谱客的其他文章。
发表评论 取消回复