diff --git a/DrissionPage/_base/base.py b/DrissionPage/_base/base.py index a1e4ce3..1fcbd40 100644 --- a/DrissionPage/_base/base.py +++ b/DrissionPage/_base/base.py @@ -169,14 +169,8 @@ class DrissionElement(BaseElement): loc = loc[1].lstrip('./') node = self._ele(f'xpath:./{loc}', timeout=timeout, index=index, relative=True, raise_err=False) - if node: - return node - - if Settings.raise_when_ele_not_found: - raise ElementNotFoundError(None, 'child()', {'locator': locator, 'index': index, - 'ele_only': ele_only}) - else: - return NoneElement(self.owner, 'child()', {'locator': locator, 'index': index, 'ele_only': ele_only}) + return node if node else NoneElement(self.owner, 'child()', + {'locator': locator, 'index': index, 'ele_only': ele_only}) def prev(self, locator='', index=1, timeout=None, ele_only=True): """返回前面的一个兄弟元素,可用查询语法筛选,可指定返回筛选结果的第几个 @@ -289,12 +283,8 @@ class DrissionElement(BaseElement): index = locator locator = '' node = self._get_relatives(index, locator, direction, brother, timeout, ele_only) - if node: - return node - if Settings.raise_when_ele_not_found: - raise ElementNotFoundError(None, func, {'locator': locator, 'index': index, 'ele_only': ele_only}) - else: - return NoneElement(self.owner, func, {'locator': locator, 'index': index, 'ele_only': ele_only}) + return node if node else NoneElement(self.owner, func, + {'locator': locator, 'index': index, 'ele_only': ele_only}) def _get_relatives(self, index=None, locator='', direction='following', brother=True, timeout=.5, ele_only=True): """按要求返回兄弟元素或节点组成的列表 diff --git a/DrissionPage/_elements/chromium_element.py b/DrissionPage/_elements/chromium_element.py index cf32848..c5c9ed6 100644 --- a/DrissionPage/_elements/chromium_element.py +++ b/DrissionPage/_elements/chromium_element.py @@ -18,7 +18,6 @@ from .session_element import make_session_ele from .._base.base import DrissionElement, BaseElement from .._functions.keys import input_text_or_keys from .._functions.locator import get_loc -from .._functions.settings import Settings from .._functions.tools import ElementsList from .._functions.web import make_absolute_link, get_ele_txt, format_html, is_js_func, offset_scroll, get_blob from .._units.clicker import Clicker @@ -28,8 +27,7 @@ from .._units.selector import SelectElement from .._units.setter import ChromiumElementSetter from .._units.states import ElementStates, ShadowRootStates from .._units.waiter import ElementWaiter -from ..errors import (ContextLostError, ElementLostError, JavaScriptError, ElementNotFoundError, - CDPError, NoResourceError, AlertExistsError) +from ..errors import ContextLostError, ElementLostError, JavaScriptError, CDPError, NoResourceError, AlertExistsError __FRAME_ELEMENT__ = ('iframe', 'frame') @@ -439,14 +437,7 @@ class ChromiumElement(DrissionElement): :param index: 获取第几个,从1开始,可传入负数获取倒数第几个 :return: SessionElement对象或属性、文本 """ - r = make_session_ele(self, locator, index=index) - if isinstance(r, NoneElement): - if Settings.raise_when_ele_not_found: - raise ElementNotFoundError(None, 's_ele()', {'locator': locator}) - else: - r.method = 's_ele()' - r.args = {'locator': locator} - return r + return make_session_ele(self, locator, index=index, method='s_ele()') def s_eles(self, locator=None): """查找所有符合条件的元素,以SessionElement列表形式返回 @@ -897,13 +888,8 @@ class ShadowRoot(BaseElement): loc = f'xpath:./{loc}' ele = self._ele(loc, index=index, relative=True) - if ele: - return ele - if Settings.raise_when_ele_not_found: - raise ElementNotFoundError(None, 'child()', {'locator': locator, 'index': index}) - else: - return NoneElement(self.owner, 'child()', {'locator': locator, 'index': index}) + return ele if ele else NoneElement(self.owner, 'child()', {'locator': locator, 'index': index}) def next(self, locator='', index=1): """返回当前元素后面一个符合条件的同级元素,可用查询语法筛选,可指定返回筛选结果的第几个 @@ -918,13 +904,8 @@ class ShadowRoot(BaseElement): loc = loc[1].lstrip('./') xpath = f'xpath:./{loc}' ele = self.parent_ele._ele(xpath, index=index, relative=True) - if ele: - return ele - if Settings.raise_when_ele_not_found: - raise ElementNotFoundError(None, 'next()', {'locator': locator, 'index': index}) - else: - return NoneElement(self.owner, 'next()', {'locator': locator, 'index': index}) + return ele if ele else NoneElement(self.owner, 'next()', {'locator': locator, 'index': index}) def before(self, locator='', index=1): """返回文档中当前元素前面符合条件的一个元素,可用查询语法筛选,可指定返回筛选结果的第几个 @@ -940,13 +921,8 @@ class ShadowRoot(BaseElement): loc = loc[1].lstrip('./') xpath = f'xpath:./preceding::{loc}' ele = self.parent_ele._ele(xpath, index=index, relative=True) - if ele: - return ele - if Settings.raise_when_ele_not_found: - raise ElementNotFoundError(None, 'before()', {'locator': locator, 'index': index}) - else: - return NoneElement(self.owner, 'before()', {'locator': locator, 'index': index}) + return ele if ele else NoneElement(self.owner, 'before()', {'locator': locator, 'index': index}) def after(self, locator='', index=1): """返回文档中此当前元素后面符合条件的一个元素,可用查询语法筛选,可指定返回筛选结果的第几个 @@ -956,12 +932,7 @@ class ShadowRoot(BaseElement): :return: 本元素后面的某个元素或节点 """ nodes = self.afters(locator=locator) - if nodes: - return nodes[index - 1] - if Settings.raise_when_ele_not_found: - raise ElementNotFoundError(None, 'after()', {'locator': locator, 'index': index}) - else: - return NoneElement(self.owner, 'after()', {'locator': locator, 'index': index}) + return nodes[index - 1] if nodes else NoneElement(self.owner, 'after()', {'locator': locator, 'index': index}) def children(self, locator=''): """返回当前元素符合条件的直接子元素或节点组成的列表,可用查询语法筛选 diff --git a/DrissionPage/_elements/none_element.py b/DrissionPage/_elements/none_element.py index b412731..31e04e6 100644 --- a/DrissionPage/_elements/none_element.py +++ b/DrissionPage/_elements/none_element.py @@ -5,6 +5,7 @@ @Copyright: (c) 2024 by g1879, Inc. All Rights Reserved. @License : BSD 3-Clause. """ +from .._functions.settings import Settings from ..errors import ElementNotFoundError @@ -15,6 +16,9 @@ class NoneElement(object): :param method: 查找元素的方法 :param args: 查找元素的参数 """ + if method and Settings.raise_when_ele_not_found: # 无传入method时不自动抛出,由调用者处理 + raise ElementNotFoundError(None, method=method, arguments=args) + if page: self._none_ele_value = page._none_ele_value self._none_ele_return_value = page._none_ele_return_value diff --git a/DrissionPage/_elements/session_element.py b/DrissionPage/_elements/session_element.py index 358354f..225b939 100644 --- a/DrissionPage/_elements/session_element.py +++ b/DrissionPage/_elements/session_element.py @@ -293,12 +293,13 @@ class SessionElement(DrissionElement): return f'{path_str[1:]}' if mode == 'css' else path_str -def make_session_ele(html_or_ele, loc=None, index=1): +def make_session_ele(html_or_ele, loc=None, index=1, method=None): """从接收到的对象或html文本中查找元素,返回SessionElement对象 如要直接从html生成SessionElement而不在下级查找,loc输入None即可 :param html_or_ele: html文本、BaseParser对象 :param loc: 定位元组或字符串,为None时不在下级查找,返回根元素 :param index: 获取第几个元素,从1开始,可传入负数获取倒数第几个,None获取所有 + :param method: 调用此方法的方法 :return: 返回SessionElement元素或列表,或属性文本 """ # ---------------处理定位符--------------- @@ -405,7 +406,7 @@ def make_session_ele(html_or_ele, loc=None, index=1): else: eles_count = len(eles) if eles_count == 0 or abs(index) > eles_count: - return NoneElement(page) + return NoneElement(page, method=method, args={'locator': loc, 'index': index}) if index < 0: index = eles_count + index + 1 @@ -415,7 +416,7 @@ def make_session_ele(html_or_ele, loc=None, index=1): elif isinstance(ele, str): return ele else: - return NoneElement(page) + return NoneElement(page, method=method, args={'locator': loc, 'index': index}) except Exception as e: if 'Invalid expression' in str(e): diff --git a/DrissionPage/_elements/session_element.pyi b/DrissionPage/_elements/session_element.pyi index 74034a9..dba8242 100644 --- a/DrissionPage/_elements/session_element.pyi +++ b/DrissionPage/_elements/session_element.pyi @@ -144,4 +144,5 @@ class SessionElement(DrissionElement): def make_session_ele(html_or_ele: Union[str, SessionElement, SessionPage, ChromiumElement, BaseElement, ChromiumFrame, ChromiumBase], loc: Union[str, Tuple[str, str]] = None, - index: Optional[int] = 1) -> Union[SessionElement, List[SessionElement]]: ... + index: Optional[int] = 1, + method: Optional[str] = None) -> Union[SessionElement, List[SessionElement]]: ... diff --git a/DrissionPage/_pages/chromium_base.py b/DrissionPage/_pages/chromium_base.py index fe365c9..6dcd165 100644 --- a/DrissionPage/_pages/chromium_base.py +++ b/DrissionPage/_pages/chromium_base.py @@ -30,7 +30,7 @@ from .._units.scroller import PageScroller from .._units.setter import ChromiumBaseSetter from .._units.states import PageStates from .._units.waiter import BaseWaiter -from ..errors import ContextLostError, CDPError, PageDisconnectedError, ElementNotFoundError, ElementLostError +from ..errors import ContextLostError, CDPError, PageDisconnectedError, ElementLostError __ERROR__ = 'error' @@ -517,14 +517,7 @@ class ChromiumBase(BasePage): :param index: 获取第几个,从1开始,可传入负数获取倒数第几个 :return: SessionElement对象或属性、文本 """ - r = make_session_ele(self, locator, index=index) - if isinstance(r, NoneElement): - if Settings.raise_when_ele_not_found: - raise ElementNotFoundError(None, 's_ele()', {'locator': locator}) - else: - r.method = 's_ele()' - r.args = {'locator': locator} - return r + return make_session_ele(self, locator, index=index, method='s_ele()') def s_eles(self, locator): """查找所有符合条件的元素以SessionElement列表形式返回