一、時間等待
我們知道在現實中我們操作瀏覽器,瀏覽網頁,我們都會自主去等待瀏覽器每一次響應給你,這個時間往往會很短,1秒-3秒,若網速不好 或服務器性能較差,可能這個時間更長
我們學習selenium 就是模擬我們現實中的操作,但是代碼往往會很快的執行,這樣那會導致很多的問題,為了讓我們開發出來的自動化腳本 穩定性,和健壯性更強 我們也要在部分環節給它加點時間等待
時間等待有三種:強制等待 、隱式等待、顯示等待
其中的 顯示等待和隱式等待 由 WebDriver提供,強制等待是使用python自帶的時間模塊
1.1、 強制等待
就是硬等待,使用time.sleep()該方法會讓當前執行進程暫停一段時間。
主要作用:
減慢運行速度,方便觀察操作效果,有助於腳本正常運行。
優點:
使用方便,哪里需要等待加哪里,不需要考慮任何邏輯,只影響下一條語句執行時間。
缺點:
就是無法應對復雜的環境,等待時間比較固定,你不能確定元素多久能加載完全,如果兩秒元素加載出來了,你用了30秒,造成腳本執行時間上的浪費。
單位是秒:s
from selenium import webdriver
from time import sleep
options = webdriver.ChromeOptions()
# 指定驅動
driver_path = "D:\\drivers\\chromedriver.exe"
driver = webdriver.Chrome(driver_path,options=options)
# 先打開百度網頁
driver.get("http://www.baidu.com")
# 強制等待3秒
sleep(3)
driver.find_element_by_id("kw").send_keys("selenium")
driver.quit()
1.2 隱式等待
WebDriver提供了implicitly_wait()方法來實現隱式等待,默認設置為0。
主要作用:對元素查找,元素操作時,給一定的緩沖時間去完成。在瀏覽器打開時 設置一次即可 implicitly_wait()
優點:
設置一次 后續一直生效全局的等待,該等待設置對整個driver生命周期都能起到作用,對元素查找,操作都起作用。
只需設置最大等待時間,比較靈活
達到最大等待時間沒有滿足 則報錯:NoSuchElementException
缺點:
無法對指定的元素進行等待
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from time import ctime
driver = webdriver.Chrome("D:\\chromedriver.exe")
# 設置隱式等待為10秒
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
try:
print(ctime())
driver.find_element_by_id("kw22").send_keys('selenium')
except NoSuchElementException as e:
print(e)
finally:
print(ctime())
driver.quit()
implicitly_wait() 默認參數的單位為秒,本例中設置等待時長為10秒。首先這10秒並非一個固定的等待時間,它並不影響腳本的執行速度。其次,它並不針對頁面上的某一元素進行等待。當腳本執行到某個元素定位時,如果元素可以定位,則繼續執行;如果元素定位不到,則它將以輪詢的方式不斷地判斷元素是否被定位到。假設在第6秒定位到了元素則繼續執行,若直到超出設置時長(10秒)還沒有定位到元素,則拋出異常。
1.3、顯示等待
針對某個元素來設置的等待時間,在整個頁面查找某個元素,如果在設定的時間內間隔時間查找到元素,則繼續執行下邊的代碼,如果未在規定的時間內完成加載則拋出異常,可以設置最長等待時間和查找控件的頻率,針對受網絡影響,加載緩慢的控件使用方便
作用 :
等待指定的元素,在設置最大時間內不斷檢查,一旦找到該元素,則停止等待,進入后續步驟,超時則拋出超時異常(TimeoutException)
優點:針對性,設置最大等待時間,比較靈活
缺點:步驟繁瑣 方法多不易選擇
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from datetime import datetime
from time import sleep
driver = webdriver.Chrome("D:\\chromedriver.exe")
driver.get("https://www.baidu.com")
print(datetime.now())
element = WebDriverWait(driver, 5, 0.5).until(
EC.presence_of_element_located((By.ID, "kj"))
)
element.send_keys('selenium')
sleep(5)
driver.quit()
WebDriverWait類是由WebDirver 提供的等待方法。在設置時間內,默認每隔一段時間檢測一次當前頁面元素是否存在,如果超過設置時間檢測不到則拋出異常。具體格式如下:
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
參數:
driver:瀏覽器驅動對象
timeout:最長超時時間,默認以秒為單位
poll_frequency:檢測的間隔(步長)時間,默認為0.5S
ignored_exceptions :超時后的異常信息,默認情況下拋NoSuchElementException異常。
WebDriverWait()一般由until()或until_not()方法配合使用,下面是until()和until_not()方法的說明。
until(method, message='') 調用該方法提供的驅動程序作為一個參數,直到返回值為True
until_not(method, message='') 調用該方法提供的驅動程序作為一個參數,直到返回值為False。
expected_conditions類提供的預期條件判斷方法如下:
方法 | 描述 |
---|---|
element_to_be_clickable(element) | 判斷某個元素中是否可點擊 |
element_to_be_selected(element) | 判斷元素是否被選中了,一般用在下拉列表 |
element_located_to_be_selected(locator) | 判斷指定元素是否被選中 |
element_selection_state_to_be(element,is_selected) | 判斷某個元素的選中狀態是否符合預期 |
element_located_selection_state_to_be | 跟上面的方法作用一樣,只是上面的方法傳入定位到的element,而這個方法傳入locator |
presence_of_element_located(locater) | 判斷某個元素是否被加到了dom樹里,並不代表該元素一定可見 |
presence_of_all_elements_located(locator) | 判斷是否至少有1個元素存在於dom樹中。舉個例子,如果頁面上有n個元素的class都是‘column-md-3‘,那么只要有1個元素存在,這個方法就返回True |
text_to_be_present_in_element(locator,text) | 判斷某個元素中的text是否 包含了預期的字符串 |
visibility_of_element_located(locator) | 判斷某個元素是否可見. 可見代表元素非隱藏,並且元素的寬和高都不等於0 |
visibility_of | 跟上面的方法做一樣的事情,只是上面的方法要傳入locator,這個方法直接傳定位到的element就好了 |
title_is(title) | 判斷當前頁面的title是否完全等於(==)預期字符串,返回布爾值 |
url_to_be(url) | 判斷url是否等於指定的url |
title_contains(title) | 判斷當前頁面的title是否包含預期字符串,返回布爾值 |
text_to_be_present_in_element_value() | 判斷某個元素中的value屬性是否 包含 了預期的字符串 |
frame_to_be_available_and_switch_to_it | 判斷該frame是否可以switch進去,如果可以的話,返回True並且switch進去,否則返回False |
invisibility_of_element_located | 判斷某個元素中是否不存在於dom樹或不可見 |
staleness_of | 等某個元素從dom樹中移除,注意,這個方法也是返回True或False |
alert_is_present | 判斷頁面上是否存在js彈框 |