顯示等待WebDriverWait常用寫法解析


在網絡上各種selenium自動化測試框架搭建的過程中,對於selenium顯示等待有好幾種寫法,包含但不限於以下幾種:

  • 寫法1:

    +++
    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    
    self.driver = webdriver.Chrome()
    
    WebDriverWait(self.driver).until(lambda x:x.find_element(*loc))
    
    +++
    
  • 寫法2:

    +++
    from selenium import webdriver
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.ui import WebDriverWait
    
    self.driver = webdriver.Chrome()
    
    WebDriverWait(self.driver).until(EC.presence_of_element_located(loc))
    
    +++
    
  • 寫法3:

    +++
    from selenium import webdriver
    from selenium.webdriver.support import expected_conditions as EC
    
    self.driver = webdriver.Chrome()
    
    EC.presence_of_element_located(loc)(self.driver)
    
    +++
    

    新手看着可能有些暈乎乎的,我曾經也是看着也挺暈的。接下來我就要來說說這幾種寫法是怎么運行的。

寫法1

先來簡單看看寫法,在WebDriverWait初始化時傳入了driver參數,然后調用until方法,傳入了一個lambda匿名函數

WebDriverWait(self.driver).until(lambda x:x.find_element(loc))

為了看清運行原委我們得去看看源碼(如果你創建了虛擬環境的話,路徑會如下所示):

venv\Lib\site-packages\selenium\webdriver\support\wait.py

可以看到driver參數傳進來之后被賦值給了WebDriverWait類變量_driver,那么他在哪里使用了呢,我們接着往下看:

在WebDriverWait類的until函數中使用了。
先看一下until的函數注釋(翻譯):調用驅動程序提供的方法作為參數,直到返回值不是False。

結合上文,我們傳入的method是lambda x:x.find_element(*loc)是一個匿名函數。

結合官方文檔的說明,f(0)可以實現給lambda傳入參數。lambda可以引用所在域的變量,x引用的域變量就是WebDriverWait的self._driver類變量 ,lambda x:x.find_element(loc)表達式就被替換成為了self.driver.find_element就可以正常的使用driver使用一樣

​ 寫法1的運行大致就是這樣了。

寫法2

寫法2我們必須關聯以下expected_conditions模塊才能看清楚

venv\Lib\site-packages\selenium\webdriver\support\expected_conditions.py

可以看到EC中的都是類,函數只有兩個,后面介紹

第二種寫法里面我們先看until里面的部分,locator的參數就是我們傳入的loc,loc是什么呢,就是(By.ID,'#su')這種。

然后下面實現了一個__call__方法,里面傳入的參數就是driver,這個方法是什么意思呢,請看下面的小提示。

小提示:重載運算符(魔法方法),python中的可調用對象包括自定義的函數python內置函數類的實例化對象,method() = method.__call__()函數。
這個方法還是通過method(self._driver)方式傳入了driver的實例對象。

然后第64行把這兩個參數傳給了_find_element方法,EC模塊中的兩個函數這個就是其中之一:

這個函數返回了什么呢,第411行,返回了driver.find_element()方法,通過__call__方法返回了self.driver.find_element。

由此我們可以推斷出寫法1和寫法2是完全一樣的,包括解包的時機。

寫法3

讀完了寫法1和寫法2,寫法3會顯得更簡單

presence_of_element_located(傳入的參數)(傳入的driver),在前面小提示已經說過,第二個括號中的正是通過__call__方法來實現的重載運算()調用。

然后兩個參數傳入進去后,presence_of_element_located函數返回driver.find_element。

和寫法1和寫法2不同的是外層沒有包含顯示等待的類。所以寫法3不支持顯示等待,只是返回了一個普通的driver方法或基於driver方法實現的結果。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM