diff --git a/DrissionPage/driver_element.py b/DrissionPage/driver_element.py index 5029204..c52f9ed 100644 --- a/DrissionPage/driver_element.py +++ b/DrissionPage/driver_element.py @@ -110,9 +110,9 @@ class DriverElement(DrissionElement): def ele(self, loc_or_str: Union[Tuple[str, str], str], timeout: float = None): - """返回当前元素下级符合条件的第一个元素、属性或节点文本 \n + """返回当前元素下级符合条件的第一个元素、属性或节点文本 \n :param loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串 - :param timeout: 查找元素超时时间 + :param timeout: 查找元素超时时间,默认与元素所在页面等待时间一致 :return: DriverElement对象或属性、文本 """ return self._ele(loc_or_str, timeout) @@ -120,9 +120,9 @@ class DriverElement(DrissionElement): def eles(self, loc_or_str: Union[Tuple[str, str], str], timeout: float = None): - """返回当前元素下级所有符合条件的子元素、属性或节点文本 \n + """返回当前元素下级所有符合条件的子元素、属性或节点文本 \n :param loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串 - :param timeout: 查找元素超时时间 + :param timeout: 查找元素超时时间,默认与元素所在页面等待时间一致 :return: DriverElement对象或属性、文本组成的列表 """ return self._ele(loc_or_str, timeout=timeout, single=False) @@ -351,15 +351,19 @@ class DriverElement(DrissionElement): :param timeout: 尝试点击的超时时间,不指定则使用父页面的超时时间 :return: 是否点击成功 """ + + def do_it() -> bool: + try: + self.inner_ele.click() + return True + except Exception: + return False + if not by_js: timeout = timeout if timeout is not None else self.page.timeout t1 = perf_counter() - while perf_counter() - t1 <= timeout: - try: - self.inner_ele.click() - return True - except Exception: - pass + while not do_it() and perf_counter() - t1 <= timeout: + pass # 若点击失败,用js方式点击 if by_js is not False: diff --git a/DrissionPage/driver_page.py b/DrissionPage/driver_page.py index 1a9c56d..26e4f80 100644 --- a/DrissionPage/driver_page.py +++ b/DrissionPage/driver_page.py @@ -7,7 +7,7 @@ from glob import glob from os import sep from pathlib import Path -from time import sleep +from time import sleep, perf_counter from typing import Union, List, Any, Tuple from urllib.parse import quote @@ -95,9 +95,9 @@ class DriverPage(BasePage): def ele(self, loc_or_ele: Union[Tuple[str, str], str, DriverElement, WebElement], timeout: float = None) -> Union[DriverElement, List[DriverElement], str, None]: - """返回页面中符合条件的第一个元素 \n + """返回页面中符合条件的第一个元素 \n :param loc_or_ele: 元素的定位信息,可以是元素对象,loc元组,或查询字符串 - :param timeout: 查找元素超时时间 + :param timeout: 查找元素超时时间,默认与页面等待时间一致 :return: DriverElement对象或属性、文本 """ return self._ele(loc_or_ele, timeout) @@ -105,9 +105,9 @@ class DriverPage(BasePage): def eles(self, loc_or_str: Union[Tuple[str, str], str], timeout: float = None) -> List[DriverElement]: - """返回页面中所有符合条件的元素 \n + """返回页面中所有符合条件的元素 \n :param loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串 - :param timeout: 查找元素超时时间 + :param timeout: 查找元素超时时间,默认与页面等待时间一致 :return: DriverElement对象或属性、文本组成的列表 """ return self._ele(loc_or_str, timeout, single=False) @@ -489,18 +489,20 @@ class DriverPage(BasePage): :param mode: 'ok' 或 'cancel',若输入其它值,不会按按钮但依然返回文本值 :param text: 处理prompt提示框时可输入文本 :param timeout: 等待提示框出现的超时时间 - :return: 提示框内容文本 + :return: 提示框内容文本,未等到提示框则返回None """ - timeout = timeout if timeout is not None else self.timeout - from time import perf_counter - alert = None - t1 = perf_counter() - while perf_counter() - t1 <= timeout: + + def do_it(): try: - alert = self.driver.switch_to.alert - break + return self.driver.switch_to.alert except NoAlertPresentException: - pass + return False + + timeout = timeout if timeout is not None else self.timeout + t1 = perf_counter() + alert = do_it() + while not alert and perf_counter() - t1 <= timeout: + alert = do_it() if not alert: return None diff --git a/DrissionPage/shadow_root_element.py b/DrissionPage/shadow_root_element.py index 9029f31..994d6bc 100644 --- a/DrissionPage/shadow_root_element.py +++ b/DrissionPage/shadow_root_element.py @@ -4,6 +4,7 @@ @Contact : g1879@qq.com @File : shadow_root_element.py """ +from time import perf_counter from typing import Union, Any, Tuple, List from selenium.webdriver.remote.webelement import WebElement @@ -98,7 +99,7 @@ class ShadowRootElement(BaseElement): timeout: float = None) -> Union[DriverElement, List[DriverElement]]: """返回当前元素下级符合条件的第一个元素,默认返回 \n :param loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串 - :param timeout: 查找元素超时时间 + :param timeout: 查找元素超时时间,默认与元素所在页面等待时间一致 :return: DriverElement对象或属性、文本 """ return self._ele(loc_or_str, timeout) @@ -108,7 +109,7 @@ class ShadowRootElement(BaseElement): timeout: float = None) -> List[DriverElement]: """返回当前元素下级所有符合条件的子元素 \n :param loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串 - :param timeout: 查找元素超时时间 + :param timeout: 查找元素超时时间,默认与元素所在页面等待时间一致 :return: DriverElement对象或属性、文本组成的列表 """ return self._ele(loc_or_str, timeout=timeout, single=False) @@ -141,11 +142,20 @@ class ShadowRootElement(BaseElement): loc = get_loc(loc_or_str) if loc[0] == 'css selector' and str(loc[1]).startswith(':root'): loc = loc[0], loc[1][5:] - + + timeout = timeout if timeout is not None else self.page.timeout eles = make_session_ele(self.html).eles(loc) + t1 = perf_counter() + while not eles and perf_counter() - t1 <= timeout: + try: + eles = make_session_ele(self.html).eles(loc) + + except Exception: + pass + if not eles: - return None if single else [] + return None if single else eles css_paths = [i.css_path[47:] for i in eles]