等待增加可抛出异常设置;easy_set删除raise_when_ele_not_found()方法;Settings的raise_ele_not_found和raise_wait_failed改名

This commit is contained in:
g1879 2023-06-29 15:57:14 +08:00
parent 07d023daad
commit 3f999f066c
11 changed files with 123 additions and 118 deletions

View File

@ -71,7 +71,7 @@ class BaseElement(BaseParser):
r = self._find_elements(loc_or_str, timeout=timeout, single=single, relative=relative, raise_err=raise_err)
if not single or raise_err is False:
return r
if not r and (Settings.raise_ele_not_found or raise_err is True):
if not r and (Settings.raise_when_ele_not_found or raise_err is True):
raise ElementNotFoundError
return r
@ -151,7 +151,7 @@ class DrissionElement(BaseElement):
filter_loc = ''
nodes = self.children(filter_loc=filter_loc, timeout=timeout, ele_only=ele_only)
if not nodes:
if Settings.raise_ele_not_found:
if Settings.raise_when_ele_not_found:
raise ElementNotFoundError
else:
return NoneElement()
@ -159,7 +159,7 @@ class DrissionElement(BaseElement):
try:
return nodes[index - 1]
except IndexError:
if Settings.raise_ele_not_found:
if Settings.raise_when_ele_not_found:
raise ElementNotFoundError
else:
return NoneElement()
@ -178,7 +178,7 @@ class DrissionElement(BaseElement):
nodes = self._get_brothers(index, filter_loc, 'preceding', timeout=timeout, ele_only=ele_only)
if nodes:
return nodes[-1]
if Settings.raise_ele_not_found:
if Settings.raise_when_ele_not_found:
raise ElementNotFoundError
else:
return NoneElement()
@ -197,7 +197,7 @@ class DrissionElement(BaseElement):
nodes = self._get_brothers(index, filter_loc, 'following', timeout=timeout, ele_only=ele_only)
if nodes:
return nodes[0]
if Settings.raise_ele_not_found:
if Settings.raise_when_ele_not_found:
raise ElementNotFoundError
else:
return NoneElement()
@ -216,7 +216,7 @@ class DrissionElement(BaseElement):
nodes = self._get_brothers(index, filter_loc, 'preceding', False, timeout=timeout, ele_only=ele_only)
if nodes:
return nodes[-1]
if Settings.raise_ele_not_found:
if Settings.raise_when_ele_not_found:
raise ElementNotFoundError
else:
return NoneElement()
@ -235,7 +235,7 @@ class DrissionElement(BaseElement):
nodes = self._get_brothers(index, filter_loc, 'following', False, timeout, ele_only=ele_only)
if nodes:
return nodes[0]
if Settings.raise_ele_not_found:
if Settings.raise_when_ele_not_found:
raise ElementNotFoundError
else:
return NoneElement()
@ -444,7 +444,7 @@ class BasePage(BaseParser):
if not single or raise_err is False:
return r
if not r and (Settings().raise_ele_not_found is True or raise_err is True):
if not r and (Settings.raise_when_ele_not_found is True or raise_err is True):
raise ElementNotFoundError
return r

View File

