mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
找不到元素时显示方法和参数;链式查找失败时可返回设置值
This commit is contained in:
parent
066eadc7e0
commit
e52d14a962
@ -10,9 +10,10 @@ from urllib.parse import quote
|
||||
|
||||
from DownloadKit import DownloadKit
|
||||
|
||||
from .._commons.constants import Settings, NoneElement
|
||||
from .._commons.constants import Settings
|
||||
from .._commons.locator import get_loc
|
||||
from .._commons.web import format_html
|
||||
from .._elements.none_element import NoneElement
|
||||
from ..errors import ElementNotFoundError
|
||||
|
||||
|
||||
@ -23,7 +24,7 @@ class BaseParser(object):
|
||||
return self.ele(loc_or_str)
|
||||
|
||||
def ele(self, loc_or_ele, timeout=None):
|
||||
return self._ele(loc_or_ele, timeout, True)
|
||||
return self._ele(loc_or_ele, timeout, True, method='ele()')
|
||||
|
||||
def eles(self, loc_or_str, timeout=None):
|
||||
return self._ele(loc_or_str, timeout, False)
|
||||
@ -39,7 +40,7 @@ class BaseParser(object):
|
||||
def s_eles(self, loc_or_str):
|
||||
pass
|
||||
|
||||
def _ele(self, loc_or_ele, timeout=None, single=True, raise_err=None):
|
||||
def _ele(self, loc_or_ele, timeout=None, single=True, raise_err=None, method=None):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
@ -67,12 +68,16 @@ class BaseElement(BaseParser):
|
||||
def nexts(self):
|
||||
pass
|
||||
|
||||
def _ele(self, loc_or_str, timeout=None, single=True, relative=False, raise_err=None):
|
||||
def _ele(self, loc_or_str, timeout=None, single=True, relative=False, raise_err=None, method=None):
|
||||
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:
|
||||
if not single:
|
||||
return r
|
||||
if not r and (Settings.raise_when_ele_not_found or raise_err is True):
|
||||
raise ElementNotFoundError
|
||||
if isinstance(r, NoneElement):
|
||||
if Settings.raise_when_ele_not_found or raise_err is True:
|
||||
raise ElementNotFoundError(None, method, {'loc_or_str': loc_or_str})
|
||||
else:
|
||||
r.method = method
|
||||
r.args = {'loc_or_str': loc_or_str}
|
||||
return r
|
||||
|
||||
@abstractmethod
|
||||
@ -136,7 +141,7 @@ class DrissionElement(BaseElement):
|
||||
else:
|
||||
raise TypeError('level_or_loc参数只能是tuple、int或str。')
|
||||
|
||||
return self._ele(loc, timeout=0, relative=True, raise_err=False)
|
||||
return self._ele(loc, timeout=0, relative=True, raise_err=False, method='parent()')
|
||||
|
||||
def child(self, filter_loc='', index=1, timeout=None, ele_only=True):
|
||||
"""返回直接子元素元素或节点组成的列表,可用查询语法筛选
|
||||
@ -152,17 +157,19 @@ class DrissionElement(BaseElement):
|
||||
nodes = self.children(filter_loc=filter_loc, timeout=timeout, ele_only=ele_only)
|
||||
if not nodes:
|
||||
if Settings.raise_when_ele_not_found:
|
||||
raise ElementNotFoundError
|
||||
raise ElementNotFoundError(None, 'child()',
|
||||
{'filter_loc': filter_loc, 'index': index, 'ele_only': ele_only})
|
||||
else:
|
||||
return NoneElement()
|
||||
return NoneElement('child()', {'filter_loc': filter_loc, 'index': index, 'ele_only': ele_only})
|
||||
|
||||
try:
|
||||
return nodes[index - 1]
|
||||
except IndexError:
|
||||
if Settings.raise_when_ele_not_found:
|
||||
raise ElementNotFoundError
|
||||
raise ElementNotFoundError(None, 'child()',
|
||||
{'filter_loc': filter_loc, 'index': index, 'ele_only': ele_only})
|
||||
else:
|
||||
return NoneElement()
|
||||
return NoneElement('child()', {'filter_loc': filter_loc, 'index': index, 'ele_only': ele_only})
|
||||
|
||||
def prev(self, filter_loc='', index=1, timeout=0, ele_only=True):
|
||||
"""返回前面的一个兄弟元素,可用查询语法筛选,可指定返回筛选结果的第几个
|
||||
@ -179,9 +186,10 @@ class DrissionElement(BaseElement):
|
||||
if nodes:
|
||||
return nodes[-1]
|
||||
if Settings.raise_when_ele_not_found:
|
||||
raise ElementNotFoundError
|
||||
raise ElementNotFoundError(None, 'prev()',
|
||||
{'filter_loc': filter_loc, 'index': index, 'ele_only': ele_only})
|
||||
else:
|
||||
return NoneElement()
|
||||
return NoneElement('prev()', {'filter_loc': filter_loc, 'index': index, 'ele_only': ele_only})
|
||||
|
||||
def next(self, filter_loc='', index=1, timeout=0, ele_only=True):
|
||||
"""返回后面的一个兄弟元素,可用查询语法筛选,可指定返回筛选结果的第几个
|
||||
@ -198,9 +206,10 @@ class DrissionElement(BaseElement):
|
||||
if nodes:
|
||||
return nodes[0]
|
||||
if Settings.raise_when_ele_not_found:
|
||||
raise ElementNotFoundError
|
||||
raise ElementNotFoundError(None, 'next()',
|
||||
{'filter_loc': filter_loc, 'index': index, 'ele_only': ele_only})
|
||||
else:
|
||||
return NoneElement()
|
||||
return NoneElement('next()', {'filter_loc': filter_loc, 'index': index, 'ele_only': ele_only})
|
||||
|
||||
def before(self, filter_loc='', index=1, timeout=None, ele_only=True):
|
||||
"""返回前面的一个兄弟元素,可用查询语法筛选,可指定返回筛选结果的第几个
|
||||
@ -217,9 +226,10 @@ class DrissionElement(BaseElement):
|
||||
if nodes:
|
||||
return nodes[-1]
|
||||
if Settings.raise_when_ele_not_found:
|
||||
raise ElementNotFoundError
|
||||
raise ElementNotFoundError(None, 'before()',
|
||||
{'filter_loc': filter_loc, 'index': index, 'ele_only': ele_only})
|
||||
else:
|
||||
return NoneElement()
|
||||
return NoneElement('before()', {'filter_loc': filter_loc, 'index': index, 'ele_only': ele_only})
|
||||
|
||||
def after(self, filter_loc='', index=1, timeout=None, ele_only=True):
|
||||
"""返回后面的一个兄弟元素,可用查询语法筛选,可指定返回筛选结果的第几个
|
||||
@ -236,9 +246,10 @@ class DrissionElement(BaseElement):
|
||||
if nodes:
|
||||
return nodes[0]
|
||||
if Settings.raise_when_ele_not_found:
|
||||
raise ElementNotFoundError
|
||||
raise ElementNotFoundError(None, 'after()',
|
||||
{'filter_loc': filter_loc, 'index': index, 'ele_only': ele_only})
|
||||
else:
|
||||
return NoneElement()
|
||||
return NoneElement('after()', {'filter_loc': filter_loc, 'index': index, 'ele_only': ele_only})
|
||||
|
||||
def children(self, filter_loc='', timeout=None, ele_only=True):
|
||||
"""返回直接子元素元素或节点组成的列表,可用查询语法筛选
|
||||
@ -372,7 +383,7 @@ class BasePage(BaseParser):
|
||||
@property
|
||||
def title(self):
|
||||
"""返回网页title"""
|
||||
ele = self._ele('xpath://title', raise_err=False)
|
||||
ele = self._ele('xpath://title', raise_err=False, method='title')
|
||||
return ele.text if ele else None
|
||||
|
||||
@property
|
||||
@ -430,7 +441,7 @@ class BasePage(BaseParser):
|
||||
|
||||
@property
|
||||
def user_agent(self):
|
||||
pass
|
||||
return
|
||||
|
||||
@abstractmethod
|
||||
def get_cookies(self, as_dict=False, all_info=False):
|
||||
@ -440,16 +451,20 @@ class BasePage(BaseParser):
|
||||
def get(self, url, show_errmsg=False, retry=None, interval=None):
|
||||
pass
|
||||
|
||||
def _ele(self, loc_or_ele, timeout=None, single=True, raise_err=None):
|
||||
def _ele(self, loc_or_ele, timeout=None, single=True, raise_err=None, method=None):
|
||||
if not loc_or_ele:
|
||||
raise ElementNotFoundError
|
||||
raise ElementNotFoundError(None, method, {'loc_or_str': loc_or_ele})
|
||||
|
||||
r = self._find_elements(loc_or_ele, timeout=timeout, single=single, raise_err=raise_err)
|
||||
|
||||
if not single or raise_err is False:
|
||||
if not single:
|
||||
return r
|
||||
if not r and (Settings.raise_when_ele_not_found is True or raise_err is True):
|
||||
raise ElementNotFoundError
|
||||
if isinstance(r, NoneElement):
|
||||
if Settings.raise_when_ele_not_found or raise_err is True:
|
||||
raise ElementNotFoundError(None, method, {'loc_or_str': loc_or_ele})
|
||||
else:
|
||||
r.method = method
|
||||
r.args = {'loc_or_str': loc_or_ele}
|
||||
return r
|
||||
|
||||
@abstractmethod
|
||||
|
@ -8,7 +8,7 @@ from typing import Union, Tuple, List
|
||||
|
||||
from DownloadKit import DownloadKit
|
||||
|
||||
from .._commons.constants import NoneElement
|
||||
from .._elements.none_element import NoneElement
|
||||
|
||||
|
||||
class BaseParser(object):
|
||||
@ -27,7 +27,8 @@ class BaseParser(object):
|
||||
|
||||
def s_eles(self, loc_or_str: Union[Tuple[str, str], str]): ...
|
||||
|
||||
def _ele(self, loc_or_ele, timeout: float = None, single: bool = True, raise_err: bool = None): ...
|
||||
def _ele(self, loc_or_ele, timeout: float = None, single: bool = True,
|
||||
raise_err: bool = None, method: str = None): ...
|
||||
|
||||
@abstractmethod
|
||||
def _find_elements(self, loc_or_ele, timeout: float = None, single: bool = True, raise_err: bool = None): ...
|
||||
@ -43,7 +44,7 @@ class BaseElement(BaseParser):
|
||||
def tag(self) -> str: ...
|
||||
|
||||
def _ele(self, loc_or_str: Union[Tuple[str, str], str], timeout: float = None, single: bool = True,
|
||||
relative: bool = False, raise_err: bool = None): ...
|
||||
relative: bool = False, raise_err: bool = None, method: str = None): ...
|
||||
|
||||
@abstractmethod
|
||||
def _find_elements(self, loc_or_str, timeout: float = None, single: bool = True, relative: bool = False,
|
||||
@ -208,7 +209,8 @@ class BasePage(BaseParser):
|
||||
retry: int = None,
|
||||
interval: float = None): ...
|
||||
|
||||
def _ele(self, loc_or_ele, timeout: float = None, single: bool = True, raise_err: bool = None): ...
|
||||
def _ele(self, loc_or_ele, timeout: float = None, single: bool = True,
|
||||
raise_err: bool = None, method: str = None): ...
|
||||
|
||||
@abstractmethod
|
||||
def _find_elements(self, loc_or_ele, timeout: float = None, single: bool = True, raise_err: bool = None): ...
|
||||
|
@ -3,8 +3,6 @@
|
||||
@Author : g1879
|
||||
@Contact : g1879@qq.com
|
||||
"""
|
||||
from ..errors import ElementNotFoundError
|
||||
|
||||
FRAME_ELEMENT = ('iframe', 'frame')
|
||||
ERROR = 'error'
|
||||
|
||||
@ -13,28 +11,4 @@ class Settings(object):
|
||||
raise_when_ele_not_found = False
|
||||
raise_when_click_failed = False
|
||||
raise_when_wait_failed = False
|
||||
|
||||
|
||||
class NoneElement(object):
|
||||
_instance = None
|
||||
|
||||
def __new__(cls):
|
||||
if not cls._instance:
|
||||
cls._instance = super(NoneElement, cls).__new__(cls)
|
||||
return cls._instance
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
raise ElementNotFoundError
|
||||
|
||||
def __getattr__(self, item):
|
||||
raise ElementNotFoundError
|
||||
|
||||
def __eq__(self, other):
|
||||
if other is None:
|
||||
return True
|
||||
|
||||
def __bool__(self):
|
||||
return False
|
||||
|
||||
def __repr__(self):
|
||||
return 'None'
|
||||
NoneElement_value = None
|
||||
|
@ -7,6 +7,12 @@ from re import split
|
||||
from .by import By
|
||||
|
||||
|
||||
def is_loc(text):
|
||||
"""返回text是否定位符"""
|
||||
return text.startswith(('.', '#', '@', 't:', 't=', 'tag:', 'tag=', 'tx:', 'tx=', 'tx^', 'tx$', 'text:', 'text=',
|
||||
'text^', 'text$', 'xpath:', 'xpath=', 'x:', 'x=', 'css:', 'css=', 'c:', 'c='))
|
||||
|
||||
|
||||
def get_loc(loc, translate_css=False):
|
||||
"""接收本库定位语法或selenium定位元组,转换为标准定位元组,可翻译css selector为xpath
|
||||
:param loc: 本库定位语法或selenium定位元组
|
||||
|
@ -6,6 +6,9 @@
|
||||
from typing import Union
|
||||
|
||||
|
||||
def is_loc(text:str) -> bool: ...
|
||||
|
||||
|
||||
def get_loc(loc: Union[tuple, str], translate_css: bool = False) -> tuple: ...
|
||||
|
||||
|
||||
|
@ -7,9 +7,10 @@ from os.path import basename, sep
|
||||
from pathlib import Path
|
||||
from time import perf_counter, sleep
|
||||
|
||||
from .none_element import NoneElement
|
||||
from .session_element import make_session_ele
|
||||
from .._base.base import DrissionElement, BaseElement
|
||||
from .._commons.constants import FRAME_ELEMENT, NoneElement, Settings
|
||||
from .._commons.constants import FRAME_ELEMENT, Settings
|
||||
from .._commons.keys import keys_to_typing, keyDescriptionForString, keyDefinitions
|
||||
from .._commons.locator import get_loc
|
||||
from .._commons.tools import get_usable_path
|
||||
@ -386,7 +387,7 @@ class ChromiumElement(DrissionElement):
|
||||
:param timeout: 查找元素超时时间,默认与元素所在页面等待时间一致
|
||||
:return: ChromiumElement对象或属性、文本
|
||||
"""
|
||||
return self._ele(loc_or_str, timeout)
|
||||
return self._ele(loc_or_str, timeout, method='ele()')
|
||||
|
||||
def eles(self, loc_or_str, timeout=None):
|
||||
"""返回当前元素下级所有符合条件的子元素、属性或节点文本
|
||||
@ -402,8 +403,16 @@ class ChromiumElement(DrissionElement):
|
||||
:return: SessionElement对象或属性、文本
|
||||
"""
|
||||
if self.tag in FRAME_ELEMENT:
|
||||
return make_session_ele(self.inner_html, loc_or_str)
|
||||
return make_session_ele(self, loc_or_str)
|
||||
r = make_session_ele(self.inner_html, loc_or_str)
|
||||
else:
|
||||
r = make_session_ele(self, loc_or_str)
|
||||
if isinstance(r, NoneElement):
|
||||
if Settings.raise_when_ele_not_found:
|
||||
raise ElementNotFoundError(None, 's_ele()', {'loc_or_str': loc_or_str})
|
||||
else:
|
||||
r.method = 's_ele()'
|
||||
r.args = {'loc_or_str': loc_or_str}
|
||||
return r
|
||||
|
||||
def s_eles(self, loc_or_str=None):
|
||||
"""查找所有符合条件的元素,以SessionElement列表形式返回
|
||||
@ -847,7 +856,7 @@ class ChromiumShadowRoot(BaseElement):
|
||||
else:
|
||||
raise TypeError('level_or_loc参数只能是tuple、int或str。')
|
||||
|
||||
return self.parent_ele._ele(loc, timeout=0, relative=True, raise_err=False)
|
||||
return self.parent_ele._ele(loc, timeout=0, relative=True, raise_err=False, method='parent()')
|
||||
|
||||
def child(self, filter_loc='', index=1):
|
||||
"""返回直接子元素元素或节点组成的列表,可用查询语法筛选
|
||||
@ -858,17 +867,17 @@ class ChromiumShadowRoot(BaseElement):
|
||||
nodes = self.children(filter_loc=filter_loc)
|
||||
if not nodes:
|
||||
if Settings.raise_when_ele_not_found:
|
||||
raise ElementNotFoundError
|
||||
raise ElementNotFoundError(None, 'child()', {'filter_loc': filter_loc, 'index': index})
|
||||
else:
|
||||
return NoneElement()
|
||||
return NoneElement('child()', {'filter_loc': filter_loc, 'index': index})
|
||||
|
||||
try:
|
||||
return nodes[index - 1]
|
||||
except IndexError:
|
||||
if Settings.raise_when_ele_not_found:
|
||||
raise ElementNotFoundError
|
||||
raise ElementNotFoundError(None, 'child()', {'filter_loc': filter_loc, 'index': index})
|
||||
else:
|
||||
return NoneElement()
|
||||
return NoneElement('child()', {'filter_loc': filter_loc, 'index': index})
|
||||
|
||||
def next(self, filter_loc='', index=1):
|
||||
"""返回当前元素后面一个符合条件的同级元素,可用查询语法筛选,可指定返回筛选结果的第几个
|
||||
@ -880,9 +889,9 @@ class ChromiumShadowRoot(BaseElement):
|
||||
if nodes:
|
||||
return nodes[index - 1]
|
||||
if Settings.raise_when_ele_not_found:
|
||||
raise ElementNotFoundError
|
||||
raise ElementNotFoundError(None, 'next()', {'filter_loc': filter_loc, 'index': index})
|
||||
else:
|
||||
return NoneElement()
|
||||
return NoneElement('next()', {'filter_loc': filter_loc, 'index': index})
|
||||
|
||||
def before(self, filter_loc='', index=1):
|
||||
"""返回文档中当前元素前面符合条件的第一个元素,可用查询语法筛选,可指定返回筛选结果的第几个
|
||||
@ -895,9 +904,9 @@ class ChromiumShadowRoot(BaseElement):
|
||||
if nodes:
|
||||
return nodes[index - 1]
|
||||
if Settings.raise_when_ele_not_found:
|
||||
raise ElementNotFoundError
|
||||
raise ElementNotFoundError(None, 'before()', {'filter_loc': filter_loc, 'index': index})
|
||||
else:
|
||||
return NoneElement()
|
||||
return NoneElement('before()', {'filter_loc': filter_loc, 'index': index})
|
||||
|
||||
def after(self, filter_loc='', index=1):
|
||||
"""返回文档中此当前元素后面符合条件的第一个元素,可用查询语法筛选,可指定返回筛选结果的第几个
|
||||
@ -910,9 +919,9 @@ class ChromiumShadowRoot(BaseElement):
|
||||
if nodes:
|
||||
return nodes[index - 1]
|
||||
if Settings.raise_when_ele_not_found:
|
||||
raise ElementNotFoundError
|
||||
raise ElementNotFoundError(None, 'after()', {'filter_loc': filter_loc, 'index': index})
|
||||
else:
|
||||
return NoneElement()
|
||||
return NoneElement('after()', {'filter_loc': filter_loc, 'index': index})
|
||||
|
||||
def children(self, filter_loc=''):
|
||||
"""返回当前元素符合条件的直接子元素或节点组成的列表,可用查询语法筛选
|
||||
@ -974,7 +983,7 @@ class ChromiumShadowRoot(BaseElement):
|
||||
:param timeout: 查找元素超时时间,默认与元素所在页面等待时间一致
|
||||
:return: ChromiumElement对象
|
||||
"""
|
||||
return self._ele(loc_or_str, timeout)
|
||||
return self._ele(loc_or_str, timeout, method='ele()')
|
||||
|
||||
def eles(self, loc_or_str, timeout=None):
|
||||
"""返回当前元素下级所有符合条件的子元素
|
||||
@ -989,7 +998,11 @@ class ChromiumShadowRoot(BaseElement):
|
||||
:param loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串
|
||||
:return: SessionElement对象或属性、文本
|
||||
"""
|
||||
return make_session_ele(self, loc_or_str)
|
||||
r = make_session_ele(self, loc_or_str)
|
||||
if isinstance(r, NoneElement):
|
||||
r.method = 's_ele()'
|
||||
r.args = {'loc_or_str': loc_or_str}
|
||||
return r
|
||||
|
||||
def s_eles(self, loc_or_str):
|
||||
"""查找所有符合条件的元素以SessionElement列表形式返回,处理复杂页面时效率很高
|
||||
|
@ -6,8 +6,8 @@
|
||||
from pathlib import Path
|
||||
from typing import Union, Tuple, List, Any
|
||||
|
||||
from .none_element import NoneElement
|
||||
from .._base.base import DrissionElement, BaseElement
|
||||
from .._commons.constants import NoneElement
|
||||
from .._elements.session_element import SessionElement
|
||||
from .._pages.chromium_base import ChromiumBase
|
||||
from .._pages.chromium_frame import ChromiumFrame
|
||||
|
42
DrissionPage/_elements/none_element.py
Normal file
42
DrissionPage/_elements/none_element.py
Normal file
@ -0,0 +1,42 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
@Author : g1879
|
||||
@Contact : g1879@qq.com
|
||||
"""
|
||||
from .._commons.constants import Settings
|
||||
from errors import ElementNotFoundError
|
||||
|
||||
|
||||
class NoneElement(object):
|
||||
def __init__(self, method=None, args=None):
|
||||
self.method = method
|
||||
self.args = args
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
if Settings.NoneElement_value is None:
|
||||
raise ElementNotFoundError(None, self.method, self.args)
|
||||
else:
|
||||
return self
|
||||
|
||||
def __getattr__(self, item):
|
||||
if Settings.NoneElement_value is None:
|
||||
raise ElementNotFoundError(None, self.method, self.args)
|
||||
elif item in ('ele', 's_ele', 'parent', 'child', 'next', 'prev', 'before',
|
||||
'after', 'get_frame', 'shadow_root', 'sr'):
|
||||
return self
|
||||
else:
|
||||
if item in ('size', 'link', 'css_path', 'xpath', 'comments', 'texts', 'tag', 'html', 'inner_html',
|
||||
'attrs', 'text', 'raw_text'):
|
||||
return Settings.NoneElement_value
|
||||
else:
|
||||
raise ElementNotFoundError(None, self.method, self.args)
|
||||
|
||||
def __eq__(self, other):
|
||||
if other is None:
|
||||
return True
|
||||
|
||||
def __bool__(self):
|
||||
return False
|
||||
|
||||
def __repr__(self):
|
||||
return 'None'
|
@ -9,8 +9,8 @@ from re import match, DOTALL
|
||||
from lxml.etree import tostring
|
||||
from lxml.html import HtmlElement, fromstring
|
||||
|
||||
from .none_element import NoneElement
|
||||
from .._base.base import DrissionElement, BasePage, BaseElement
|
||||
from .._commons.constants import NoneElement
|
||||
from .._commons.locator import get_loc
|
||||
from .._commons.web import get_ele_txt, make_absolute_link
|
||||
|
||||
@ -221,7 +221,7 @@ class SessionElement(DrissionElement):
|
||||
:param timeout: 不起实际作用
|
||||
:return: SessionElement对象或属性、文本
|
||||
"""
|
||||
return self._ele(loc_or_str)
|
||||
return self._ele(loc_or_str, method='ele()')
|
||||
|
||||
def eles(self, loc_or_str, timeout=None):
|
||||
"""返回当前元素下级所有符合条件的子元素、属性或节点文本
|
||||
@ -236,7 +236,7 @@ class SessionElement(DrissionElement):
|
||||
:param loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串
|
||||
:return: SessionElement对象或属性、文本
|
||||
"""
|
||||
return self._ele(loc_or_str)
|
||||
return self._ele(loc_or_str, method='s_ele()')
|
||||
|
||||
def s_eles(self, loc_or_str):
|
||||
"""返回当前元素下级所有符合条件的子元素、属性或节点文本
|
||||
|
@ -7,8 +7,8 @@ from typing import Union, List, Tuple
|
||||
|
||||
from lxml.html import HtmlElement
|
||||
|
||||
from .none_element import NoneElement
|
||||
from .._base.base import DrissionElement, BaseElement
|
||||
from .._commons.constants import NoneElement
|
||||
from .._elements.chromium_element import ChromiumElement
|
||||
from .._pages.chromium_base import ChromiumBase
|
||||
from .._pages.chromium_frame import ChromiumFrame
|
||||
|
@ -11,11 +11,12 @@ from threading import Thread
|
||||
from time import perf_counter, sleep
|
||||
|
||||
from .._base.base import BasePage
|
||||
from .._commons.constants import ERROR, NoneElement
|
||||
from .._commons.locator import get_loc
|
||||
from .._commons.constants import ERROR, Settings
|
||||
from .._commons.locator import get_loc, is_loc
|
||||
from .._commons.tools import get_usable_path
|
||||
from .._commons.web import location_in_viewport
|
||||
from .._elements.chromium_element import ChromiumElement, run_js, make_chromium_ele
|
||||
from .._elements.none_element import NoneElement
|
||||
from .._elements.session_element import make_session_ele
|
||||
from .._units.action_chains import ActionChains
|
||||
from .._units.network_listener import NetworkListener
|
||||
@ -26,7 +27,7 @@ from .._units.setter import ChromiumBaseSetter
|
||||
from .._units.states import PageStates
|
||||
from .._units.waiter import BaseWaiter
|
||||
from ..errors import (ContextLossError, ElementLossError, CDPError, PageClosedError, NoRectError, AlertExistsError,
|
||||
GetDocumentError)
|
||||
GetDocumentError, ElementNotFoundError)
|
||||
|
||||
|
||||
class ChromiumBase(BasePage):
|
||||
@ -540,7 +541,7 @@ class ChromiumBase(BasePage):
|
||||
:param timeout: 查找超时时间
|
||||
:return: ChromiumElement对象
|
||||
"""
|
||||
return self._ele(loc_or_ele, timeout=timeout)
|
||||
return self._ele(loc_or_ele, timeout=timeout, method='ele()')
|
||||
|
||||
def eles(self, loc_or_str, timeout=None):
|
||||
"""获取所有符合条件的元素对象
|
||||
@ -555,7 +556,14 @@ class ChromiumBase(BasePage):
|
||||
:param loc_or_ele: 元素的定位信息,可以是loc元组,或查询字符串
|
||||
:return: SessionElement对象或属性、文本
|
||||
"""
|
||||
return make_session_ele(self, loc_or_ele)
|
||||
r = make_session_ele(self, loc_or_ele)
|
||||
if isinstance(r, NoneElement):
|
||||
if Settings.raise_when_ele_not_found:
|
||||
raise ElementNotFoundError(None, 's_ele()', {'loc_or_ele': loc_or_ele})
|
||||
else:
|
||||
r.method = 's_ele()'
|
||||
r.args = {'loc_or_ele': loc_or_ele}
|
||||
return r
|
||||
|
||||
def s_eles(self, loc_or_str):
|
||||
"""查找所有符合条件的元素以SessionElement列表形式返回
|
||||
@ -714,34 +722,39 @@ class ChromiumBase(BasePage):
|
||||
:return: ChromiumFrame对象
|
||||
"""
|
||||
if isinstance(loc_ind_ele, str):
|
||||
if not loc_ind_ele.startswith(('.', '#', '@', 't:', 't=', 'tag:', 'tag=', 'tx:', 'tx=', 'tx^', 'tx$',
|
||||
'text:', 'text=', 'text^', 'text$', 'xpath:', 'xpath=', 'x:', 'x=', 'css:',
|
||||
'css=', 'c:', 'c=')):
|
||||
loc_ind_ele = f'xpath://*[(name()="iframe" or name()="frame") and ' \
|
||||
if not is_loc(loc_ind_ele):
|
||||
xpath = f'xpath://*[(name()="iframe" or name()="frame") and ' \
|
||||
f'(@name="{loc_ind_ele}" or @id="{loc_ind_ele}")]'
|
||||
ele = self._ele(loc_ind_ele, timeout=timeout)
|
||||
else:
|
||||
xpath = loc_ind_ele
|
||||
ele = self._ele(xpath, timeout=timeout)
|
||||
if ele and not str(type(ele)).endswith(".ChromiumFrame'>"):
|
||||
raise TypeError('该定位符不是指向frame元素。')
|
||||
return ele
|
||||
r = ele
|
||||
|
||||
elif isinstance(loc_ind_ele, tuple):
|
||||
ele = self._ele(loc_ind_ele, timeout=timeout)
|
||||
if ele and not str(type(ele)).endswith(".ChromiumFrame'>"):
|
||||
raise TypeError('该定位符不是指向frame元素。')
|
||||
return ele
|
||||
r = ele
|
||||
|
||||
elif isinstance(loc_ind_ele, int):
|
||||
if loc_ind_ele < 1:
|
||||
raise ValueError('序号必须大于0。')
|
||||
xpath = f'xpath:(//*[name()="frame" or name()="iframe"])[{loc_ind_ele}]'
|
||||
return self._ele(xpath, timeout=timeout)
|
||||
r = self._ele(xpath, timeout=timeout)
|
||||
|
||||
elif str(type(loc_ind_ele)).endswith(".ChromiumFrame'>"):
|
||||
return loc_ind_ele
|
||||
r = loc_ind_ele
|
||||
|
||||
else:
|
||||
raise TypeError('必须传入定位符、iframe序号、id、name、ChromiumFrame对象其中之一。')
|
||||
|
||||
if isinstance(r, NoneElement):
|
||||
r.method = 'get_frame()'
|
||||
r.args = {'loc_ind_ele': loc_ind_ele}
|
||||
return r
|
||||
|
||||
def get_frames(self, loc=None, timeout=None):
|
||||
"""获取所有符合条件的frame对象
|
||||
:param loc: 定位符,为None时返回所有
|
||||
|
@ -6,17 +6,17 @@
|
||||
from pathlib import Path
|
||||
from typing import Union, Tuple, List, Any, Optional
|
||||
|
||||
from .._units.rect import TabRect
|
||||
from .._base.base import BasePage
|
||||
from .._base.browser import Browser
|
||||
from .._base.chromium_driver import ChromiumDriver
|
||||
from .._commons.constants import NoneElement
|
||||
from .._elements.chromium_element import ChromiumElement
|
||||
from .._elements.none_element import NoneElement
|
||||
from .._elements.session_element import SessionElement
|
||||
from .._pages.chromium_frame import ChromiumFrame
|
||||
from .._pages.chromium_page import ChromiumPage
|
||||
from .._units.action_chains import ActionChains
|
||||
from .._units.network_listener import NetworkListener
|
||||
from .._units.rect import TabRect
|
||||
from .._units.screencast import Screencast
|
||||
from .._units.scroller import Scroller, PageScroller
|
||||
from .._units.setter import ChromiumBaseSetter
|
||||
|
@ -137,7 +137,7 @@ class SessionPage(BasePage):
|
||||
:param timeout: 不起实际作用,用于和ChromiumElement对应,便于无差别调用
|
||||
:return: SessionElement对象或属性、文本
|
||||
"""
|
||||
return self._ele(loc_or_ele)
|
||||
return self._ele(loc_or_ele, method='ele()')
|
||||
|
||||
def eles(self, loc_or_str, timeout=None):
|
||||
"""返回页面中所有符合条件的元素、属性或节点文本
|
||||
@ -152,7 +152,7 @@ class SessionPage(BasePage):
|
||||
:param loc_or_ele: 元素的定位信息,可以是元素对象,loc元组,或查询字符串
|
||||
:return: SessionElement对象或属性、文本
|
||||
"""
|
||||
return make_session_ele(self.html) if loc_or_ele is None else self._ele(loc_or_ele)
|
||||
return make_session_ele(self.html) if loc_or_ele is None else self._ele(loc_or_ele, method='s_ele()')
|
||||
|
||||
def s_eles(self, loc_or_str):
|
||||
"""返回页面中符合条件的所有元素、属性或节点文本
|
||||
|
@ -9,8 +9,8 @@ from requests import Session, Response
|
||||
from requests.structures import CaseInsensitiveDict
|
||||
|
||||
from .._base.base import BasePage
|
||||
from .._commons.constants import NoneElement
|
||||
from .._configs.session_options import SessionOptions
|
||||
from .._elements.none_element import NoneElement
|
||||
from .._elements.session_element import SessionElement
|
||||
from .._units.setter import SessionPageSetter
|
||||
|
||||
|
@ -9,13 +9,26 @@ class BaseError(Exception):
|
||||
_info = None
|
||||
|
||||
def __init__(self, ErrorInfo=None):
|
||||
super().__init__(self) # 初始化父类
|
||||
self._info = ErrorInfo or self._info
|
||||
|
||||
def __str__(self):
|
||||
return self._info
|
||||
|
||||
|
||||
class ElementNotFoundError(BaseError):
|
||||
_info = '\n没有找到元素。'
|
||||
|
||||
def __init__(self, ErrorInfo=None, method=None, arguments=None):
|
||||
super().__init__(ErrorInfo=ErrorInfo)
|
||||
self.method = method
|
||||
self.arguments = arguments
|
||||
|
||||
def __str__(self):
|
||||
method = f'\nmethod: {self.method}' if self.method else ''
|
||||
arguments = f'\nargs: {self.arguments}' if self.arguments else ''
|
||||
return f'{self._info}{method}{arguments}'
|
||||
|
||||
|
||||
class AlertExistsError(BaseError):
|
||||
_info = '存在未处理的提示框。'
|
||||
|
||||
@ -36,10 +49,6 @@ class PageClosedError(BaseError):
|
||||
_info = '页面已关闭。'
|
||||
|
||||
|
||||
class ElementNotFoundError(BaseError):
|
||||
_info = '没有找到元素。'
|
||||
|
||||
|
||||
class JavaScriptError(BaseError):
|
||||
_info = 'JavaScript运行错误。'
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user