『心善淵』Selenium3.0基礎 — 23、Selenium的元素等待

繁華似錦Fighting發表於2021-07-13

1、元素等待介紹

WebDriver定位頁面元素時如果未找到,會在指定時間內一直等待的過程。為了保證指令碼執行的穩定性,需要指令碼中新增等待時間。

2、為什麼要設定元素等待

在元素定位的時,可能出現指令碼已經執行到定位某個元素的時候,但該元素尚未載入到頁面,此時指令碼會因無法定位到該元素而導致執行失敗。換句話說就是程式碼執行的速度,快於頁面元素載入的速度,我們需要等待頁面元素全部載入完成之後,再做定位元素。元素等待本質是為了解決元素定位時序上不匹配的問題。

頁面載入速度慢的原因

  1. 由於網路速度原因。
  2. 電腦配置原因。
  3. 伺服器處理請求原因。

3、Selenium中常用的元素等待方式

Selenium中常用的元素等待方式有三種:

  1. 強制等待:time.sleep()
  2. 隱式等待:implicitly_wait()
  3. 顯式等待:WebDriverWait()

4、強制等待

設定等待最簡單的方法就是強制等待,其實就是time.sleep()方法。不管它什麼情況,讓程式暫停執行一定時間,時間過後繼續執行。缺點是不智慧,如果設定的時間太短,元素還沒有載入出來一樣會報錯。設定的時間太長,則會浪費時間。因而在實際UI自動化指令碼開發中,這個方式一般比較少用。

5、隱式等待

(1)隱式等待介紹

WebDriver提供了mplicitly_wait()方法來實現隱式等待。隱式等待相當於設定全域性等待,在定位元素時,對所有元素設定的超時時間。implicitly_wait()預設引數的單位為秒,預設設定超時時間為0,設定後這個隱式等待會在WebDriver物件例項的整個生命週期起作用。

從等待作用上看,是可以滿足需要的,但是考慮到實際應用場景,Driver(瀏覽器)要等待的元素和指令碼要操作的元素未必相同,也就是說,指令碼要操作的元素已經出現,但因為設定了全域性等待,Driver(瀏覽器)也會繼續等待頁面上其他無關元素,直至整個頁面載入完畢。所以與顯式等待相比,可能會出現一些無效等待的情況。

如果超出了設定的時長,元素還沒有被載入,則拋NoSuchElementException異常(可自己指定異常或自定義異常)。

(2)隱式等待示例

"""
1.學習目標:
    掌握selenium隱式等待方法使用
2.操作
    2.1 隱式等待方法
        driver.implicitly_wait(最大等待時間,單位:秒)
    2.2 隱式等待作用
        在規定的時間內等待頁面所有元素載入;
    2.3 使用場景:
        在有頁面跳轉的時候,可以使用隱式等待。
3.需求
    實現selenium隱式等待方法
"""
# 1.匯入selenium
from selenium import webdriver
import time
from selenium.common.exceptions import NoSuchElementException

# 2.開啟瀏覽器
driver = webdriver.Chrome()

# 3.開啟頁面
url = "https://www.jd.com/"
driver.get(url)

# 4. 新增隱式等待
print("等待開始時間", time.time())
# 等待5秒鐘,最多等待5秒。
# 如果在5秒內載入完成,載入完就繼續執行。
driver.implicitly_wait(5)
print("等待結束時間", time.time())

# 5. 定位元素,點選連結
try:
    driver.find_element_by_link_text("秒殺").click()
except NoSuchElementException as e:
    print(e)
finally:
    # 6.關閉瀏覽器
    time.sleep(3)
    driver.quit()

"""
輸出結果:
等待開始時間 1590511914.654972
等待結束時間 1590511914.6569717
"""

說明:

在上面的案例中implicitly_wait()設定等待時長為5秒。這個5秒的設定並不針對頁面上的某一個元素進行等待,也不是一個固定的等待時間。如果頁面全部元素提前載入完,不用等待全部時間。如果直到超出設定時長(5秒)還沒有定位到元素,則丟擲異常。