@ -15,12 +15,12 @@ from requests import Session
from .base import BasePage
from .chromium_driver import ChromiumDriver
from .chromium_element import ChromiumScroll, ChromiumElement, run_js, make_chromium_ele
from .commons.constants import HANDLE_ALERT_METHOD, ERROR, NoneElement
from .commons.constants import HANDLE_ALERT_METHOD, ERROR, NoneElement, Settings
from .commons.locator import get_loc
from .commons.tools import get_usable_path, clean_folder
from .commons.web import set_browser_cookies
from .errors import ContextLossError, ElementLossError, AlertExistsError, CDPError, TabClosedError, \
NoRectError, BrowserConnectError, GetDocumentError
NoRectError, BrowserConnectError, GetDocumentError, WaitTimeoutError
from .network_listener import NetworkListener
from .session_element import make_session_ele
@ -1002,66 +1002,78 @@ class ChromiumBaseWaiter(object):
"""
self._driver = page_or_ele
def ele_delete(self, loc_or_ele, timeout=None):
def ele_delete(self, loc_or_ele, timeout=None, raise_err=None):
"""等待元素从DOM中删除
:param loc_or_ele: 要等待的元素可以是已有元素定位符
:param timeout: 超时时间默认读取页面超时时间
:param raise_err: 等待识别时是否报错为None时根据Settings设置
:return: 是否等待成功
"""
ele = self._driver._ele(loc_or_ele, raise_err=False, timeout=0)
return ele.wait.delete(timeout) if ele else True
return ele.wait.delete(timeout, raise_err=raise_err) if ele else True
def ele_display(self, loc_or_ele, timeout=None):
def ele_display(self, loc_or_ele, timeout=None, raise_err=None):
"""等待元素变成显示状态
:param loc_or_ele: 要等待的元素可以是已有元素定位符
:param timeout: 超时时间默认读取页面超时时间
:param raise_err: 等待识别时是否报错为None时根据Settings设置
:return: 是否等待成功
"""
ele = self._driver._ele(loc_or_ele, raise_err=False, timeout=0)
return ele.wait.display(timeout)
return ele.wait.display(timeout, raise_err=raise_err)
def ele_hidden(self, loc_or_ele, timeout=None):
def ele_hidden(self, loc_or_ele, timeout=None, raise_err=None):
"""等待元素变成隐藏状态
:param loc_or_ele: 要等待的元素可以是已有元素定位符
:param timeout: 超时时间默认读取页面超时时间
:param raise_err: 等待识别时是否报错为None时根据Settings设置
:return: 是否等待成功
"""
ele = self._driver._ele(loc_or_ele, raise_err=False, timeout=0)
return ele.wait.hidden(timeout)
return ele.wait.hidden(timeout, raise_err=raise_err)
def ele_load(self, loc, timeout=None):
def ele_load(self, loc, timeout=None, raise_err=None):
"""等待元素加载到DOM
:param loc: 要等待的元素输入定位符
:param timeout: 超时时间默认读取页面超时时间
:param raise_err: 等待识别时是否报错为None时根据Settings设置
:return: 成功返回元素对象失败返回False
"""
ele = self._driver._ele(loc, raise_err=False, timeout=timeout)
return ele if ele else False
if ele:
return True
if raise_err is True or Settings.raise_when_wait_failed is True:
raise WaitTimeoutError('等待元素加载失败。')
else:
return False
def load_start(self, timeout=None):
def load_start(self, timeout=None, raise_err=None):
"""等待页面开始加载
:param timeout: 超时时间为None时使用页面timeout属性
:param raise_err: 等待识别时是否报错为None时根据Settings设置
:return: 是否等待成功
"""
return self._loading(timeout=timeout, gap=.002)
return self._loading(timeout=timeout, gap=.002, raise_err=raise_err)
def load_complete(self, timeout=None):
def load_complete(self, timeout=None, raise_err=None):
"""等待页面开始加载
:param timeout: 超时时间为None时使用页面timeout属性
:param raise_err: 等待识别时是否报错为None时根据Settings设置
:return: 是否等待成功
"""
return self._loading(timeout=timeout, start=False)
return self._loading(timeout=timeout, start=False, raise_err=raise_err)
def upload_paths_inputted(self):
"""等待自动填写上传文件路径"""
while self._driver._upload_list:
sleep(.01)
def _loading(self, timeout=None, start=True, gap=.01):
def _loading(self, timeout=None, start=True, gap=.01, raise_err=None):
"""等待页面开始加载或加载完成
:param timeout: 超时时间为None时使用页面timeout属性
:param start: 等待开始还是结束
:param gap: 间隔秒数
:param raise_err: 等待识别时是否报错为None时根据Settings设置
:return: 是否等待成功
"""
if timeout != 0:
@ -1072,7 +1084,11 @@ class ChromiumBaseWaiter(object):
if self._driver.is_loading == start:
return True
sleep(gap)
return False
if raise_err is True or Settings.raise_when_wait_failed is True:
raise WaitTimeoutError('等待页面加载失败。')
else:
return False
class ChromiumPageScroll(ChromiumScroll):

View File

@ -217,19 +217,23 @@ class ChromiumBaseWaiter(object):
def __init__(self, page: ChromiumBase):
self._driver: ChromiumBase = ...
def ele_delete(self, loc_or_ele: Union[str, tuple, ChromiumElement], timeout: float = None) -> bool: ...
def ele_delete(self, loc_or_ele: Union[str, tuple, ChromiumElement], timeout: float = None,
raise_err: bool = None) -> bool: ...
def ele_display(self, loc_or_ele: Union[str, tuple, ChromiumElement], timeout: float = None) -> bool: ...
def ele_display(self, loc_or_ele: Union[str, tuple, ChromiumElement], timeout: float = None,
raise_err: bool = None) -> bool: ...
def ele_hidden(self, loc_or_ele: Union[str, tuple, ChromiumElement], timeout: float = None) -> bool: ...
def ele_hidden(self, loc_or_ele: Union[str, tuple, ChromiumElement], timeout: float = None,
raise_err: bool = None) -> bool: ...
def ele_load(self, loc: Union[str, tuple], timeout: float = None) -> Union[bool, ChromiumElement]: ...
def ele_load(self, loc: Union[str, tuple], timeout: float = None,
raise_err: bool = None) -> Union[bool, ChromiumElement]: ...
def _loading(self, timeout: float = None, start: bool = True, gap: float = .01) -> bool: ...
def _loading(self, timeout: float = None, start: bool = True, gap: float = .01, raise_err: bool = None) -> bool: ...
def load_start(self, timeout: float = None) -> bool: ...
def load_start(self, timeout: float = None, raise_err: bool = None) -> bool: ...
def load_complete(self, timeout: float = None) -> bool: ...
def load_complete(self, timeout: float = None, raise_err: bool = None) -> bool: ...
def upload_paths_inputted(self) -> None: ...

View File

@ -14,7 +14,7 @@ from .commons.keys import keys_to_typing, keyDescriptionForString, keyDefinition
from .commons.locator import get_loc
from .commons.web import make_absolute_link, get_ele_txt, format_html, is_js_func, location_in_viewport, offset_scroll
from .errors import ContextLossError, ElementLossError, JavaScriptError, NoRectError, ElementNotFoundError, \
CDPError, NoResourceError, CanNotClickError
CDPError, NoResourceError, CanNotClickError, WaitTimeoutError
from .session_element import make_session_ele
@ -839,7 +839,7 @@ class ChromiumShadowRoot(BaseElement):
"""
nodes = self.children(filter_loc=filter_loc)
if not nodes:
if Settings.raise_ele_not_found:
if Settings.raise_when_ele_not_found:
raise ElementNotFoundError
else:
return NoneElement()
@ -847,7 +847,7 @@ class ChromiumShadowRoot(BaseElement):
try:
return nodes[index - 1]
except IndexError:
if Settings.raise_ele_not_found:
if Settings.raise_when_ele_not_found:
raise ElementNotFoundError
else:
return NoneElement()
@ -861,7 +861,7 @@ class ChromiumShadowRoot(BaseElement):
nodes = self.nexts(filter_loc=filter_loc)
if nodes:
return nodes[index - 1]
if Settings.raise_ele_not_found:
if Settings.raise_when_ele_not_found:
raise ElementNotFoundError
else:
return NoneElement()
@ -876,7 +876,7 @@ class ChromiumShadowRoot(BaseElement):
nodes = self.befores(filter_loc=filter_loc)
if nodes:
return nodes[index - 1]
if Settings.raise_ele_not_found:
if Settings.raise_when_ele_not_found:
raise ElementNotFoundError
else:
return NoneElement()
@ -891,7 +891,7 @@ class ChromiumShadowRoot(BaseElement):
nodes = self.afters(filter_loc=filter_loc)
if nodes:
return nodes[index - 1]
if Settings.raise_ele_not_found:
if Settings.raise_when_ele_not_found:
raise ElementNotFoundError
else:
return NoneElement()
@ -1633,9 +1633,9 @@ class Click(object):
if by_js is not False:
self._ele.run_js('this.click();')
return True
if Settings.raise_click_failed:
if Settings.raise_when_click_failed:
raise CanNotClickError
return False
def right(self):
@ -2039,58 +2039,66 @@ class ChromiumElementWaiter(object):
self._page = page
self._ele = ele
def delete(self, timeout=None):
def delete(self, timeout=None, raise_err=None):
"""等待元素从dom删除
:param timeout: 超时时间为None使用元素所在页面timeout属性
:param raise_err: 等待识别时是否报错为None时根据Settings设置
:return: 是否等待成功
"""
return self._wait_state('is_alive', False, timeout)
return self._wait_state('is_alive', False, timeout, raise_err)
def display(self, timeout=None):
def display(self, timeout=None, raise_err=None):
"""等待元素从dom显示
:param timeout: 超时时间为None使用元素所在页面timeout属性
:param raise_err: 等待识别时是否报错为None时根据Settings设置
:return: 是否等待成功
"""
return self._wait_state('is_displayed', True, timeout)
return self._wait_state('is_displayed', True, timeout, raise_err)
def hidden(self, timeout=None):
def hidden(self, timeout=None, raise_err=None):
"""等待元素从dom隐藏
:param timeout: 超时时间为None使用元素所在页面timeout属性
:param raise_err: 等待识别时是否报错为None时根据Settings设置
:return: 是否等待成功
"""
return self._wait_state('is_displayed', False, timeout)
return self._wait_state('is_displayed', False, timeout, raise_err)
def covered(self, timeout=None):
def covered(self, timeout=None, raise_err=None):
"""等待当前元素被遮盖
:param timeout:超时时间为None使用元素所在页面timeout属性
:param raise_err: 等待识别时是否报错为None时根据Settings设置
:return: 是否等待成功
"""
return self._wait_state('is_covered', True, timeout)
return self._wait_state('is_covered', True, timeout, raise_err)
def not_covered(self, timeout=None):
def not_covered(self, timeout=None, raise_err=None):
"""等待当前元素被遮盖
:param timeout:超时时间为None使用元素所在页面timeout属性
:param raise_err: 等待识别时是否报错为None时根据Settings设置
:return: 是否等待成功
"""
return self._wait_state('is_covered', False, timeout)
return self._wait_state('is_covered', False, timeout, raise_err)
def enabled(self, timeout=None):
def enabled(self, timeout=None, raise_err=None):
"""等待当前元素变成可用
:param timeout:超时时间为None使用元素所在页面timeout属性
:param raise_err: 等待识别时是否报错为None时根据Settings设置
:return: 是否等待成功
"""
return self._wait_state('is_enabled', True, timeout)
return self._wait_state('is_enabled', True, timeout, raise_err)
def disabled(self, timeout=None):
def disabled(self, timeout=None, raise_err=None):
"""等待当前元素变成可用
:param timeout:超时时间为None使用元素所在页面timeout属性
:param raise_err: 等待识别时是否报错为None时根据Settings设置
:return: 是否等待成功
"""
return self._wait_state('is_enabled', False, timeout)
return self._wait_state('is_enabled', False, timeout, raise_err)
def disabled_or_delete(self, timeout=None):
def disabled_or_delete(self, timeout=None, raise_err=None):
"""等待当前元素变成不可用或从DOM移除
:param timeout:超时时间为None使用元素所在页面timeout属性
:param raise_err: 等待识别时是否报错为None时根据Settings设置
:return: 是否等待成功
"""
if timeout is None:
@ -2101,13 +2109,17 @@ class ChromiumElementWaiter(object):
return True
sleep(.05)
return False
if raise_err is True or Settings.raise_when_wait_failed is True:
raise WaitTimeoutError('等待元素隐藏或删除失败。')
else:
return False
def _wait_state(self, attr, mode=False, timeout=None):
def _wait_state(self, attr, mode=False, timeout=None, raise_err=None):
"""等待元素某个bool状态到达指定状态
:param attr: 状态名称
:param mode: True或False
:param timeout: 超时时间为None使用元素所在页面timeout属性
:param raise_err: 等待识别时是否报错为None时根据Settings设置
:return: 是否等待成功
"""
if timeout is None:
@ -2118,7 +2130,10 @@ class ChromiumElementWaiter(object):
return True
sleep(.05)
return False
if raise_err is True or Settings.raise_when_wait_failed is True:
raise WaitTimeoutError('等待元素状态改变失败。')
else:
return False
class Pseudo(object):

