列表中筛选元素增加tag;get_frames()返回ChromiumElementsList

This commit is contained in:
g1879 2024-08-25 23:25:12 +08:00
parent 1029bc225d
commit e10030e23f
5 changed files with 165 additions and 81 deletions

View File

@ -910,7 +910,7 @@ class ShadowRoot(BaseElement):
if result:
return result
return NoneElement(self.owner) if index is not None else ChromiumElementsList()
return NoneElement(self.owner) if index is not None else ChromiumElementsList(self.owner)
def _get_node_id(self, obj_id):
return self.owner._run_cdp('DOM.requestNode', objectId=obj_id)['nodeId']

View File

@ -40,24 +40,14 @@ class ChromiumElementsList(SessionElementsList):
return ChromiumFilterOne(self)
def search(self, displayed=None, checked=None, selected=None, enabled=None, clickable=None,
have_rect=None, have_text=None):
"""或关系筛选元素
:param displayed: 是否显示boolNone为忽略该项
:param checked: 是否被选中boolNone为忽略该项
:param selected: 是否被选择boolNone为忽略该项
:param enabled: 是否可用boolNone为忽略该项
:param clickable: 是否可点击boolNone为忽略该项
:param have_rect: 是否拥有大小和位置boolNone为忽略该项
:param have_text: 是否含有文本boolNone为忽略该项
:return: 筛选结果
"""
have_rect=None, have_text=None, tag=None):
return _search(self, displayed=displayed, checked=checked, selected=selected, enabled=enabled,
clickable=clickable, have_rect=have_rect, have_text=have_text)
clickable=clickable, have_rect=have_rect, have_text=have_text, tag=tag)
def search_one(self, index=1, displayed=None, checked=None, selected=None, enabled=None, clickable=None,
have_rect=None, have_text=None):
have_rect=None, have_text=None, tag=None):
return _search_one(self, index=index, displayed=displayed, checked=checked, selected=selected,
enabled=enabled, clickable=clickable, have_rect=have_rect, have_text=have_text)
enabled=enabled, clickable=clickable, have_rect=have_rect, have_text=have_text, tag=tag)
class SessionFilterOne(object):
@ -69,6 +59,23 @@ class SessionFilterOne(object):
self._index = index
return self
def tag(self, name, equal=True):
num = 0
name = name.lower()
if equal:
for i in self._list:
if not isinstance(i, str) and i.tag == name:
num += 1
if self._index == num:
return i
else:
for i in self._list:
if not isinstance(i, str) and i.tag != name:
num += 1
if self._index == num:
return i
return NoneElement(self._list._owner, 'tag()', args={'name': name, 'equal': equal, 'index': self._index})
def attr(self, name, value, equal=True):
return self._get_attr(name, value, 'attr', equal=equal)
@ -127,14 +134,18 @@ class SessionFilter(SessionFilterOne):
def get(self):
return self._list.get
def tag(self, name, equal=True):
self._list = _tag_all(self._list, SessionElementsList(owner=self._list._owner), name=name, equal=equal)
return self
def text(self, text, fuzzy=True, contain=True):
self._list = _text_all(self._list, SessionElementsList(owner=self._list._owner),
text=text, fuzzy=fuzzy, contain=contain)
return self
def _get_attr(self, name, value, method, equal=True):
self._list = _get_attr_all(self._list, SessionElementsList(owner=self._list._owner),
name=name, value=value, method=method, equal=equal)
self._list = _attr_all(self._list, SessionElementsList(owner=self._list._owner),
name=name, value=value, method=method, equal=equal)
return self
@ -200,14 +211,18 @@ class ChromiumFilter(ChromiumFilterOne):
return self._list.get
def search_one(self, index=1, displayed=None, checked=None, selected=None, enabled=None, clickable=None,
have_rect=None, have_text=None):
have_rect=None, have_text=None, tag=None):
return _search_one(self._list, index=index, displayed=displayed, checked=checked, selected=selected,
enabled=enabled, clickable=clickable, have_rect=have_rect, have_text=have_text)
enabled=enabled, clickable=clickable, have_rect=have_rect, have_text=have_text, tag=tag)
def search(self, displayed=None, checked=None, selected=None, enabled=None, clickable=None,
have_rect=None, have_text=None):
have_rect=None, have_text=None, tag=None):
return _search(self._list, displayed=displayed, checked=checked, selected=selected, enabled=enabled,
clickable=clickable, have_rect=have_rect, have_text=have_text)
clickable=clickable, have_rect=have_rect, have_text=have_text, tag=tag)
def tag(self, name, equal=True):
self._list = _tag_all(self._list, ChromiumElementsList(owner=self._list._owner), name=name, equal=equal)
return self
def text(self, text, fuzzy=True, contain=True):
self._list = _text_all(self._list, ChromiumElementsList(owner=self._list._owner),
@ -215,8 +230,8 @@ class ChromiumFilter(ChromiumFilterOne):
return self
def _get_attr(self, name, value, method, equal=True):
self._list = _get_attr_all(self._list, ChromiumElementsList(owner=self._list._owner),
name=name, value=value, method=method, equal=equal)
self._list = _attr_all(self._list, ChromiumElementsList(owner=self._list._owner),
name=name, value=value, method=method, equal=equal)
return self
def _any_state(self, name, equal=True):
@ -302,7 +317,7 @@ def get_frame(owner, loc_ind_ele, timeout=None):
return r
def _get_attr_all(src_list, aim_list, name, value, method, equal=True):
def _attr_all(src_list, aim_list, name, value, method, equal=True):
if equal:
for i in src_list:
if not isinstance(i, str) and getattr(i, method)(name) == value:
@ -314,6 +329,19 @@ def _get_attr_all(src_list, aim_list, name, value, method, equal=True):
return aim_list
def _tag_all(src_list, aim_list, name, equal=True):
name = name.lower()
if equal:
for i in src_list:
if not isinstance(i, str) and i.tag == name:
aim_list.append(i)
else:
for i in src_list:
if not isinstance(i, str) and i.tag != name:
aim_list.append(i)
return aim_list
def _text_all(src_list, aim_list, text, fuzzy=True, contain=True):
"""以是否含有指定文本为条件筛选元素
:param text: 用于匹配的文本
@ -335,7 +363,7 @@ def _text_all(src_list, aim_list, text, fuzzy=True, contain=True):
def _search(_list, displayed=None, checked=None, selected=None, enabled=None, clickable=None,
have_rect=None, have_text=None):
have_rect=None, have_text=None, tag=None):
"""或关系筛选元素
:param displayed: 是否显示boolNone为忽略该项
:param checked: 是否被选中boolNone为忽略该项
@ -344,6 +372,7 @@ def _search(_list, displayed=None, checked=None, selected=None, enabled=None, cl
:param clickable: 是否可点击boolNone为忽略该项
:param have_rect: 是否拥有大小和位置boolNone为忽略该项
:param have_text: 是否含有文本boolNone为忽略该项
:param tag: 元素类型
:return: 筛选结果
"""
r = ChromiumElementsList(owner=_list._owner)
@ -362,13 +391,14 @@ def _search(_list, displayed=None, checked=None, selected=None, enabled=None, cl
or (have_rect is not None and (have_rect is True and i.states.has_rect)
or (have_rect is False and not i.states.has_rect))
or (have_text is not None and (have_text is True and i.raw_text)
or (have_text is False and not i.raw_text))):
or (have_text is False and not i.raw_text))
or (tag is not None and i.tag == tag.lower())):
r.append(i)
return ChromiumFilter(r)
def _search_one(_list, index=1, displayed=None, checked=None, selected=None, enabled=None, clickable=None,
have_rect=None, have_text=None):
have_rect=None, have_text=None, tag=None):
"""或关系筛选元素,获取一个结果
:param index: 元素序号从1开始
:param displayed: 是否显示boolNone为忽略该项
@ -378,6 +408,7 @@ def _search_one(_list, index=1, displayed=None, checked=None, selected=None, ena
:param clickable: 是否可点击boolNone为忽略该项
:param have_rect: 是否拥有大小和位置boolNone为忽略该项
:param have_text: 是否含有文本boolNone为忽略该项
:param tag: 元素类型
:return: 筛选结果
"""
num = 0
@ -396,12 +427,13 @@ def _search_one(_list, index=1, displayed=None, checked=None, selected=None, ena
or (have_rect is not None and (have_rect is True and i.states.has_rect)
or (have_rect is False and not i.states.has_rect))
or (have_text is not None and (have_text is True and i.raw_text)
or (have_text is False and not i.raw_text))):
or (have_text is False and not i.raw_text))
or (tag is not None and i.tag == tag.lower())):
num += 1
if num == index:
return i
return NoneElement(_list._owner, method='filter()', args={'displayed': displayed,
'checked': checked, 'selected': selected,
'enabled': enabled, 'clickable': clickable,
'have_rect': have_rect, 'have_text': have_text})
return NoneElement(_list._owner, method='filter()', args={'displayed': displayed, 'checked': checked,
'selected': selected, 'enabled': enabled,
'clickable': clickable, 'have_rect': have_rect,
'have_text': have_text, 'tag': tag})

View File

@ -20,7 +20,12 @@ class SessionElementsList(list):
def __init__(self,
owner: SessionPage = None,
*args): ...
*args):
"""
:param owner: 产生元素列表的页面
:param args:
"""
...
@property
def get(self) -> Getter:
@ -45,7 +50,12 @@ class ChromiumElementsList(SessionElementsList):
def __init__(self,
owner: ChromiumBase = None,
*args): ...
*args):
"""
:param owner: 产生元素列表的页面
:param args:
"""
...
@property
def filter(self) -> ChromiumFilter:
@ -64,7 +74,8 @@ class ChromiumElementsList(SessionElementsList):
enabled: Optional[bool] = None,
clickable: Optional[bool] = None,
have_rect: Optional[bool] = None,
have_text: Optional[bool] = None) -> ChromiumFilter:
have_text: Optional[bool] = None,
tag: str = None) -> ChromiumFilter:
"""或关系筛选元素
:param displayed: 是否显示boolNone为忽略该项
:param checked: 是否被选中boolNone为忽略该项
@ -73,6 +84,7 @@ class ChromiumElementsList(SessionElementsList):
:param clickable: 是否可点击boolNone为忽略该项
:param have_rect: 是否拥有大小和位置boolNone为忽略该项
:param have_text: 是否含有文本boolNone为忽略该项
:param tag: 指定的元素类型
:return: 筛选结果
"""
...
@ -85,7 +97,8 @@ class ChromiumElementsList(SessionElementsList):
enabled: Optional[bool] = None,
clickable: Optional[bool] = None,
have_rect: Optional[bool] = None,
have_text: Optional[bool] = None) -> ChromiumElement:
have_text: Optional[bool] = None,
tag: str = None) -> ChromiumElement:
"""或关系筛选元素,获取一个结果
:param index: 元素序号从1开始
:param displayed: 是否显示boolNone为忽略该项
@ -95,6 +108,7 @@ class ChromiumElementsList(SessionElementsList):
:param clickable: 是否可点击boolNone为忽略该项
:param have_rect: 是否拥有大小和位置boolNone为忽略该项
:param have_text: 是否含有文本boolNone为忽略该项
:param tag: 指定的元素类型
:return: 筛选结果
"""
...
@ -119,6 +133,14 @@ class SessionFilterOne(object):
"""
...
def tag(self, name: str, equal: bool = True) -> SessionElement:
"""筛选某种元素
:param name: 标签页名称
:param equal: True表示匹配这种元素False表示匹配非这种元素
:return: 筛选结果
"""
...
def attr(self, name: str, value: str, equal: bool = True) -> SessionElement:
"""以是否拥有某个attribute值为条件筛选元素
:param name: 属性名称
@ -166,6 +188,14 @@ class SessionFilter(SessionFilterOne):
"""返回用于获取元素属性的对象"""
...
def tag(self, name: str, equal: bool = True) -> SessionFilter:
"""筛选某种元素
:param name: 标签页名称
:param equal: True表示匹配这种元素False表示匹配非这种元素
:return: 筛选结果
"""
...
def attr(self, name: str, value: str, equal: bool = True) -> SessionFilter:
"""以是否拥有某个attribute值为条件筛选元素
:param name: 属性名称
@ -214,6 +244,35 @@ class ChromiumFilterOne(SessionFilterOne):
"""
...
def tag(self, name: str, equal: bool = True) -> SessionElement:
"""筛选某种元素
:param name: 标签页名称
:param equal: True表示匹配这种元素False表示匹配非这种元素
:return: 筛选结果
"""
...
def attr(self, name: str, value: str, equal: bool = True) -> ChromiumElement:
"""以是否拥有某个attribute值为条件筛选元素
:param name: 属性名称
:param value: 属性值
:param equal: True表示匹配name值为value值的元素False表示匹配name值不为value值的
:return: 筛选结果
"""
...
def text(self,
text: str,
fuzzy: bool = True,
contain: bool = True) -> ChromiumElement:
"""以是否含有指定文本为条件筛选元素
:param text: 用于匹配的文本
:param fuzzy: 是否模糊匹配
:param contain: 是否包含该字符串False表示不包含
:return: 筛选结果
"""
...
def displayed(self, equal: bool = True) -> ChromiumElement:
"""以是否显示为条件筛选元素
:param equal: 是否匹配显示的元素False匹配不显示的
@ -276,27 +335,6 @@ class ChromiumFilterOne(SessionFilterOne):
"""
...
def attr(self, name: str, value: str, equal: bool = True) -> ChromiumElement:
"""以是否拥有某个attribute值为条件筛选元素
:param name: 属性名称
:param value: 属性值
:param equal: True表示匹配name值为value值的元素False表示匹配name值不为value值的
:return: 筛选结果
"""
...
def text(self,
text: str,
fuzzy: bool = True,
contain: bool = True) -> ChromiumElement:
"""以是否含有指定文本为条件筛选元素
:param text: 用于匹配的文本
:param fuzzy: 是否模糊匹配
:param contain: 是否包含该字符串False表示不包含
:return: 筛选结果
"""
...
def _get_attr(self,
name: str,
value: str,
@ -333,6 +371,32 @@ class ChromiumFilter(ChromiumFilterOne):
"""返回用于获取元素属性的对象"""
...
def tag(self, name: str, equal: bool = True) -> ChromiumFilter:
"""筛选某种元素
:param name: 标签页名称
:param equal: True表示匹配这种元素False表示匹配非这种元素
:return: 筛选结果
"""
...
def attr(self, name: str, value: str, equal: bool = True) -> ChromiumFilter:
"""以是否拥有某个attribute值为条件筛选元素
:param name: 属性名称
:param value: 属性值
:param equal: True表示匹配name值为value值的元素False表示匹配name值不为value值的
:return: 筛选结果
"""
...
def text(self, text: str, fuzzy: bool = True, contain: bool = True) -> ChromiumFilter:
"""以是否含有指定文本为条件筛选元素
:param text: 用于匹配的文本
:param fuzzy: 是否模糊匹配
:param contain: 是否包含该字符串False表示不包含
:return: 筛选结果
"""
...
def displayed(self, equal: bool = True) -> ChromiumFilter:
"""以是否显示为条件筛选元素
:param equal: 是否匹配显示的元素False匹配不显示的
@ -395,15 +459,6 @@ class ChromiumFilter(ChromiumFilterOne):
"""
...
def attr(self, name: str, value: str, equal: bool = True) -> ChromiumFilter:
"""以是否拥有某个attribute值为条件筛选元素
:param name: 属性名称
:param value: 属性值
:param equal: True表示匹配name值为value值的元素False表示匹配name值不为value值的
:return: 筛选结果
"""
...
def search_one(self,
index: int = 1,
displayed: Optional[bool] = None,
@ -412,7 +467,8 @@ class ChromiumFilter(ChromiumFilterOne):
enabled: Optional[bool] = None,
clickable: Optional[bool] = None,
have_rect: Optional[bool] = None,
have_text: Optional[bool] = None) -> ChromiumElement:
have_text: Optional[bool] = None,
tag: str = None) -> ChromiumElement:
"""或关系筛选元素,获取一个结果
:param index: 元素序号从1开始
:param displayed: 是否显示boolNone为忽略该项
@ -422,6 +478,7 @@ class ChromiumFilter(ChromiumFilterOne):
:param clickable: 是否可点击boolNone为忽略该项
:param have_rect: 是否拥有大小和位置boolNone为忽略该项
:param have_text: 是否含有文本boolNone为忽略该项
:param tag: 指定的元素类型
:return: 筛选结果
"""
...
@ -433,7 +490,8 @@ class ChromiumFilter(ChromiumFilterOne):
enabled: Optional[bool] = None,
clickable: Optional[bool] = None,
have_rect: Optional[bool] = None,
have_text: Optional[bool] = None) -> ChromiumFilter:
have_text: Optional[bool] = None,
tag: str = None) -> ChromiumFilter:
"""或关系筛选元素
:param displayed: 是否显示boolNone为忽略该项
:param checked: 是否被选中boolNone为忽略该项
@ -442,15 +500,7 @@ class ChromiumFilter(ChromiumFilterOne):
:param clickable: 是否可点击boolNone为忽略该项
:param have_rect: 是否拥有大小和位置boolNone为忽略该项
:param have_text: 是否含有文本boolNone为忽略该项
:return: 筛选结果
"""
...
def text(self, text: str, fuzzy: bool = True, contain: bool = True) -> ChromiumFilter:
"""以是否含有指定文本为条件筛选元素
:param text: 用于匹配的文本
:param fuzzy: 是否模糊匹配
:param contain: 是否包含该字符串False表示不包含
:param tag: 指定的元素类型
:return: 筛选结果
"""
...

View File

@ -476,7 +476,7 @@ class ChromiumBase(BasePage):
raise PageDisconnectedError
if perf_counter() >= end_time:
return NoneElement(self) if index is not None else ChromiumElementsList()
return NoneElement(self) if index is not None else ChromiumElementsList(owner=self)
sleep(.1)
timeout = end_time - perf_counter()
@ -601,7 +601,7 @@ class ChromiumBase(BasePage):
def get_frames(self, locator=None, timeout=None):
locator = locator or 'xpath://*[name()="iframe" or name()="frame"]'
frames = self._ele(locator, timeout=timeout, index=None, raise_err=False)
return [i for i in frames if i._type == 'ChromiumFrame']
return ChromiumElementsList(self, frames)
def session_storage(self, item=None):
js = f'sessionStorage.getItem("{item}")' if item else 'sessionStorage'

View File

@ -6,7 +6,7 @@
@License : BSD 3-Clause.
"""
from pathlib import Path
from typing import Union, Tuple, List, Any, Optional, Literal
from typing import Union, Tuple, Any, Optional, Literal
from .chromium_page import ChromiumPage
from .chromium_tab import ChromiumTab
@ -489,7 +489,9 @@ class ChromiumBase(BasePage):
"""
...
def get_frames(self, locator: Union[str, tuple] = None, timeout: float = None) -> List[ChromiumFrame]:
def get_frames(self,
locator: Union[str, tuple] = None,
timeout: float = None) -> ChromiumElementsList:
"""获取所有符合条件的frame对象
:param locator: 定位符为None时返回所有
:param timeout: 查找超时时间