6、顯式等待

(1)顯式等待介紹

顯示等待是一種更智慧的等待方式。顯示等待比隱式等待更節省測試時間,個人更推薦使用顯示等待的方式來判斷頁面元素是否出現。程式會每隔一段時間(預設為0.5秒,可自定義)執行一下判斷條件,等待某個條件成立時繼續執行,否則在達到最大時長丟擲超時異常TimeoutException(實際上是until()丟擲的TimeoutException異常,這裡注意一下)。

WebDriverWait()類是由WebDirver提供的等待方法。在設定時間內,通過配合until()until_not()ExpectedCondition等條件的使用,預設每隔一段時間,輪詢檢測一次當前頁面元素是否存在,如果超過設定時間檢測不到則丟擲異常。這樣的等待方式可避免無效等待,在實際應用中推薦使用該方法。

(2)顯式等待語法

# 導包WebDriverWait
from selenium.webdriver.support.wait import WebDriverWait

# 顯示等待方法
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)

說明:

  • driverWebDriver的驅動程式(IEFirefoxChrome等)。
  • timeout:最長超時時間,預設以秒為單位。
  • poll_frequency:休眠時間的間隔(步長)時間,預設為0.5秒(輪詢頻率)
  • ignored_exceptions:超時後的異常資訊,預設值ignored_exceptions=None,因為通常配合until()方法使用,until()方法預設情況下拋TimeoutException異常。

(3)until()until_not()方法

WebDriverWait()方法一般會和until()until_not()方法配合使用。

@1、until(method, message=' ')

  • method:在等待期間,每隔一段時間呼叫這個傳入的方法,直到返回值為True;
  • message:如果超時,丟擲TimeoutException,將message位置傳入異常。

@2、until_not(method, message=’ ’)

  • method:在等待期間,每隔一段時間呼叫這個傳入的方法,直到返回值為False。
  • message:如果超時,丟擲TimeoutException,將message位置傳入異常。

注:until_not是當某元素消失或什麼條件不成立則繼續執行。

(4)顯式等待的使用

呼叫方式如下

WebDriverWait(driver, 超時時長, 呼叫頻率(可選,有預設值), 忽略異常(可選,有預設值)).until(可執行方法, 超時時返回的資訊)

示例

"""
1.學習目標
     必須掌握selenium中顯式等待使用方法
2.操作步驟(語法)
    2.1匯入WebDriverWait類
    2.2使用方法
        WebDriverWait(driver,timeout,pol1_frequency=0.5).until(method)
            driver:瀏覽器
            timeout:最大等待時間,單位:秒(和隱式顯示是一樣的)
            po11_frequency:輪詢時間

        until(method,message)
        method:將一個方法作為引數傳入

3.需求
    在註冊A頁面中,使用顯示等待來定位賬號A輸入相
"""
# 1.匯入selenium
from selenium import webdriver
import time
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import NoSuchElementException

# 2.開啟瀏覽器
driver = webdriver.Chrome()

# 3.開啟頁面
url = "https://www.jd.com/"
driver.get(url)

# 4.使用顯示等待,定位元素,點選連結
try:
    print("等待開始時間", time.time())
    """
    lambda x: x.find_element_by_link_text("秒殺")
    是Python的匿名函式,主要記得這裡要傳入一個方法。
    x = driver
    不過以後在我們的實際開發中,不這樣傳入一個方法。
    """
    login = WebDriverWait(driver, 5).until(lambda x: x.find_element_by_link_text("秒殺"))
    print("等待結束時間", time.time())
    login.click()
except NoSuchElementException as e:
    print(e)
finally:
    # 5.關閉瀏覽器
    time.sleep(3)
    driver.quit()

"""
輸出結果:
等待開始時間 1590511979.5245922
等待結束時間 1590511979.5725648
"""

參考:https://www.testclass.cn/selenium_elements_wait.html

相關文章