selenium 頁面加載以及4種等待


1、頁面加載

1.1、頁面加載超時設置

通過driver.set_page_load_timeout()來設置頁面加載超時時間

1.2、頁面加載策略設置

首選需要明白的一點是,如果什么都不設置,通常,以chrome瀏覽器為例,所有的元素定位是在頁面被完全加載后(頁面tab不再轉圈)才開始。

有時候其實想要的元素已經加載出來了,只是頁面還在加載其他東西,例如圖片,此時若不想繼續等待直接執行元素定位操作,則需要在創建driver的時候設置頁面加載策略:

當調用driver.get("https://xxxx.xxx.xxx")來訪問某頁面時,get方法通常會阻塞瀏覽器直到頁面完全加載后才執行后面的動作,若一個頁面加載過慢,則會導致get方法一直阻塞。有時候希望頁面在加載過程中就開始檢測元素是否存在,而不是等到頁面加載完了才開始檢測,想要實現這個效果,可以用DesiredCapabilities類下的setPageLoadStrategy方法(Python,Chrome瀏覽器):

from selenium import webdriver

from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.support.ui import WebDriverWait

desired_capabilities = DesiredCapabilities.CHROME # 修改頁面加載策略
desired_capabilities["pageLoadStrategy"] = "none" # 注釋這兩行會導致最后輸出結果的延遲,即等待頁面加載完成再輸出
#注:2021/12/20 在谷歌瀏覽器96.0.4664.110上驗證出效果。
driver = webdriver.Chrome('browsers/chromedriver.exe') wait = WebDriverWait(driver, 10) #后面可以使用wait對特定元素進行等待 driver.get('http://qzone.qq.com/') # some code to work. print("Reach end.")

其中PageLoadStrategy有三種選擇:

(1) none: 當html下載完成之后,不等待解析完成,selenium會直接返回

(2) eager: 要等待整個dom樹加載完成,即DOMContentLoaded這個事件完成,僅對html的內容進行下載解析。注:在谷歌瀏覽器96.0.4664.110驗證不支持eager。

(3) normal: 即正常情況下,selenium會等待整個界面加載完成(指對html和子資源的下載與解析,如JS文件,圖片等,不包括ajax

以下這段來自https://blog.csdn.net/wkb342814892/article/details/81611737,感謝原作者

實際上,對於一個新加載的dom,頁面啥時候開始接受命令由頁面的加載策略決定,也就是說,我們通過修改頁面加載策略,可以使頁面即使處於加載中,也能接受我們的命令,從這點可以解決webdriver.get的阻塞問題。而每類webdriver都有一個對應的配置文件放在特定的類DesiredCapabilities里面,通過修改里面的pageLoadStrategy,可以使webdriver的頁面加載策略發生改變。

上面的代碼用了最后一種解析方式——none,不作等待,直接返回,然后在后面的代碼中可以用explicit_wait或者implicit_wait等方式來對特定元素進行等待捕捉。

 

2、4種等待

UI自動化測試,大多都是通過定位頁面元素來模擬實際的生產場景操作。但在編寫自動化測試腳本中,經常出現元素定位不到的情況,究其原因,無非兩種情況:1、有frame;2、沒有設置等待。

因為代碼運行速度和瀏覽器加載渲染速度,不是一個量級,所以導致了這種情況發生。webdriver提供了3種類型的等待:顯式等待、隱式等待、強制等待。

2.1、強制等待

即sleep()方法,由python中的time模塊提供,強制讓代碼等待xxx時間,無論前面的代碼是否執行完成或者還未完成,都必須等待設定的時間。

不建議用這種等待方法,嚴重影響代碼的執行速度。

示例代碼如下:

復制代碼
 1 # coding = utf-8
 2 from selenium import webdriver
 3 from time import sleep
 4  
 5 driver = webdriver.Chrome("F:\安裝工具\python\chromedriver.exe")
 6 driver.get('http://www.cnblogs.com/imyalost/')
 7 
 8 sleep(5)
 9  
10 print(driver.current_url)
11 driver.quit()
復制代碼

代碼解析:

本例中,設置強制等待時間為5秒,5秒之后,打印獲取到的當前頁面的url,然后關閉窗口。

這種強制等待的方法,在debug時候很有用,不過建議慎用這種方法,因為太死板,嚴重影響程序執行速度!

 

2.2、隱式等待

隱式等待是設置全局的查找頁面元素的等待時間,在這個時間內沒找到指定元素則拋出異常,只需設置一次。

driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);

