一. 結論
presence_of_element_located和visibility_of_element_located都是selenium里判斷元素展示的方法,相信做ui自動化的小伙伴一定被這倆困擾過,本期做了一個方法測試。
先說結論:
- presence_of_element_located: 是否加載到dom樹
- visibility_of_element_located:是否加載到dom樹且長寬大於0。
說明:
- visibility_of_element_located為判斷是否"可見",可見還是不可見並不是以人眼為標准,而是頁面層級里是否有,包括被遮罩的層級,可以理解為加載到dom樹且長寬大於0。
- presence_of_element_located的校驗程度輕一些,在頁面跳轉之后判斷某種標志是否出現用這個快一些;特殊情況下校驗無邊框的元素也會用到這個。
二. 源碼查看
不少小伙伴為一探究竟,看源碼怎么寫的,源碼里調了js,也看不出個所以然,所以還得實際測試一下。。。
三. 測試兩個方法
測試中選擇了一個可見元素,一個部分可見元素,一個隱藏(人眼看不到,被遮住)的元素進行測試。
而 百度翻譯 網站剛好滿足這樣的場景。
選擇彈窗為可見的元素,搜索框為部分可見的元素,后面按鈕為看不見的元素。
下面通過代碼驗證:
from selenium import webdriver from selenium.common.exceptions import TimeoutException, ElementClickInterceptedException from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as ec bs = webdriver.Chrome() bs.get("https://fanyi.baidu.com/#zh/en/%E4%BD%93%E9%AD%84%2C%E6%8A%80%E6%9C%AF%2C%E8%8B%B1%E8%AF%AD") 彈窗 = '//span[@class="app-guide-close"]' 半可見的輸入框 = '//textarea[@id="baidu_translate_input"]' 被遮住的按鈕 = '//span[@class="op-check"]' # 彈窗:完全展示 try: x1 = WebDriverWait(bs, 3).until( ec.presence_of_element_located((By.XPATH, 彈窗))) print("彈窗加載到dom: ", x1) x1.click() except TimeoutException: print("彈窗沒加載到dom:") try: x1 = WebDriverWait(bs, 3).until( ec.visibility_of_element_located((By.XPATH, 彈窗))) print("彈窗可見: ", x1) # 確實可見 x1.click() except TimeoutException: print("彈窗沒加載到dom:") # 輸入框:展示了一半。本來就加載至dom了,只需測試visibility_of_element_located try: x2 = WebDriverWait(bs, 3).until( ec.visibility_of_element_located((By.XPATH, 半可見的輸入框))) print("輸入框可見: ", x2) # 此時輸入框被遮住了但還是顯示可見。由此得知,可見還是不可見並不是以人眼為標准,而是以層級里的元素是否展示了為准。 x2.click() x2.send_keys("你好世界") except (TimeoutException, ElementClickInterceptedException): print("輸入框不可見或被遮住了,或不可點擊") # 對照按鈕:根本看不到。本來就加載至dom了,只需測試visibility_of_element_located try: x2 = WebDriverWait(bs, 10).until( ec.visibility_of_element_located((By.XPATH, 被遮住的按鈕))) print("隱藏按鈕可見: ", x2) # 完全遮住的元素還是可見的,說明上面推斷正確。結論在下方。 x2.click() except (TimeoutException, ElementClickInterceptedException): print("隱藏按鈕不可見或被遮住了,或不可點擊") """ 結論: 1:presence_of_element_located: 是否加載到dom樹 2:visibility_of_element_located:是否"可見",可見還是不可見並不是以人眼為標准,加載到dom樹且長寬大於0。 ui自動化中操作的元素一般都是有長寬的,所以絕大大部分情況下,用2更好。 presence_of_element_located的校驗程度輕一些,在頁面跳轉之后判斷某種標志是否出現用這個快一些;特殊情況下校驗無邊框的元素也會用到這個。 """
通過測試,證實了結論中的猜想。仔細想想這也很符合邏輯,如果調整一下窗口大小、或者分辨率從而隱藏了元素,從而人眼看不到,如果這種情況下程序也知道你看不到,那么這個程序至少和瀏覽器外部環境交互了,顯然是不可能也很沒有必要的。
最后再次說一下結論:
- presence_of_element_located: 是否加載到dom樹
- visibility_of_element_located:是否加載到dom樹且長寬大於0。
- visibility_of_element_located為判斷是否"可見",可見還是不可見並不是以人眼為標准,而是頁面層級里是否有,包括被遮罩的層級,可以理解為加載到dom樹且長寬大於0。
- presence_of_element_located的校驗程度輕一些,在頁面跳轉之后判斷某種標志是否出現用這個快一些;特殊情況下校驗無邊框的元素也會用到這個。