【筆記】Selenium的三種等待方式

閱讀時間約 9 分鐘
為了更好的讓程式運行,或多或少會需要使用等待方式,順利的讓driver取得元素後順利運行,本篇會提到Selenium的三種等待方式,以及常用的操作語法。

等待方式有三種,分別是強制等待、隱性等待、顯性等待:

強制等待

from time import sleep ​
#強制等待10秒​
sleep(10)

強制等待在不管任何情況下,等待設定的時間,簡單易用,等待期間會完全暫停程式的執行,可用於單純的等待場景。

缺點:因為是無條件的固定等待時間,在一些比較複雜的情況下無法設定自己想要的情境,如果使用強制等待的目的是讓頁面某個元素出現,即便元素出現了,也是要繼續等待。


隱性等待

#隱性等待10秒​
driver.implicitly_wait(10)

隱性等待不用導入任何套件,是一個全局設定,整個WebDriver都適用,當等待元素出現在頁面時,就會繼續執行後面的程式,或是等待設定的秒數。

可以跟顯性等待混用,會取時間長的那個。

缺點:等待時間不夠精確,每個場景所需要的等待時間不一定一樣,沒辦法個別針對場景進行設定等待時間,會造成資源不必要的浪費,另外也沒有辦法特定等待條件:比如點一個按鈕,才會出現提示框,這種隱性等待就沒有辦法處理。


顯性等待

#顯性等待​
from selenium.webdriver.support.ui import WebDriverWait
#預期條件函數,網頁元素在瀏覽器中的的出現、可見、可點擊
from selenium.webdriver.support import expected_conditions
#等待超時異常處理
from selenium.common.exceptions import TimeoutException

#創造一個顯性等待,等待時間20秒,每1秒檢查一次、忽略找不到元素的錯誤​
driver_wait = WebDriverWait(driver, timeout=20, poll_frequency=1, ignored_exceptions=[NoSuchElementException])

顯性等待可以設定許多條件,來達到完全我們需要的場景,明確等待某個特定條件,等出現後才會去執行:


timeout,等待時間,以秒為單位,強制等待跟隱性等待的等待時間也是以秒為單位。

poll_frequency,指定等待條件檢查的頻率,以秒為單位,預設值是0.5秒,可以不設定,如果不設定的情況下,那WebDriver會按照預設值每0.5秒檢查一次元素是否出現,有設定則按照預設值。

ignored_exceptions,在等待期間希望忽略的例外錯誤,有些錯誤會導致程式的中斷,它可以很好的讓程式順利運行,常見的忽略類型如下:

  • NoSuchElementException:找不到元素,就是你的元素定位定錯了,可能多字或少字,或是方法錯了,比如NAME你用ID去搜。


  • TimeoutException:在設定的等待時間內仍找不到元素,有可能未加載完全或是其他原因導致。


  • StaleElementReferenceException:訪問已不存在的元素,原先存在的元素,因為進行了某些操作,該元素不見或是刷新頁面導致。


  • ElementNotVisibleException:當元素存在但不可見時,比如頁面把元素藏起來了,display: none 或是visibility: hidden,或是在頁面以外,需要往下滑動才會看到。


  • ElementNotSelectableException:當元素存在但不可點擊,比如登入按鈕需要帳號密碼都輸入才能點登入,如果帳號密碼沒有輸入時,就會出現此情況。

顯性等待語法我們可以簡化成:

#去除掉​參數文字,簡化的情況下,順序一定要是 時間、頻率、忽略例外錯誤
driver_wait = WebDriverWait(driver, 20, 0.5, [NoSuchElementException])

如果想同時忽略多個例外錯誤,直接後面繼續加就可以了:

#同時忽略多個錯誤
driver_wait = WebDriverWait(driver, 20, 1, [NoSuchElementException, ElementNotVisibleException, StaleElementReferenceException])


顯性等待實際使用

#這裡我們拿expected_conditions的字首e跟c出來取別名叫做EC,不然整串程式碼太長了
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException

​driver.get("https://www.google.com/")

#等待時間20秒,搜尋頻率1秒一次​
driver_wait = WebDriverWait(driver,20,1)

#顯性等待抓取元素​
search_box = driver_wait.until(EC.presence_of_element_located((By.NAME,"q")))

#隱性等待抓取元素​(對照組)
search_box = driver.find_element(By.NAME,"q")

說明:

1.創建WebDriverWait的物件時,需要有兩個參數是必要的,分別是瀏覽器的控制跟等待時間,這裡我們瀏覽器的控制是"driver",後面必填的是等待時間(timeout),至於頻率跟忽略例外錯誤是選配,可加可不加。

2.需要三層( )的原因是:

driver_wait.until( ) 第一層,用來指示要使用顯性等待。

EC.presence_of_element_located( )第二層,表示要使用的方法,像這裡是使用"元素出現"這個等待條件。

(By.NAME,"q")第三層,定位元素本身作為一種參數,外面需要一層套用在第二層上。

以下是 expected_conditions,或是說顯性等待常見的幾種等待條件:

