4.0.4.24 支持对eles()结果进行筛选

This commit is contained in:
g1879 2024-06-05 19:06:52 +08:00
parent a13177f86e
commit 6624c2651a
9 changed files with 153 additions and 17 deletions

View File

@ -14,4 +14,4 @@ from ._configs.chromium_options import ChromiumOptions
from ._configs.session_options import SessionOptions
__all__ = ['ChromiumPage', 'ChromiumOptions', 'SessionOptions', 'SessionPage', 'WebPage', '__version__']
__version__ = '4.0.4.23'
__version__ = '4.0.4.24'

View File

@ -19,6 +19,7 @@ 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
from .._units.rect import ElementRect
@ -55,6 +56,7 @@ class ChromiumElement(DrissionElement):
self._tag = None
self._wait = None
self._type = 'ChromiumElement'
self._doc_id = None
if node_id and obj_id and backend_id:
self._node_id = node_id
@ -75,9 +77,6 @@ class ChromiumElement(DrissionElement):
else:
raise ElementLostError
doc = self.run_js('return this.ownerDocument;')
self._doc_id = doc['objectId'] if doc else None
def __repr__(self):
attrs = [f"{k}='{v}'" for k, v in self.attrs.items()]
return f'<ChromiumElement {self.tag} {" ".join(attrs)}>'
@ -1219,8 +1218,12 @@ def find_by_xpath(ele, xpath, index, timeout, relative=True):
res = ele.owner.run_cdp('Runtime.getProperties', objectId=res['result']['objectId'],
ownProperties=True)['result'][:-1]
if index is None:
r = [make_chromium_eles(ele.owner, _ids=i['value']['objectId'], is_obj_id=True)
if i['value']['type'] == 'object' else i['value']['value'] for i in res]
r = ElementsList()
for i in res:
if i['value']['type'] == 'object':
r.append(make_chromium_eles(ele.owner, _ids=i['value']['objectId'], is_obj_id=True))
else:
r.append(i['value']['value'])
return None if False in r else r
else:
@ -1244,7 +1247,7 @@ def find_by_xpath(ele, xpath, index, timeout, relative=True):
if result:
return result
return NoneElement(ele.owner) if index is not None else []
return NoneElement(ele.owner) if index is not None else ElementsList()
def find_by_css(ele, selector, index, timeout):
@ -1290,7 +1293,7 @@ def find_by_css(ele, selector, index, timeout):
if result:
return result
return NoneElement(ele.owner) if index is not None else []
return NoneElement(ele.owner) if index is not None else ElementsList()
def make_chromium_eles(page, _ids, index=1, is_obj_id=True, ele_only=False):
@ -1322,7 +1325,7 @@ def make_chromium_eles(page, _ids, index=1, is_obj_id=True, ele_only=False):
return get_node_func(page, obj_id, ele_only)
else: # 获取全部
nodes = []
nodes = ElementsList()
for obj_id in _ids:
tmp = get_node_func(page, obj_id, ele_only)
if tmp is False:

View File