所有的findElement方法都會隱式等待10s

 

2.3、顯示等待

定義:等待某個條件成立時繼續執行,否則在達到最大時長時拋出異常(TimeoutException);

WebDriverWait類是由webdriver提供的等待方法,配合該類提供的until()和until_not()方法一起使用,就可以根據判斷條件而靈活進行等待,格式如下:
復制代碼
1 WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
2 driver:瀏覽器驅動
3 timeout:最長超時時間
4 poll_frequency:檢測間隔時間,默認0.5s
5 ignored_exceptions:超時后的異常信息,默認情況拋出NoSuchElementException異常
6 WebDriverWait()一般由until()或until_not方法配合使用,下面是這兩種方法的說明: 7 until(method,message=''):調用該方法提供的驅動程序作為一個參數,直到返回值為True; 8 until_not(method,message=''):調用該方法提供的驅動程序作為一個參數,直到返回值為Flase;
復制代碼

示例代碼如下:

復制代碼
 1 # coding = utf-8
 2 from selenium import webdriver
 3 from selenium.webdriver.support.wait import WebDriverWait
 4 from selenium.webdriver.support import expected_conditions as EC
 5 from selenium.webdriver.common.by import By
 6  
 7 driver = webdriver.Chrome("F:\安裝工具\python\chromedriver.exe")
 8 driver.implicitly_wait(10)
 9 driver.get('http://www.cnblogs.com/imyalost/')
10 locator = (By.LINK_TEXT, '老_張')
11  
12 try:
13     WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located(locator))
14     print(driver.find_element_by_link_text('老_張').get_attribute('href'))
15 finally:
16     driver.close()
復制代碼

代碼解析:

本例中,通過as關鍵字將expected_conditions重命名為EC,並調用presence_of_element_located()方法判斷元素是否存在;

上面的例子中,同時使用了隱性等待和顯性等待,但是需要注意的是:等待的最長時間取兩者之中的最大值;

expected_conditions類提供的預期條件判斷方法如下:
復制代碼
 1 title_is: 判斷當前頁面的title是否完全等於(==)預期字符串,返回布爾值
 2 title_contains : 判斷當前頁面的title是否包含預期字符串,返回布爾值
 3 presence_of_element_located : 判斷某個元素是否被加到了dom樹里,並不代表該元素一定可見
 4 visibility_of_element_located : 判斷某個元素是否可見. 可見代表元素非隱藏,並且元素的寬和高都不等於0
 5 visibility_of : 跟上面的方法做一樣的事情,只是上面的方法要傳入locator,這個方法直接傳定位到的element就好了
 6 presence_of_all_elements_located : 判斷是否至少有1個元素存在於dom樹中。舉個例子,如果頁面上有n個元素的class都是‘column-md-3‘,那么只要有1個元素存在,這個方法就返回True
 7 text_to_be_present_in_element : 判斷某個元素中的text是否 包含 了預期的字符串
 8 text_to_be_present_in_element_value : 判斷某個元素中的value屬性是否 包含 了預期的字符串
 9 frame_to_be_available_and_switch_to_it : 判斷該frame是否可以switch進去,如果可以的話,返回True並且switch進去,否則返回False
10 invisibility_of_element_located : 判斷某個元素中是否不存在於dom樹或不可見
11 element_to_be_clickable : 判斷某個元素中是否可見並且是enable的,這樣的話才叫clickable
12 staleness_of : 等某個元素從dom樹中移除,注意,這個方法也是返回True或False
13 element_to_be_selected : 判斷某個元素是否被選中了,一般用在下拉列表
14 element_selection_state_to_be : 判斷某個元素的選中狀態是否符合預期
15 element_located_selection_state_to_be : 跟上面的方法作用一樣,只是上面的方法傳入定位到的element,而這個方法傳入locator
16 alert_is_present : 判斷頁面上是否存在alert
復制代碼

 

2.4、流暢等待: FluentWait

與顯示等待的 WebDriverWait類似,區別是WebDriverWait已經設置好幾個等待條件,而流暢等待 FluentWait可以自己設置等待條件。

 

3、如何提高運行速度

設置等待時間的時候,少用sleep,盡量不用implicitly_wait,多用顯式等待方法;

 

參考鏈接:

https://www.cnblogs.com/imyalost/p/7420924.html

https://www.cnblogs.com/qianjin100/p/9910699.html

https://blog.csdn.net/ouyanggengcheng/article/details/83036680


免責聲明!

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



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