強制等待

彭灰發表於2024-04-10

強制等待

即sleep()方法,由python中的time模組提供,強制讓程式碼等待xxx時間,無論前面的程式碼是否執行完成或者還未完成,都必須等待設定的時間。
示例程式碼如下:

# coding = utf-8
from selenium import webdriver
from time import sleep

driver = webdriver.Chrome()
driver.get('http://www.baidu.com/')

sleep(5)

print(driver.current_url)
driver.quit()



隱式等待

1、透過設定的時長等待頁面元素載入完成,再執行下面的程式碼,如果超過設定時間還未載入完成,則繼續執行下面的程式碼(注意:在設定時間內載入完成則立即執行下面的程式碼);
隱式等待的方法為:implicitly_wait,示例程式碼如下:

# coding = utf-8
from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(10) # 隱性等待,最長等10秒
driver.get('http://www.baidu.com/')

print(driver.current_url)
driver.quit()

本例中,設定的等待時長為10秒,但這10秒並非一個固定時間,並不影響指令碼執行速度;其次,隱式等待對整個driver的週期都起作用,因此只需要設定一次即可。


顯示等待

等待某個條件成立時繼續執行,否則在達到最大時長時丟擲異常(TimeoutException);
1、導包:

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec

2、使用技巧

wait = WebDriverWait(self.driver, 5)
wait.until(ec.text_to_be_present_in_element((by.XPATH, '//*[@id="hasContentDiv"]/div[1]/h2'), '章節列表'))

3、原始碼解析

class WebDriverWait(Generic[D]):
    def __init__(
        self,
        driver: D,   
        timeout: float,  #超時時長
        poll_frequency: float = POLL_FREQUENCY,  #輪詢時間間隔
        ignored_exceptions: typing.Optional[WaitExcTypes] = None, #忽略異常
    ):




def until(self, method: Callable[[D], Union[Literal[False], T]], message: str = "") -> T:
    """Calls the method provided with the driver as an argument until the \
    return value does not evaluate to ``False``.

    :param method: callable(WebDriver)
    :param message: optional message for :exc:`TimeoutException`
    :returns: the result of the last call to `method`
    :raises: :exc:`selenium.common.exceptions.TimeoutException` if timeout occurs
    """
    screen = None
    stacktrace = None

    end_time = time.monotonic() + self._timeout
    while True:
        try:
            value = method(self._driver) # 呼叫傳入的方法,有返回值則正常返回
            if value:
                return value
        except self._ignored_exceptions as exc:
            screen = getattr(exc, "screen", None)
            stacktrace = getattr(exc, "stacktrace", None)
        time.sleep(self._poll) # 出現異常或者無返回值時,等待輪詢時間間隔
        if time.monotonic() > end_time:
            break # 達到超時時長,迴圈結束
    raise TimeoutException(message, screen, stacktrace) # 達到超時時長,丟擲異常
    
    
until方法傳入可呼叫物件型別method、異常放回欄位message。找到element或者返回true時迴圈結束。

def until_not(self, method: Callable[[D], T], message: str = "") -> Union[T, Literal[True]]:
    ...
until_not方法功能與until相反。未找到element或者返回false時迴圈結束。

4、until方法入參中常用的method

title_is(title: str)-> Callable[[WebDriver], bool]:標題是某內容

title_contains(title: str)-> Callable[[WebDriver], bool]:標題包含某內容

presence_of_element_located(locator: Tuple[str, str])-> Callable[[WebDriverOrWebElement], WebElement]:元素載入出,傳入定位元組,如(By.ID, 'p')

url_contains(url: str) -> Callable[[WebDriver], bool]:當前url是否包含某個欄位

url_matches(pattern: str) -> Callable[[WebDriver], bool]:當前url是否包含傳入的pattern

url_to_be(url: str) -> Callable[[WebDriver], bool]:當前url是否為傳入欄位

url_changes(url: str) -> Callable[[WebDriver], bool]:當前url是否不等於傳入欄位

visibility_of_element_located(
    locator: Tuple[str, str]
) -> Callable[[WebDriverOrWebElement], Union[Literal[False], WebElement]]:元素可見,傳入定位元組

visibility_of(element: WebElement) -> Callable[[Any], Union[Literal[False], WebElement]]:可見,傳入元素物件