@ -10,6 +10,7 @@ from typing import Union, Tuple, List, Any, Literal, Optional
from .._base.base import DrissionElement, BaseElement
from .._elements.session_element import SessionElement
from .._functions.tools import ElementsList
from .._pages.chromium_base import ChromiumBase
from .._pages.chromium_frame import ChromiumFrame
from .._pages.chromium_page import ChromiumPage
@ -188,7 +189,7 @@ class ChromiumElement(DrissionElement):
def eles(self,
locator: Union[Tuple[str, str], str],
timeout: float = None) -> List[ChromiumElement]: ...
timeout: float = None) -> ElementsList: ...
def s_ele(self,
locator: Union[Tuple[str, str], str] = None,
@ -318,7 +319,7 @@ class ShadowRoot(BaseElement):
def eles(self,
locator: Union[Tuple[str, str], str],
timeout: float = None) -> List[ChromiumElement]: ...
timeout: float = None) -> ElementsList: ...
def s_ele(self,
locator: Union[Tuple[str, str], str] = None,

View File

@ -353,8 +353,14 @@ def make_session_ele(html_or_ele, loc=None, index=1):
page = html_or_ele.owner
xpath = html_or_ele.xpath
# ChromiumElement兼容传入的元素在iframe内的情况
html = html_or_ele.owner.run_cdp('DOM.getOuterHTML', objectId=html_or_ele._doc_id)['outerHTML'] \
if html_or_ele._doc_id else html_or_ele.owner.html
if html_or_ele._doc_id is None:
doc = html_or_ele.run_js('return this.ownerDocument;')
html_or_ele._doc_id = doc['objectId'] if doc else False
if html_or_ele._doc_id:
html = html_or_ele.owner.run_cdp('DOM.getOuterHTML', objectId=html_or_ele._doc_id)['outerHTML']
else:
html = html_or_ele.owner.html
html_or_ele = fromstring(html)
html_or_ele = html_or_ele.xpath(xpath)[0]

View File

@ -232,3 +232,94 @@ def raise_error(result, ignore=None):
if not ignore or not isinstance(r, ignore):
raise r
class ElementsList(list):
def displayed(self):
"""返回所有显示的元素"""
return self._any_state('is_displayed')
def hidden(self):
"""返回所有不显示的元素"""
return self._any_state('is_displayed', True)
def checked(self):
"""返回所有被选中的元素"""
return self._any_state('is_checked')
def not_checked(self):
"""返回所有没被选中的元素"""
return self._any_state('is_checked', True)
def selected(self):
"""返回所有被选中的列表元素"""
return self._any_state('is_selected')
def not_selected(self):
"""返回所有没被选中的列表元素"""
return self._any_state('is_selected', True)
def enabled(self):
"""返回所有有效的元素"""
return self._any_state('is_enabled')
def disabled(self):
"""返回所有无效的元素"""
return self._any_state('is_enabled', True)
def clickable(self):
"""返回所有可被点击的元素"""
return self._any_state('is_clickable')
def not_clickable(self):
"""返回所有不可被点击的元素"""
return self._any_state('is_clickable', True)
def has_rect(self):
"""返回所有有大小和位置的元素"""
return self._any_state('has_rect')
def no_rect(self):
"""返回所有没有大小和位置的元素"""
return self._any_state('has_rect', True)
def style(self, name, value):
"""返回所有拥有某个style值的元素
:param name: 属性名称
:param value: 属性值
:return: 筛选结果
"""
r = ElementsList()
for i in self:
if i.style(name) == value:
r.append(i)
return r
def property(self, name, value):
"""返回所有拥有某个property值的元素
:param name: 属性名称
:param value: 属性值
:return: 筛选结果
"""
r = ElementsList()
for i in self:
if i.property(name) == value:
r.append(i)
return r
def _any_state(self, name, is_not=False):
"""
:param name: 状态名称
:param is_not: 是否选择否定的
:return: 选中的列表
"""
r = ElementsList()
if is_not:
for i in self:
if not getattr(i.states, name):
r.append(i)
else:
for i in self:
if getattr(i.states, name):
r.append(i)
return r

View File

@ -8,8 +8,9 @@
from os import popen
from pathlib import Path
from threading import Lock
from typing import Union, Tuple
from typing import Union, Tuple, List
from .._elements.chromium_element import ChromiumElement
from .._pages.chromium_base import ChromiumBase
@ -46,3 +47,35 @@ def configs_to_here(file_name: Union[Path, str] = None) -> None: ...
def raise_error(result: dict, ignore=None) -> None: ...
class ElementsList(list):
def displayed(self) -> List[ChromiumElement]: ...
def hidden(self) -> List[ChromiumElement]: ...
def checked(self) -> List[ChromiumElement]: ...
def not_checked(self) -> List[ChromiumElement]: ...
def selected(self) -> List[ChromiumElement]: ...
def not_selected(self) -> List[ChromiumElement]: ...
def enabled(self) -> List[ChromiumElement]: ...
def disabled(self) -> List[ChromiumElement]: ...
def clickable(self) -> List[ChromiumElement]: ...
def not_clickable(self) -> List[ChromiumElement]: ...
def has_rect(self) -> List[ChromiumElement]: ...
def no_rect(self) -> List[ChromiumElement]: ...
def style(self, name: str, value: str) -> List[ChromiumElement]: ...
def property(self, name: str, value: str) -> List[ChromiumElement]: ...
def _any_state(self, name: str, is_not: bool = False) -> List[ChromiumElement]: ...

View File

@ -14,6 +14,7 @@ from .._base.browser import Browser
from .._base.driver import Driver
from .._elements.chromium_element import ChromiumElement
from .._elements.session_element import SessionElement
from .._functions.tools import ElementsList
from .._pages.chromium_frame import ChromiumFrame
from .._pages.chromium_page import ChromiumPage
from .._units.actions import Actions
@ -187,7 +188,7 @@ class ChromiumBase(BasePage):
def eles(self,
locator: Union[Tuple[str, str], str],
timeout: float = None) -> List[ChromiumElement]: ...
timeout: float = None) -> ElementsList: ...
def s_ele(self,
locator: Union[Tuple[str, str], str] = None,

View File

@ -19,6 +19,7 @@ from .._configs.chromium_options import ChromiumOptions
from .._configs.session_options import SessionOptions
from .._elements.chromium_element import ChromiumElement
from .._elements.session_element import SessionElement
from .._functions.tools import ElementsList
from .._units.setter import WebPageSetter
@ -108,7 +109,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
def eles(self,
locator: Union[Tuple[str, str], str],
timeout: float = None) -> List[Union[ChromiumElement, SessionElement]]: ...
timeout: float = None) -> Union[ElementsList, List[Union[ChromiumElement, SessionElement]]]: ...
def s_ele(self,
locator: Union[Tuple[str, str], str] = None,

View File

@ -18,7 +18,7 @@ class ElementStates(object):
@property
def is_selected(self):
"""返回元素是否被选择"""
"""返回列表元素是否被选择"""
return self._ele.run_js('return this.selected;')
@property