Selenium 之顯性等待詳解
本文轉(zhuǎn)載自微信公眾號「Python技術」,作者派森醬 。轉(zhuǎn)載本文請聯(lián)系Python技術公眾號。
上次介紹了下 Selenium 元素等待的三種方法,以及每種元素等待方法的優(yōu)缺點,在使用場景下該如何操作。并寫了一些具體使用的簡單例子,給大家作為參考。后臺看到大家對顯性等待比較感興趣,想詳細了解下如何使用,今天就來繼續(xù)跟大家詳細介紹下。
顯性等待使用
在使用 WebDriverWait 調(diào)用可執(zhí)行方法,除了可定位的元素,還可以使用 selenium 提供的 expected_conditions 模塊中的各種條件,也可以使用 WebElement 的 is_enabled(),is_selected(),is_displayed() 等等方法,還可以使用自己封裝的方法。
這次我們換百度官網(wǎng)測試,首先我先上一段使用顯性等待的標準使用方式,這里使用的 LINK_TEXT 查找的元素:
- # 導入庫
- from selenium import webdriver
- from selenium.webdriver.support.ui import WebDriverWait
- from selenium.webdriver.support import expected_conditions as ECS
- from selenium.webdriver.common.by import By
- import time
- # executable_path 用于指定driver存放路徑
- browser = webdriver.Chrome(executable_path='/Users/xx/python/chromedriver')
- # 打開京東官網(wǎng)
- browser.get('https://www.baidu.com/')
- # 定位要查找的元素
- loc = (By.LINK_TEXT, "關于百度")
- try:
- # 等待5秒,直到發(fā)現(xiàn)元素
- WebDriverWait(driver, 5).until(ECS.presence_of_element_located(loc))
- except:
- # 沒有發(fā)現(xiàn)元素則會打印提示
- print("沒有找到對應元素!")
- finally:
- # 發(fā)現(xiàn)元素則執(zhí)行下面的方法
- driver.find_element_by_link_text('關于百度').click()
- #退出瀏覽器
- browser.quit()
顯性等待方式介紹
好了,知道顯性等待怎么用了,接下來我們來看下,還有哪些其他常見的使用方式:
- 先來個簡單的,這里通過頁面標題來判斷
- # 元素等待直到標題出現(xiàn) `百度一下,你就知道`
- WebDriverWait(driver,3).until(ECS.title_is('百度一下,你就知道'))
- # 元素等待直到標題出現(xiàn)包含 `百度` 即可
- WebDriverWait(driver,3).until(ECS.title_contains('百度'))
- 通常在網(wǎng)頁中并不是所有元素都是可見的,也有的是初始化時不可見,加載完成時則狀態(tài)又變?yōu)榭梢?,所以在元素等待中以下這些方式是經(jīng)常被用到的。
- # 元素等待直到能定位到元素,這里是定位到搜索輸入框
- # 這里定位時不關心元素是否可見,只要是加載到DOM中能定位到即可
- WebDriverWait(driver,3).until(ECS.presence_of_element_located((By.ID,'kw')))
- # 元素等待直到能定位到可見的元素,比如這里定位到搜索按鈕
- # 和上面不同,這里等待的元素除加載DOM中,也必須可見
- WebDriverWait(driver,3).until(ECS.visibility_of_element_located((By.ID,'su')))
- # 元素等待直到能定位到可見的元素,比如這里定位到搜索框
- # 這個方法和上面 `visibility_of_element_located` 使用類似
- WebDriverWait(driver,3).until(ECS.visibility_of((By.ID,value='su')))
- # 元素等待直到通過 `CSS` 定位到至少有一個元素存在,則結(jié)束等待
- WebDriverWait(driver,3).until(ECS.presence_of_all_elements_located((By.CSS_SELECTOR,'.uinv')))
- # 這和上一個等待方法類似,主要就是需要元素可見才會結(jié)束等待
- WebDriverWait(driver,3).until(ECS.visibility_of_any_elements_located((By.CSS_SELECTOR,'.uinv')))
- # 元素等待直到元素被加載,可以定位到并且元素必須為不可見狀態(tài),才會結(jié)束等待
- WebDriverWait(driver,3).until(ECS.invisibility_of_element_located((By.CSS_SELECTOR,'#nwWrap')))
- 在平時使用中,也經(jīng)常會用到等待的元素包含某些內(nèi)容來判斷,而且這種方式能適用很多場景
- # 元素等待直到定位到指定的元素,并且元素的屬性值中包含指定的字符串
- WebDriverWait(driver,3).until(ECS.text_to_be_present_in_element((By.XPATH,"//*[@id='bottom_layer']/div/p[1]/a"),'關于百度'))
- # 這種實現(xiàn)跟上面效果差不多
- WebDriverWait(driver,3).until(ECS.text_to_be_present_in_element_value((By.CSS_SELECTOR,'#su'),'百度一下'))
- 下面幾種方式主要是針對下拉框類型的等待,還有可點擊的組件,如超鏈接
- # 元素等待直到元素被加載,為可見狀態(tài),并且是可點擊的狀態(tài),才會結(jié)束等待
- WebDriverWait(driver,3).until(ECS.element_to_be_clickable((By.XPATH,"//*[@id='bottom_layer']/div/p[1]/a"))).click()
- # 元素等待直到元素被加載,可見狀態(tài)并且這個元素是被選中的狀態(tài)
- # 這種方式我運用于下拉選擇框
- WebDriverWait(driver,3).until(ECS.element_to_be_selected((By.XPATH,"//*[@id='sel']/option[2]")))
- # 元素等待直到元素被加載后,并且元素選中狀態(tài)為預期的狀態(tài),才會結(jié)束等待
- WebDriverWait(driver,3).until(ECS.element_selection_state_to_be((By.XPATH,"//*[@id='sel']/option[1]"),False))
- 以下是比較特殊的幾種方式,在某些情況下用處很大
- # 元素等待直到頁面加載出現(xiàn) `alert`,出現(xiàn)自己切換過去并將提示內(nèi)容返回
- WebDriverWait(driver,3).until(ECS.alert_is_present())
- # 其他都是等待加載元素并操作,這種是等待元素被從Dom中移除時,才會觸發(fā)結(jié)束等待
- WebDriverWait(driver,3).until(ECS.staleness_of(driver.find_element(By.ID,'su')))
- # 這種是頁面有多個Frame時,等待頁面加載直到 `frame1` 可以切換進去,這時就會自動切換到 `frame1` ,然后結(jié)束等待
- WebDriverWait(driver,3).until(ECS.frame_to_be_available_and_switch_to_it(frame1))
除了上面這些,還有很多其他的方式,這里就不再一一列舉了,大家有興趣可以自己去研究一下,然后寫些小例子實際使用下。
對了,有小伙伴問如果隱性等待和顯性等待都使用了,那它會按哪種方式等待呢?在這里說下,它會按等待時間較長的設置為最終等待時間。
總結(jié)
好了,今天我們又介紹了下 Selenium 顯性等待元素加載的方式,詳細介紹并列舉了一些常見場景使用的例子,給大家學習參考,后續(xù)還會為大家介紹更多。