Web自動化測試 五 ----- selenium的等待和切換

樂樂先生發表於2019-07-21

一、selenium的三種等待

當執行python的selenium程式碼時,如果需要定位一個元素或者點選一個元素,需要考慮到網速等多方面原因,導致頁面載入速度慢,元素還未載入出來,這樣就會導致找不到對應元素,從而報錯的問題,所以要設定等待條件,等待元素載入出來後才執行相應的程式碼。

其中,selenium中有三種等待方式,下面一一進行介紹。

1、強制等待

最簡單的一種方式,直接引入time模組,設定等待時間,但這種方式實用性不高,設定時間太短元素仍未找到,設定時間過長影響效率。

import time

time.sleep(5) 

2、顯式等待

原理:指定一個等待條件,和一個最長等待時間,程式會判斷在等待時間內條件是否滿足,如果滿足則返回,如果不滿足會繼續等待,超過時間就會丟擲異常。

(簡而言之,就是直到元素出現才去操作,如果超時則報異常)from selenium.webdriver import Chromefrom selenium.webdriver.support.wait import WebDriverWait

 

 

from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC


browser = Chrome() # 瀏覽器物件

browser.get('http://www.baidu.com') # 訪問百度頁面

e = browser.find_element_by_id('kw')

# 傳送資料,輸入文字
e.send_keys('檸檬班')

# 快速點選,查詢父節點如果有form表單就會直接提交
e.submit()

wait = WebDriverWait(browser, 20)

e = wait.until(EC.visibility_of_element_located((By.XPATH, "//a[contains(text(), 'lemon.ke.qq.com/' )]")))

e = browser.find_element_by_xpath("//a[contains(text(), 'lemon.ke.qq.com/' )]")

print(e)



WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
 
driver:瀏覽器驅動

timeout:最長超過時間,預設以秒為單位

poll_frequency:監測的時間間隔,預設為0.5

ignored_exceptions:超時後的異常資訊,預設情況下拋NoSuchElementException異常

WebDriverWait一般有until和until_not方法配合使用

until(method,message)

until_not(method ,message)
 

until中的所有方法:

title_is 標題是某內容
title_contains 標題包含某內容
presence_of_element_located 元素載入出,傳入定位元組,如(By.ID, 'p')
visibility_of_element_located 元素可見,傳入定位元組
visibility_of 可見,傳入元素物件
presence_of_all_elements_located 所有元素載入出
text_to_be_present_in_element 某個元素文字包含某文字
text_to_be_present_in_element_value 某個元素值包含某文字
frame_to_be_available_and_switch_to_it frame載入並切換
invisibility_of_element_located 元素不可見
element_to_be_clickable 元素可點選
staleness_of 判斷一個元素是否仍在DOM,可判斷頁面是否已經重新整理
element_to_be_selected 元素可選擇,傳元素物件
element_located_to_be_selected 元素可選擇,傳入定位元組
element_selection_state_to_be 傳入元素物件以及狀態,相等返回True,否則返回False
element_located_selection_state_to_be 傳入定位元組以及狀態,相等返回True,否則返回False
alert_is_present 是否出現Alert

3、隱式等待

原理:隱式等待,就是在建立driver時,為瀏覽器物件建立一個等待時間,這個方法是得不到某個元素就等待一段時間,直到拿到某個元素位置。

當使用了隱式等待執行測試的時候,如果 WebDriver沒有在 DOM中找到元素,將繼續等待,超出設定時間後則丟擲找不到元素的異常,換句話說,當查詢元素或元素並沒有立即出現的時候,隱式等待將等待一段時間再查詢 DOM,預設的時間是0。

缺點:侷限性高,只能用來等元素出現,或者是某個指令沒有完成,並不能等待所有情況,只能等待很少的一部分。

 

from selenium.webdriver import Chrome

browser = Chrome() # 瀏覽器物件

# 開啟隱式等待,全域性只需放一次
browser.implicitly_wait(30)
 
browser.implicitly_wait(10)  # 等待十秒載入不出來就會丟擲異常,10秒內載入出來正常返回
browser.get('http://www.baidu.com')
e = browser.find_element_by_id('kw')
print(e)

 

implicity_wait()預設引數的單位為秒,本例中設定等待時長為10秒,首先這10秒並非一個固定的等待時間,它並不影響指令碼的執行速度。其次,它並不針對頁面上的某一元素進行等待。當指令碼執行到某個元素定位時,如果元素可以定位,則繼續執行,如果元素定位不到,則它將以輪詢的方式不斷地判斷元素是否被定位到。假設在第六秒定位到了元素則繼續執行,若直到超出設定的時長10秒還沒有定位到元素,則丟擲異常。

 

二、selenium的三種切換

1、視窗切換

原理:獲取開啟新視窗之前的控制程式碼(列表),然後在獲取開啟新視窗之後的控制程式碼,使用browser.switch_to.window(handles[-1])方法切換到最新視窗。

from selenium.webdriver import Chrome
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

browser = Chrome() # 瀏覽器物件

# 開啟隱式等待,全域性只需放一次
browser.implicitly_wait(30)  # 30S之內只要元素出現就結束,每一個元素都有30S

browser.get('http://www.baidu.com')

e = browser.find_element_by_id('kw')  # 型別e WebElement

# 傳送資料,輸入文字
e.send_keys('檸檬班')

# 快速點選,查詢父節點如果有form表單就會直接提交
e.submit()

# 定定位百度一下
# e_submit = browser.find_element_by_id('su')
# e_submit.click()

# time.sleep(10)

# 定時器
wait = WebDriverWait(browser, 20)

e = wait.until(EC.visibility_of_element_located((By.XPATH, "//a[contains(text(), 'lemon.ke.qq.com/' )]")))

e = browser.find_element_by_xpath("//a[contains(text(), 'lemon.ke.qq.com/' )]")

handles = browser.window_handles # 是一個列表  獲取控制程式碼的動作一定要放到click之前,因為new_window_is_opened是要比較控制程式碼數量

e.click()

print(browser.window_handles)
# 切換視窗,可能視窗沒開啟,也是需要等待的,必須要用顯示等待
# 定時器
wait = WebDriverWait(browser, 20)
e = wait.until(EC.new_window_is_opened(handles))
browser.switch_to.window(handles[-1])

wait = WebDriverWait(browser, 20)
e = wait.until(EC.visibility_of_element_located((By.XPATH, "//h4[text()='華華老師']")))
# 找到華華 huahua = browser.find_element_by_xpath("//h4[text()= '華華老師' ]")

print(huahua)  

注意:獲取控制程式碼的動作一定要放到click之前,因為new_window_is_opened是要比較控制程式碼數量。

 

2、iframe切換

from selenium.webdriver import Chrome
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

browser = Chrome() # 瀏覽器物件

# 開啟隱式等待,全域性只需放一次
browser.implicitly_wait(30)  # 30S之內只要元素出現就結束,每一個元素都有30S

browser.get('http://www.baidu.com')

# iframe 等待
wait = WebDriverWait(browser, 20)
e = wait.until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, '//iframe[@name="iframe2"]')))
# 會自動進行切換,不用再單獨進行切換

# browser.switch_to.frame('iframe2')
e = browser.find_element_by_id('kw')
print(e)
"""
:Usage:
driver.switch_to.frame('frame_name') 
driver.switch_to.frame(1) 索引
driver.switch_to.frame(driver.find_elements_by_tag_name("iframe")[0])  webelement物件切換
"""
iframe_e = browser.find_element_by_xpath('//iframe[@name="iframe2"]')
browser.switch_to.frame(iframe_e) 

3、彈框切換

 

相關文章