View File

@ -561,23 +561,23 @@ class ChromiumElementWaiter(object):
self._ele: ChromiumElement = ...
self._page: ChromiumBase = ...
def delete(self, timeout: float = None) -> bool: ...
def delete(self, timeout: float = None, raise_err: bool = None) -> bool: ...
def display(self, timeout: float = None) -> bool: ...
def display(self, timeout: float = None, raise_err: bool = None) -> bool: ...
def hidden(self, timeout: float = None) -> bool: ...
def hidden(self, timeout: float = None, raise_err: bool = None) -> bool: ...
def covered(self, timeout: float = None) -> bool: ...
def covered(self, timeout: float = None, raise_err: bool = None) -> bool: ...
def not_covered(self, timeout: float = None) -> bool: ...
def not_covered(self, timeout: float = None, raise_err: bool = None) -> bool: ...
def enabled(self, timeout: float = None) -> bool: ...
def enabled(self, timeout: float = None, raise_err: bool = None) -> bool: ...
def disabled(self, timeout: float = None) -> bool: ...
def disabled(self, timeout: float = None, raise_err: bool = None) -> bool: ...
def disabled_or_delete(self, timeout: float = None) -> bool: ...
def disabled_or_delete(self, timeout: float = None, raise_err: bool = None) -> bool: ...
def _wait_state(self, attr: str, mode: bool = False, timeout: float = None) -> bool: ...
def _wait_state(self, attr: str, mode: bool = False, timeout: float = None, raise_err: bool = None) -> bool: ...
class Pseudo(object):