presence_of_all_elements_located(locator: Tuple[str, str]) -> Callable[[WebDriverOrWebElement], List[WebElement]]:所有元素載入出
    
visibility_of_any_elements_located(locator: Tuple[str, str]) -> Callable[[WebDriverOrWebElement], List[WebElement]]:判斷頁面至少有一個元素可見 visible,傳入locator,一旦定位就返回 the list of located WebElements;不可見(元素隱藏 或是 完全不存在,一個都沒有)返回的是 空列表;
和顯式等待結合後, 符合 最少存在一個WebElement的 返回符合定位元素條件WebElement的列表,不可見(元素隱藏 或是 完全不存在的)顯式等待+報錯;

visibility_of_all_elements_located(
    locator: Tuple[str, str]
) -> Callable[[WebDriverOrWebElement], Union[List[WebElement], Literal[False]]]:判斷頁面all elements存在且可見 visible
all elements are present and visible;傳入locator,全部符合的 就返回 the list of located and visible WebElements;不能全部符合的返回False;不存在的元素返回 空列表; 和顯式等待結合後,符合 全部可見WebElement的 返回符合定位元素條件WebElement的列表,找不到元素的 + WebElement不能全部可見的 顯式等待+報錯

text_to_be_present_in_element:某個元素文字包含某文字

text_to_be_present_in_element_value:某個元素值包含某文字

text_to_be_present_in_element_attribute(
    locator: Tuple[str, str], attribute_: str, text_: str
) -> Callable[[WebDriverOrWebElement], bool]:某個元素屬性包含某文字

frame_to_be_available_and_switch_to_it(locator: Union[Tuple[str, str], str]) -> Callable[[WebDriver], bool]:frame載入並切換
    
invisibility_of_element_located(
    locator: Union[WebElement, Tuple[str, str]]
) -> Callable[[WebDriverOrWebElement], Union[WebElement, bool]]:元素是否不可見
    
invisibility_of_element(
    element: Union[WebElement, Tuple[str, str]]
) -> Callable[[WebDriverOrWebElement], Union[WebElement, bool]]:元素是否不可見
    
element_to_be_clickable(
    mark: Union[WebElement, Tuple[str, str]]
) -> Callable[[WebDriverOrWebElement], Union[Literal[False], WebElement]]:元素是否可點選
    
staleness_of(element: WebElement) -> Callable[[Any], bool]:判斷一個元素是否仍在DOM,可判斷頁面是否已經重新整理
    
element_to_be_selected(element: WebElement) -> Callable[[Any], bool]:元素是否可選擇,傳元素物件
    
element_located_to_be_selected(locator: Tuple[str, str]) -> Callable[[WebDriverOrWebElement], bool]:元素可選擇,傳入定位元組

    
element_selection_state_to_be(element: WebElement, is_selected: bool) -> Callable[[Any], bool]:傳入元素物件以及狀態,相等返回True,否則返回False
    
element_located_selection_state_to_be(
    locator: Tuple[str, str], is_selected: bool
) -> Callable[[WebDriverOrWebElement], bool]:傳入定位元組以及狀態,相等返回True,否則返回False
    
    
number_of_windows_to_be(num_windows: int) -> Callable[[WebDriver], bool]:特定視窗數和實際視窗數是否一致
    
new_window_is_opened(current_handles: List[str]) -> Callable[[WebDriver], bool]:新視窗是否開啟 
    
alert_is_present() -> Callable[[WebDriver], Union[Alert, Literal[False]]]:是否出現Alert
    
element_attribute_to_include(locator: Tuple[str, str], attribute_: str) -> Callable[[WebDriverOrWebElement], bool]:是否包含某個屬性
    
any_of(*expected_conditions: Callable[[D], T]) -> Callable[[D], Union[Literal[False], T]]:對多個期望條件中的任何一個為真則為真。
    
all_of(
    *expected_conditions: Callable[[D], Union[T, Literal[False]]]
) -> Callable[[D], Union[List[T], Literal[False]]]:對多個期望條件中的所有條件為真則為真
    
none_of(*expected_conditions: Callable[[D], Any]) -> Callable[[D], bool]:對多個期望條件中的所有條件為假則為真

5、日常用法

可用作元素查詢或者斷言動作是否生效

相關文章