presence_of_element_located:元素出現,元素存在DOM中並可以使用元素定位方法取得,字尾"located"指的是Locator(元素定位方法),像是(By.NAME,"皮卡丘")。

#​presence_of_element_located
search_box = driver_wait.until(EC.presence_of_element_located((By.NAME,"q")))


presence_of_all_elements_located:所有元素出現,元素存在DOM,並透過元素定位方法,把指定的元素都找出來,並形成一個陣列。

#​presence_of_all_elements_located
search_results = driver_wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "div.g")))


visibility_of_element_located:元素可見,元素存在瀏覽器畫面上,即元素沒有被隱藏(display:none、visibility:hidden),並且高寬都大於0,可用Locator定位。

#​visibility_of_element_located
search_box = driver_wait.until(EC.visibility_of_element_located((By.NAME,"q")))


element_to_be_clickable:元素可點擊,元素存在瀏覽器畫面,沒有被隱藏,並且可點擊,可用Locator定位。

#​element_to_be_clickable
search_box = driver_wait.until(EC.element_to_be_clickable((By.NAME,"q")))
search_box.click()


text_to_be_present_in_element:文本出現,等待網頁DOM可見,並且指定的元素出現特定的文本。

#​text_to_be_present_in_element
search_box = driver_wait.until(EC.text_to_be_present_in_element((By.ID, "pikachu"), "皮卡丘"))


alert_is_present:出現彈出窗口,當瀏覽器畫面出現彈窗時,做相應的處理。

#​alert_is_present,出現彈窗,印出提示,並接受
alert = driver_wait.until(EC.alert_is_present())
alert_text = alert.text
print("彈窗內容顯示:", alert_text)
alert.accept()


註:DOM,文件物件模型(Document Object Model),簡單來說就是瀏覽器開發者模式中,元素分頁那頁的內容。


至於顯性等待的缺點:它有點複雜



20會員
18Content count
留言0
查看全部
發表第一個留言支持創作者!
你可能也想看
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
从个人发展的角度来讲,我认为每个人都要有一点自己的长处,这个长处并不是人们常说的一些爱好之类的东西,而是个人身上那种相对稀缺的禀赋,或者是几种特质组合起来的独特性能。 这是任何时候都能保持一定竞争力的前提,也是一种不需要卷就能体现出来的个人优势。其实不需要对自己要求很高,只要在自己的领域高于平均,就
Thumbnail
在日常工作、学习、生活中,笔记软件成为重要的生产力工具。然而,如今的笔记软件百花齐放:云文档? 云笔记? 离线笔记? Markdown 编辑器? 块编辑器?双链笔记?在每个类别中,都有几十款比较有名的笔记软件。那么,我们应该如何选择这些适合自己的笔记软件呢? 文本编辑器的特征 文本编辑器的分类
取得最多列數 行數 openpyxl sheet.max_row sheet.max_column
Thumbnail
兩年多前,開始有了重新架構網站的想法,所以把 Blogger 架設的網站,移轉至到了新的平台,當年我也做過了一些優缺點評析,剛好最近又再重新整理網站的所有架構,順便也重新啟動了一次 Hugo 架設網站的循環。
什麼樣的社會運動,才算是成功的社會運動?或者,什麼樣的社會運動,才算有價值與完美的社會運動?這部紀錄片,並未給出一個正確的解答。 但……沒有答案,並不代表就不值得觀看,只因藉由這部紀錄片,我們可以省思在運動之後,這個社會是否得到了什麼?改善了什麼?前進了什麼?還是什麼也沒有,只是一段激情之後換來一股
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
从个人发展的角度来讲,我认为每个人都要有一点自己的长处,这个长处并不是人们常说的一些爱好之类的东西,而是个人身上那种相对稀缺的禀赋,或者是几种特质组合起来的独特性能。 这是任何时候都能保持一定竞争力的前提,也是一种不需要卷就能体现出来的个人优势。其实不需要对自己要求很高,只要在自己的领域高于平均,就
Thumbnail
在日常工作、学习、生活中,笔记软件成为重要的生产力工具。然而,如今的笔记软件百花齐放:云文档? 云笔记? 离线笔记? Markdown 编辑器? 块编辑器?双链笔记?在每个类别中,都有几十款比较有名的笔记软件。那么,我们应该如何选择这些适合自己的笔记软件呢? 文本编辑器的特征 文本编辑器的分类
取得最多列數 行數 openpyxl sheet.max_row sheet.max_column
Thumbnail
兩年多前,開始有了重新架構網站的想法,所以把 Blogger 架設的網站,移轉至到了新的平台,當年我也做過了一些優缺點評析,剛好最近又再重新整理網站的所有架構,順便也重新啟動了一次 Hugo 架設網站的循環。
什麼樣的社會運動,才算是成功的社會運動?或者,什麼樣的社會運動,才算有價值與完美的社會運動?這部紀錄片,並未給出一個正確的解答。 但……沒有答案,並不代表就不值得觀看,只因藉由這部紀錄片,我們可以省思在運動之後,這個社會是否得到了什麼?改善了什麼?前進了什麼?還是什麼也沒有,只是一段激情之後換來一股