天天看點

Selenium4+Python3系列(六) - Selenium的三種等待,強制等待、隐式等待、顯式等待

為什麼要設定元素等待

直白點說,怕報錯,哈哈哈!

肯定有人會說,這也有點太直白了吧。

用一句通俗易懂的話就是:等待元素已被加載完全之後,再去定位該元素,就不會出現定位失敗的報錯了。

如何避免元素未加載出來而導緻定位失敗 ?

三種方式,強制等待、隐式等待、顯式等待!

1、強制等待

就是​

​sleep() ​

​​,也叫硬等待;

缺點就是:如果等待時間過長,即使元素已被加載出來了,但還是要繼續等,這樣會導緻整個腳本的執行上會浪費很多時間。

示例代碼如下:

# 強制等待案例
driver.get("http://localhost:8080/wait.html")
driver.find_element(By.ID, "wait").click()
time.sleep(3)
text = driver.find_element(By.ID, "green_box").text
print('text is : '+text)      

2、隐式等待

​WebDriver ​

​提供了三種隐性等待方法:

  • ​implicitly_wait​

識别對象時的逾時時間。過了這個時間如果對象還沒找到的話就會抛出​

​NoSuchElementException ​

​異常。

  • ​set_script_timeout​

異步腳本的逾時時間。​

​WebDriver ​

​可以異步執行腳本,這個是設定異步執行腳本,腳本傳回結果的逾時時間。

  • ​set_page_load_timeout​

頁面加載時的逾時時間。因為 ​

​WebDriver ​

​​會等頁面加載完畢再進行後面的操作,是以如果頁面超過設定時間依然沒有加載完成,那麼 ​

​WebDriver​

​ 就會抛出異常。

以上三種都是在整個webDriver生命周期有效,即全局設定,相當于全局變量!

示例代碼如下:

def init():
    # 最大化操作
    driver.maximize_window()
    driver.set_script_timeout(60)
    # 智能等待60秒,找到元素後立即繼續執行,全局生效
    driver.implicitly_wait(60)
    driver.set_page_load_timeout(60)


init()
# 強制等待案例
driver.get("http://localhost:8080/wait.html")
driver.find_element(By.ID, "wait").click()
# 硬等待
# time.sleep(3)
text = driver.find_element(By.ID, "green_box").text
print('text is : '+text)      

3、顯式等待

就是明确的要等到指定元素(相當于局部變量)的出現或者是某個元素的可點選等條件等到為止,才會繼續執行後續操作,等不到,就一直等,如果在規定的時間之内都沒找到,就會抛出異常!

顯示等待與隐式等待相對,顯示等待必須在每個需要等待的元素前面進行聲明。

示例代碼如下:

# -*- coding: utf-8 -*-
"""
@Time : 2022/10/31 8:12 PM
@Auth : 軟體測試君
@File :test_wait.py
@IDE :PyCharm
@Motto:ABC(Always Be Coding)
"""

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from webdriver_manager.chrome import ChromeDriverManager

'''
初始化操作
'''
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))


def init():
    # 最大化操作
    driver.maximize_window()


init()
driver.get("http://localhost:8080/wait.html")
driver.find_element(By.ID, "wait").click()
# 顯示等待案例
# 設定元素等待執行個體,最多等5秒,每0.5秒檢視條件是否成立
element = WebDriverWait(driver, 5, 0.5).until(EC.presence_of_element_located((By.ID, "green_box")))
print('text is : ' + element.text)
driver.quit()      
3.1、顯示等待需要用到兩個類

​WebDriverWait​

​​和​

​expected_conditions​

​兩個類。

WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)參數說明:

​driver:​

​浏覽器驅動

​timeout:​

​最長逾時時間,預設以秒為機關

​poll_frequency:​

​檢測的間隔步長,預設為0.5s

​ignored_exceptions:​

​逾時後的抛出的異常資訊,預設抛出NoSuchElementExeception異常。

3.2、until()和until_not()的方法

until

  • ​WebDriverWait(driver,10).until(method,message="")​

  • 調用該方法提供的驅動程式作為參數,直到傳回值為True

​method: ​

​ 在等待期間,每隔一段時間(__init__中的poll_frequency)調用這個傳入的方法,直到傳回值不是False

​message: ​

​ 如果逾時,抛出TimeoutException,将message傳入異常

until_not

  • WebDriverWait(driver,10).until_not(method,message="")
  • 調用該方法提供的驅動程式作為參數,直到傳回值為False

與until相反,until是當某元素出現或什麼條件成立則繼續執行,until_not是當某元素消失或什麼條件不成立則繼續執行,參數也相同。

3.3、expected_conditions類

各種類,達到某種條件,傳回True和False,詳細參考下表。

Selenium4+Python3系列(六) - Selenium的三種等待,強制等待、隐式等待、顯式等待
3.4、顯示等待,自定義等待條件

示例代碼如下:

# 設定等待
wait = WebDriverWait(driver, 10, 0.5)
# 使用匿名函數
element = wait.until(lambda diver: driver.find_element(By.ID, 'green_box'))
print(element.text)
driver.quit()      

寫在最後

其實隐式等待和顯示等待在本質上是一緻的,隻是顯示等待多了一個指定元素條件逾時時間,在使用場景上,可以使用隐式等待來做一個全局的控制,例如設定全局隐式等待6秒;

如果某個控件比較特殊,需要更長的時間加載,比如十幾秒或者更長,就可以使用顯示等待對其進行單獨處理;

優秀不夠,你是否無可替代

軟體測試交流QQ群:721256703,期待你的加入!!

歡迎關注我的微信公衆号:軟體測試君

Selenium4+Python3系列(六) - Selenium的三種等待,強制等待、隐式等待、顯式等待