优化找不到元素时处理逻辑

This commit is contained in:
g1879 2024-06-18 14:11:08 +08:00
parent 41b8d3824b
commit 15f59258bf
6 changed files with 22 additions and 62 deletions

View File

@ -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):
"""按要求返回兄弟元素或节点组成的列表

View File

@ -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=''):
"""返回当前元素符合条件的直接子元素或节点组成的列表,可用查询语法筛选

View File

@ -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

View File

@ -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):

View File

@ -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]]: ...

View File

@ -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列表形式返回