View File

@ -10,9 +10,10 @@ from .chromium_base import ChromiumBase, Timeout, ChromiumBaseSetter, ChromiumBa
from .chromium_driver import ChromiumDriver
from .chromium_tab import ChromiumTab
from .commons.browser import connect_browser
from .commons.constants import Settings
from .commons.tools import port_is_using
from .configs.chromium_options import ChromiumOptions
from .errors import BrowserConnectError
from .errors import BrowserConnectError, WaitTimeoutError
class ChromiumPage(ChromiumBase):
@ -152,24 +153,6 @@ class ChromiumPage(ChromiumBase):
self._set = ChromiumPageSetter(self)
return self._set
# @property
# def download_path(self):
# """返回默认下载路径"""
# p = self._download_path or ''
# return str(Path(p).absolute())
#
# @property
# def download_set(self):
# """返回用于设置下载参数的对象"""
# if self._download_set is None:
# self._download_set = BaseDownloadSetter(self)
# return self._download_set
#
# @property
# def download(self):
# """返回下载器对象"""
# return self.download_set._switched_DownloadKit
@property
def rect(self):
if self._rect is None:
@ -385,29 +368,23 @@ class ChromiumPageWaiter(ChromiumBaseWaiter):
super().__init__(page)
self._listener = None
def new_tab(self, timeout=None):
def new_tab(self, timeout=None, raise_err=None):
"""等待新标签页出现
:param timeout: 等待超时时间为None则使用页面对象timeout属性
:return: 是否等到下载开始
:param raise_err: 等待识别时是否报错为None时根据Settings设置
:return: 是否等到新标签页出现
"""
timeout = timeout if timeout is not None else self._driver.timeout
end_time = perf_counter() + timeout
while self._driver.tab_id == self._driver.latest_tab and perf_counter() < end_time:
while perf_counter() < end_time:
if self._driver.tab_id != self._driver.latest_tab:
return True
sleep(.01)
# def download_begin(self, timeout=1.5):
# """等待浏览器下载开始
# :param timeout: 等待超时时间为None则使用页面对象timeout属性
# :return: 是否等到下载开始
# """
# return self._driver.download_set.wait_download_begin(timeout)
#
# def download_finish(self, timeout=None):
# """等待下载结束
# :param timeout: 等待超时时间为None则使用页面对象timeout属性
# :return: 是否等到下载结束
# """
# return self._driver.download_set.wait_download_finish(timeout)
if raise_err is True or Settings.raise_when_wait_failed is True:
raise WaitTimeoutError('等待新标签页失败。')
else:
return False
class ChromiumTabRect(object):

View File

@ -102,11 +102,11 @@ class ChromiumPageWaiter(ChromiumBaseWaiter):
_driver: ChromiumPage = ...
_listener: Union[NetworkListener, None] = ...
def download_begin(self, timeout: float = 1.5) -> bool: ...
# def download_begin(self, timeout: float = 1.5) -> bool: ...
def download_finish(self, timeout: float = None) -> bool: ...
# def download_finish(self, timeout: float = None) -> bool: ...
def new_tab(self, timeout: float = None) -> bool: ...
def new_tab(self, timeout: float = None, raise_err: bool = None) -> bool: ...
class ChromiumTabRect(object):

View File

@ -11,8 +11,9 @@ ERROR = 'error'
class Settings(object):
raise_ele_not_found = False
raise_click_failed = False
raise_when_ele_not_found = False
raise_when_click_failed = False
raise_when_wait_failed = False
class NoneElement(object):

View File

@ -7,19 +7,10 @@ from os import popen
from pathlib import Path
from re import search
from .commons.constants import Settings
from .configs.chromium_options import ChromiumOptions
from .configs.options_manage import OptionsManager
def raise_when_ele_not_found(on_off=True):
"""设置全局变量,找不到元素时是否抛出异常
:param on_off: True False
:return: None
"""
Settings.raise_ele_not_found = on_off
def configs_to_here(save_name=None):
"""把默认ini文件复制到当前目录
:param save_name: 指定文件名为None则命名为'dp_configs.ini'

View File

@ -7,9 +7,6 @@ from pathlib import Path
from typing import Union
def raise_when_ele_not_found(on_off: bool = True) -> None: ...
def configs_to_here(file_name: Union[Path, str] = None) -> None: ...

View File

@ -58,3 +58,7 @@ class CanNotClickError(BaseError):
class GetDocumentError(BaseError):
_info = '获取文档失败。'
class WaitTimeoutError(BaseError):
_info = '等待失败。'