mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
完善eles()筛选和获取元素属性功能
This commit is contained in:
parent
15f59258bf
commit
dc5eae65ec
@ -18,7 +18,7 @@ from .session_element import make_session_ele
|
|||||||
from .._base.base import DrissionElement, BaseElement
|
from .._base.base import DrissionElement, BaseElement
|
||||||
from .._functions.keys import input_text_or_keys
|
from .._functions.keys import input_text_or_keys
|
||||||
from .._functions.locator import get_loc
|
from .._functions.locator import get_loc
|
||||||
from .._functions.tools import ElementsList
|
from .._functions.elements import ElementsList
|
||||||
from .._functions.web import make_absolute_link, get_ele_txt, format_html, is_js_func, offset_scroll, get_blob
|
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.clicker import Clicker
|
||||||
from .._units.rect import ElementRect
|
from .._units.rect import ElementRect
|
||||||
|
@ -10,7 +10,7 @@ from typing import Union, Tuple, List, Any, Literal, Optional
|
|||||||
|
|
||||||
from .._base.base import DrissionElement, BaseElement
|
from .._base.base import DrissionElement, BaseElement
|
||||||
from .._elements.session_element import SessionElement
|
from .._elements.session_element import SessionElement
|
||||||
from .._functions.tools import ElementsList
|
from .._functions.elements import ElementsList
|
||||||
from .._pages.chromium_base import ChromiumBase
|
from .._pages.chromium_base import ChromiumBase
|
||||||
from .._pages.chromium_frame import ChromiumFrame
|
from .._pages.chromium_frame import ChromiumFrame
|
||||||
from .._pages.chromium_page import ChromiumPage
|
from .._pages.chromium_page import ChromiumPage
|
||||||
|
309
DrissionPage/_functions/elements.py
Normal file
309
DrissionPage/_functions/elements.py
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
# -*- coding:utf-8 -*-
|
||||||
|
"""
|
||||||
|
@Author : g1879
|
||||||
|
@Contact : g1879@qq.com
|
||||||
|
@Copyright: (c) 2024 by g1879, Inc. All Rights Reserved.
|
||||||
|
@License : BSD 3-Clause.
|
||||||
|
"""
|
||||||
|
from time import perf_counter
|
||||||
|
|
||||||
|
from .._elements.none_element import NoneElement
|
||||||
|
|
||||||
|
|
||||||
|
class ElementsList(list):
|
||||||
|
def __init__(self, page=None):
|
||||||
|
super().__init__()
|
||||||
|
self._page = page
|
||||||
|
self._filter = None
|
||||||
|
self._filter_one = None
|
||||||
|
self._getter = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def filter(self):
|
||||||
|
if self._filter is None:
|
||||||
|
self._filter = Filter(self)
|
||||||
|
return self._filter
|
||||||
|
|
||||||
|
@property
|
||||||
|
def filter_one(self):
|
||||||
|
if self._filter_one is None:
|
||||||
|
self._filter_one = FilterOne(self)
|
||||||
|
return self._filter_one
|
||||||
|
|
||||||
|
@property
|
||||||
|
def get(self):
|
||||||
|
if self._getter is None:
|
||||||
|
self._getter = Getter(self)
|
||||||
|
return self._getter
|
||||||
|
|
||||||
|
def search(self, get_all=False, displayed=None, checked=None, selected=None, enabled=None, clickable=None,
|
||||||
|
have_rect=None, have_text=None):
|
||||||
|
"""或关系筛选元素
|
||||||
|
:param get_all: 是否返回所有筛选到的元素
|
||||||
|
:param displayed: 是否显示,bool,None为忽略该项
|
||||||
|
:param checked: 是否被选中,bool,None为忽略该项
|
||||||
|
:param selected: 是否被选择,bool,None为忽略该项
|
||||||
|
:param enabled: 是否可用,bool,None为忽略该项
|
||||||
|
:param clickable: 是否可点击,bool,None为忽略该项
|
||||||
|
:param have_rect: 是否拥有大小和位置,bool,None为忽略该项
|
||||||
|
:param have_text: 是否含有文本,bool,None为忽略该项
|
||||||
|
:return: 筛选结果
|
||||||
|
"""
|
||||||
|
if get_all:
|
||||||
|
r = ElementsList()
|
||||||
|
for i in self:
|
||||||
|
if ((displayed is not None and (displayed is True and i.states.is_displayed) or (
|
||||||
|
displayed is False and not i.states.is_displayed))
|
||||||
|
or (checked is not None and (checked is True and i.states.is_checked) or (
|
||||||
|
checked is False and not i.states.is_checked))
|
||||||
|
or (selected is not None and (selected is True and i.states.is_selected) or (
|
||||||
|
selected is False and not i.states.is_selected))
|
||||||
|
or (enabled is not None and (enabled is True and i.states.is_enabled) or (
|
||||||
|
enabled is False and not i.states.is_enabled))
|
||||||
|
or (clickable is not None and (clickable is True and i.states.is_clickable) or (
|
||||||
|
clickable is False and not i.states.is_clickable))
|
||||||
|
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))):
|
||||||
|
r.append(i)
|
||||||
|
return r
|
||||||
|
|
||||||
|
for i in self:
|
||||||
|
if ((displayed is not None and (displayed is True and i.states.is_displayed) or (
|
||||||
|
displayed is False and not i.states.is_displayed))
|
||||||
|
or (checked is not None and (checked is True and i.states.is_checked) or (
|
||||||
|
checked is False and not i.states.is_checked))
|
||||||
|
or (selected is not None and (selected is True and i.states.is_selected) or (
|
||||||
|
selected is False and not i.states.is_selected))
|
||||||
|
or (enabled is not None and (enabled is True and i.states.is_enabled) or (
|
||||||
|
enabled is False and not i.states.is_enabled))
|
||||||
|
or (clickable is not None and (clickable is True and i.states.is_clickable) or (
|
||||||
|
clickable is False and not i.states.is_clickable))
|
||||||
|
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))):
|
||||||
|
return i
|
||||||
|
|
||||||
|
return NoneElement(self._page, method='filter()', args={'get_all': get_all, 'displayed': displayed,
|
||||||
|
'checked': checked, 'selected': selected,
|
||||||
|
'enabled': enabled, 'clickable': clickable,
|
||||||
|
'have_rect': have_rect, 'have_text': have_text})
|
||||||
|
|
||||||
|
|
||||||
|
class BaseFilter(object):
|
||||||
|
def __init__(self, _list):
|
||||||
|
self._list = _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 have_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: 筛选结果
|
||||||
|
"""
|
||||||
|
return self._get_attr(name, value, 'style')
|
||||||
|
|
||||||
|
def property(self, name, value):
|
||||||
|
"""返回拥有某个property值的元素
|
||||||
|
:param name: 属性名称
|
||||||
|
:param value: 属性值
|
||||||
|
:return: 筛选结果
|
||||||
|
"""
|
||||||
|
return self._get_attr(name, value, 'property')
|
||||||
|
|
||||||
|
def attr(self, name, value):
|
||||||
|
"""返回拥有某个attribute值的元素
|
||||||
|
:param name: 属性名称
|
||||||
|
:param value: 属性值
|
||||||
|
:return: 筛选结果
|
||||||
|
"""
|
||||||
|
return self._get_attr(name, value, 'attr')
|
||||||
|
|
||||||
|
def _get_attr(self, name, value, method):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _any_state(self, name, is_not=False):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Filter(BaseFilter):
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return iter(self._list)
|
||||||
|
|
||||||
|
def __next__(self):
|
||||||
|
return next(self._list)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def get(self):
|
||||||
|
"""返回用于获取元素属性的对象"""
|
||||||
|
return self._list.get
|
||||||
|
|
||||||
|
def have_text(self):
|
||||||
|
"""返回包含文本的元素"""
|
||||||
|
r = ElementsList()
|
||||||
|
for i in self._list:
|
||||||
|
if i.raw_text:
|
||||||
|
r.append(i)
|
||||||
|
self._list = r
|
||||||
|
return self
|
||||||
|
|
||||||
|
def _get_attr(self, name, value, method):
|
||||||
|
"""返回通过某个方法可获得某个值的元素
|
||||||
|
:param name: 属性名称
|
||||||
|
:param value: 属性值
|
||||||
|
:param method: 方法名称
|
||||||
|
:return: 筛选结果
|
||||||
|
"""
|
||||||
|
r = ElementsList()
|
||||||
|
for i in self._list:
|
||||||
|
if getattr(i, method)(name) == value:
|
||||||
|
r.append(i)
|
||||||
|
self._list = r
|
||||||
|
return self
|
||||||
|
|
||||||
|
def _any_state(self, name, is_not=False):
|
||||||
|
"""
|
||||||
|
:param name: 状态名称
|
||||||
|
:param is_not: 是否选择否定的
|
||||||
|
:return: 选中的列表
|
||||||
|
"""
|
||||||
|
r = ElementsList()
|
||||||
|
if is_not:
|
||||||
|
for i in self._list:
|
||||||
|
if not getattr(i.states, name):
|
||||||
|
r.append(i)
|
||||||
|
else:
|
||||||
|
for i in self._list:
|
||||||
|
if getattr(i.states, name):
|
||||||
|
r.append(i)
|
||||||
|
self._list = r
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
class FilterOne(BaseFilter):
|
||||||
|
|
||||||
|
def have_text(self):
|
||||||
|
"""返回包含文本的元素"""
|
||||||
|
for i in self._list:
|
||||||
|
if i.raw_text:
|
||||||
|
return i
|
||||||
|
return NoneElement(self._list._page, method='have_text()')
|
||||||
|
|
||||||
|
def _get_attr(self, name, value, method):
|
||||||
|
"""返回通过某个方法可获得某个值的元素
|
||||||
|
:param name: 属性名称
|
||||||
|
:param value: 属性值
|
||||||
|
:param method: 方法名称
|
||||||
|
:return: 筛选结果
|
||||||
|
"""
|
||||||
|
for i in self._list:
|
||||||
|
if getattr(i, method)(name) == value:
|
||||||
|
return i
|
||||||
|
return NoneElement(self._list._page, f'{method}()', args={'name': name, 'value': value})
|
||||||
|
|
||||||
|
def _any_state(self, name, is_not=False):
|
||||||
|
"""
|
||||||
|
:param name: 状态名称
|
||||||
|
:param is_not: 是否选择否定的
|
||||||
|
:return: 选中的列表
|
||||||
|
"""
|
||||||
|
if is_not:
|
||||||
|
for i in self._list:
|
||||||
|
if not getattr(i.states, name):
|
||||||
|
return i
|
||||||
|
else:
|
||||||
|
for i in self._list:
|
||||||
|
if getattr(i.states, name):
|
||||||
|
return i
|
||||||
|
|
||||||
|
return NoneElement(self._list._page, f'{name}()', args={'name': name, 'is_not': is_not})
|
||||||
|
|
||||||
|
|
||||||
|
class Getter(object):
|
||||||
|
def __init__(self, _list):
|
||||||
|
self._list = _list
|
||||||
|
|
||||||
|
def links(self):
|
||||||
|
return [e.link for e in self._list]
|
||||||
|
|
||||||
|
def texts(self):
|
||||||
|
return [e.text for e in self._list]
|
||||||
|
|
||||||
|
def attrs(self, name):
|
||||||
|
return [e.attr(name) for e in self._list]
|
||||||
|
|
||||||
|
|
||||||
|
def get_eles(locators, owner, any_one=False, first_ele=True, timeout=10):
|
||||||
|
"""传入多个定位符,获取多个ele
|
||||||
|
:param locators: 定位符组成的列表
|
||||||
|
:param owner: 页面或元素对象
|
||||||
|
:param any_one: 是否找到任何一个即返回
|
||||||
|
:param first_ele: 每个定位符是否只获取第一个元素
|
||||||
|
:param timeout: 超时时间(秒)
|
||||||
|
:return: 多个定位符组成的dict
|
||||||
|
"""
|
||||||
|
res = {loc: False for loc in locators}
|
||||||
|
end_time = perf_counter() + timeout
|
||||||
|
while perf_counter() <= end_time:
|
||||||
|
for loc in locators:
|
||||||
|
if res[loc] is not False:
|
||||||
|
continue
|
||||||
|
ele = owner.ele(loc, timeout=0) if first_ele else owner.eles(loc, timeout=0)
|
||||||
|
if ele:
|
||||||
|
res[loc] = ele
|
||||||
|
if any_one:
|
||||||
|
return res
|
||||||
|
if False not in res.values():
|
||||||
|
break
|
||||||
|
|
||||||
|
return res
|
206
DrissionPage/_functions/elements.pyi
Normal file
206
DrissionPage/_functions/elements.pyi
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
# -*- coding:utf-8 -*-
|
||||||
|
"""
|
||||||
|
@Author : g1879
|
||||||
|
@Contact : g1879@qq.com
|
||||||
|
@Copyright: (c) 2024 by g1879, Inc. All Rights Reserved.
|
||||||
|
@License : BSD 3-Clause.
|
||||||
|
"""
|
||||||
|
from typing import Union, List, Optional, Iterable
|
||||||
|
|
||||||
|
from .._base.base import BaseParser
|
||||||
|
from .._elements.chromium_element import ChromiumElement
|
||||||
|
|
||||||
|
|
||||||
|
def get_eles(locators: Union[List[str], tuple],
|
||||||
|
owner: BaseParser,
|
||||||
|
any_one: bool = False,
|
||||||
|
first_ele: bool = True,
|
||||||
|
timeout: float = 10) -> dict: ...
|
||||||
|
|
||||||
|
|
||||||
|
class ElementsList(list):
|
||||||
|
_page = ...
|
||||||
|
_filter: Optional[Filter] = ...
|
||||||
|
_filter_one: Optional[FilterOne] = ...
|
||||||
|
_getter: Optional[Getter] = ...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def filter(self) -> Filter: ...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def filter_one(self) -> FilterOne: ...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def get(self) -> Getter: ...
|
||||||
|
|
||||||
|
def search(self,
|
||||||
|
get_all: bool = False,
|
||||||
|
displayed: Optional[bool] = None,
|
||||||
|
checked: Optional[bool] = None,
|
||||||
|
selected: Optional[bool] = None,
|
||||||
|
enabled: Optional[bool] = None,
|
||||||
|
clickable: Optional[bool] = None,
|
||||||
|
have_rect: Optional[bool] = None,
|
||||||
|
have_text: Optional[bool] = None) -> Union[ElementsList, ChromiumElement]: ...
|
||||||
|
|
||||||
|
def __next__(self) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
|
||||||
|
class BaseFilter(object):
|
||||||
|
_list: ElementsList = ...
|
||||||
|
|
||||||
|
def __init__(self, _list: ElementsList): ...
|
||||||
|
|
||||||
|
def displayed(self): ...
|
||||||
|
|
||||||
|
def hidden(self): ...
|
||||||
|
|
||||||
|
def checked(self): ...
|
||||||
|
|
||||||
|
def not_checked(self): ...
|
||||||
|
|
||||||
|
def selected(self): ...
|
||||||
|
|
||||||
|
def not_selected(self): ...
|
||||||
|
|
||||||
|
def enabled(self): ...
|
||||||
|
|
||||||
|
def disabled(self): ...
|
||||||
|
|
||||||
|
def clickable(self): ...
|
||||||
|
|
||||||
|
def not_clickable(self): ...
|
||||||
|
|
||||||
|
def have_rect(self): ...
|
||||||
|
|
||||||
|
def no_rect(self): ...
|
||||||
|
|
||||||
|
# def have_text(self): ...
|
||||||
|
|
||||||
|
def style(self, name: str, value: str): ...
|
||||||
|
|
||||||
|
def property(self,
|
||||||
|
name: str,
|
||||||
|
value: str): ...
|
||||||
|
|
||||||
|
def attr(self, name: str, value: str): ...
|
||||||
|
|
||||||
|
def _get_attr(self,
|
||||||
|
name: str,
|
||||||
|
value: str,
|
||||||
|
method: str): ...
|
||||||
|
|
||||||
|
def _any_state(self, name: str, is_not: bool = False): ...
|
||||||
|
|
||||||
|
|
||||||
|
class Filter:
|
||||||
|
_list: ElementsList = ...
|
||||||
|
|
||||||
|
def __init__(self, _list: ElementsList): ...
|
||||||
|
|
||||||
|
def __iter__(self) -> Iterable[ChromiumElement]: ...
|
||||||
|
|
||||||
|
def __next__(self) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def get(self) -> Getter: ...
|
||||||
|
|
||||||
|
def displayed(self) -> Filter: ...
|
||||||
|
|
||||||
|
def hidden(self) -> Filter: ...
|
||||||
|
|
||||||
|
def checked(self) -> Filter: ...
|
||||||
|
|
||||||
|
def not_checked(self) -> Filter: ...
|
||||||
|
|
||||||
|
def selected(self) -> Filter: ...
|
||||||
|
|
||||||
|
def not_selected(self) -> Filter: ...
|
||||||
|
|
||||||
|
def enabled(self) -> Filter: ...
|
||||||
|
|
||||||
|
def disabled(self) -> Filter: ...
|
||||||
|
|
||||||
|
def clickable(self) -> Filter: ...
|
||||||
|
|
||||||
|
def not_clickable(self) -> Filter: ...
|
||||||
|
|
||||||
|
def have_rect(self) -> Filter: ...
|
||||||
|
|
||||||
|
def no_rect(self) -> Filter: ...
|
||||||
|
|
||||||
|
def have_text(self) -> Filter: ...
|
||||||
|
|
||||||
|
def style(self, name: str, value: str) -> Filter: ...
|
||||||
|
|
||||||
|
def property(self,
|
||||||
|
name: str,
|
||||||
|
value: str) -> Filter: ...
|
||||||
|
|
||||||
|
def attr(self, name: str, value: str) -> Filter: ...
|
||||||
|
|
||||||
|
def _get_attr(self,
|
||||||
|
name: str,
|
||||||
|
value: str,
|
||||||
|
method: str) -> Filter: ...
|
||||||
|
|
||||||
|
def _any_state(self, name: str, is_not: bool = False) -> Filter: ...
|
||||||
|
|
||||||
|
|
||||||
|
class FilterOne(BaseFilter):
|
||||||
|
_list: ElementsList = ...
|
||||||
|
|
||||||
|
def __init__(self, _list: ElementsList): ...
|
||||||
|
|
||||||
|
def displayed(self) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
def hidden(self) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
def checked(self) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
def not_checked(self) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
def selected(self) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
def not_selected(self) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
def enabled(self) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
def disabled(self) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
def clickable(self) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
def not_clickable(self) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
def have_rect(self) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
def no_rect(self) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
def have_text(self) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
def style(self, name: str, value: str) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
def property(self,
|
||||||
|
name: str,
|
||||||
|
value: str) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
def attr(self, name: str, value: str) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
def _get_attr(self,
|
||||||
|
name: str,
|
||||||
|
value: str,
|
||||||
|
method: str) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
def _any_state(self, name: str, is_not: bool = False) -> ChromiumElement: ...
|
||||||
|
|
||||||
|
|
||||||
|
class Getter(object):
|
||||||
|
_list: ElementsList = ...
|
||||||
|
|
||||||
|
def __init__(self, _list: ElementsList): ...
|
||||||
|
|
||||||
|
def links(self) -> list: ...
|
||||||
|
|
||||||
|
def texts(self) -> list: ...
|
||||||
|
|
||||||
|
def attrs(self, name) -> list: ...
|
@ -13,7 +13,6 @@ from threading import Lock
|
|||||||
from time import perf_counter, sleep
|
from time import perf_counter, sleep
|
||||||
|
|
||||||
from .._configs.options_manage import OptionsManager
|
from .._configs.options_manage import OptionsManager
|
||||||
from .._elements.none_element import NoneElement
|
|
||||||
from ..errors import (ContextLostError, ElementLostError, CDPError, PageDisconnectedError, NoRectError,
|
from ..errors import (ContextLostError, ElementLostError, CDPError, PageDisconnectedError, NoRectError,
|
||||||
AlertExistsError, WrongURLError, StorageError, CookieFormatError, JavaScriptError)
|
AlertExistsError, WrongURLError, StorageError, CookieFormatError, JavaScriptError)
|
||||||
|
|
||||||
@ -233,269 +232,3 @@ def raise_error(result, ignore=None):
|
|||||||
|
|
||||||
if not ignore or not isinstance(r, ignore):
|
if not ignore or not isinstance(r, ignore):
|
||||||
raise r
|
raise r
|
||||||
|
|
||||||
|
|
||||||
class ElementsList(list):
|
|
||||||
def __init__(self, page=None):
|
|
||||||
super().__init__()
|
|
||||||
self.page = page
|
|
||||||
|
|
||||||
def displayed(self, get_all=False):
|
|
||||||
"""返回显示的元素,默认返回第一个
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:return: 元素或元素组成的列表
|
|
||||||
"""
|
|
||||||
return self._any_state('is_displayed', get_all=get_all)
|
|
||||||
|
|
||||||
def hidden(self, get_all=False):
|
|
||||||
"""返回不显示的元素,默认返回第一个
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:return: 元素或元素组成的列表
|
|
||||||
"""
|
|
||||||
return self._any_state('is_displayed', True, get_all=get_all)
|
|
||||||
|
|
||||||
def checked(self, get_all=False):
|
|
||||||
"""返回被选中的元素,默认返回第一个
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:return: 元素或元素组成的列表
|
|
||||||
"""
|
|
||||||
return self._any_state('is_checked', get_all=get_all)
|
|
||||||
|
|
||||||
def not_checked(self, get_all=False):
|
|
||||||
"""返回没被选中的元素,默认返回第一个
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:return: 元素或元素组成的列表
|
|
||||||
"""
|
|
||||||
return self._any_state('is_checked', True, get_all=get_all)
|
|
||||||
|
|
||||||
def selected(self, get_all=False):
|
|
||||||
"""返回被选中的列表元素,默认返回第一个
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:return: 元素或元素组成的列表
|
|
||||||
"""
|
|
||||||
return self._any_state('is_selected', get_all=get_all)
|
|
||||||
|
|
||||||
def not_selected(self, get_all=False):
|
|
||||||
"""返回没被选中的列表元素,默认返回第一个
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:return: 元素或元素组成的列表
|
|
||||||
"""
|
|
||||||
return self._any_state('is_selected', True, get_all=get_all)
|
|
||||||
|
|
||||||
def enabled(self, get_all=False):
|
|
||||||
"""返回有效的元素,默认返回第一个
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:return: 元素或元素组成的列表
|
|
||||||
"""
|
|
||||||
return self._any_state('is_enabled', get_all=get_all)
|
|
||||||
|
|
||||||
def disabled(self, get_all=False):
|
|
||||||
"""返回无效的元素,默认返回第一个
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:return: 元素或元素组成的列表
|
|
||||||
"""
|
|
||||||
return self._any_state('is_enabled', True, get_all=get_all)
|
|
||||||
|
|
||||||
def clickable(self, get_all=False):
|
|
||||||
"""返回可被点击的元素,默认返回第一个
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:return: 元素或元素组成的列表
|
|
||||||
"""
|
|
||||||
return self._any_state('is_clickable', get_all=get_all)
|
|
||||||
|
|
||||||
def not_clickable(self, get_all=False):
|
|
||||||
"""返回不可被点击的元素,默认返回第一个
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:return: 元素或元素组成的列表
|
|
||||||
"""
|
|
||||||
return self._any_state('is_clickable', True, get_all=get_all)
|
|
||||||
|
|
||||||
def have_rect(self, get_all=False):
|
|
||||||
"""返回有大小和位置的元素,默认返回第一个
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:return: 元素或元素组成的列表
|
|
||||||
"""
|
|
||||||
return self._any_state('has_rect', get_all=get_all)
|
|
||||||
|
|
||||||
def no_rect(self, get_all=False):
|
|
||||||
"""返回没有大小和位置的元素,默认返回第一个
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:return: 元素或元素组成的列表
|
|
||||||
"""
|
|
||||||
return self._any_state('has_rect', True, get_all=get_all)
|
|
||||||
|
|
||||||
def have_text(self, get_all=False):
|
|
||||||
"""返回包含文本的元素,默认返回第一个
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:return: 元素或元素组成的列表
|
|
||||||
"""
|
|
||||||
if get_all:
|
|
||||||
r = ElementsList()
|
|
||||||
for i in self:
|
|
||||||
if i.raw_text:
|
|
||||||
r.append(i)
|
|
||||||
return r
|
|
||||||
|
|
||||||
for i in self:
|
|
||||||
if i.raw_text:
|
|
||||||
return i
|
|
||||||
|
|
||||||
return NoneElement(self.page, method='have_text()', args={'get_all': get_all})
|
|
||||||
|
|
||||||
def style(self, name, value, get_all=False):
|
|
||||||
"""返回拥有某个style值的元素,默认返回第一个
|
|
||||||
:param name: 属性名称
|
|
||||||
:param value: 属性值
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:return: 筛选结果
|
|
||||||
"""
|
|
||||||
return self._get_attr(name, value, 'style', get_all)
|
|
||||||
|
|
||||||
def property(self, name, value, get_all=False):
|
|
||||||
"""返回拥有某个property值的元素,默认返回第一个
|
|
||||||
:param name: 属性名称
|
|
||||||
:param value: 属性值
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:return: 筛选结果
|
|
||||||
"""
|
|
||||||
return self._get_attr(name, value, 'property', get_all)
|
|
||||||
|
|
||||||
def attr(self, name, value, get_all=False):
|
|
||||||
"""返回拥有某个attribute值的元素,默认返回第一个
|
|
||||||
:param name: 属性名称
|
|
||||||
:param value: 属性值
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:return: 筛选结果
|
|
||||||
"""
|
|
||||||
return self._get_attr(name, value, 'attr', get_all)
|
|
||||||
|
|
||||||
def filter(self, get_all=False, displayed=None, checked=None, selected=None, enabled=None, clickable=None,
|
|
||||||
have_rect=None, have_text=None):
|
|
||||||
"""或关系筛选元素
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:param displayed: 是否显示,bool,None为忽略该项
|
|
||||||
:param checked: 是否被选中,bool,None为忽略该项
|
|
||||||
:param selected: 是否被选择,bool,None为忽略该项
|
|
||||||
:param enabled: 是否可用,bool,None为忽略该项
|
|
||||||
:param clickable: 是否可点击,bool,None为忽略该项
|
|
||||||
:param have_rect: 是否拥有大小和位置,bool,None为忽略该项
|
|
||||||
:param have_text: 是否含有文本,bool,None为忽略该项
|
|
||||||
:return: 筛选结果
|
|
||||||
"""
|
|
||||||
if get_all:
|
|
||||||
r = ElementsList()
|
|
||||||
for i in self:
|
|
||||||
if ((displayed is not None and (displayed is True and i.states.is_displayed) or (
|
|
||||||
displayed is False and not i.states.is_displayed))
|
|
||||||
or (checked is not None and (checked is True and i.states.is_checked) or (
|
|
||||||
checked is False and not i.states.is_checked))
|
|
||||||
or (selected is not None and (selected is True and i.states.is_selected) or (
|
|
||||||
selected is False and not i.states.is_selected))
|
|
||||||
or (enabled is not None and (enabled is True and i.states.is_enabled) or (
|
|
||||||
enabled is False and not i.states.is_enabled))
|
|
||||||
or (clickable is not None and (clickable is True and i.states.is_clickable) or (
|
|
||||||
clickable is False and not i.states.is_clickable))
|
|
||||||
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))):
|
|
||||||
r.append(i)
|
|
||||||
return r
|
|
||||||
|
|
||||||
for i in self:
|
|
||||||
if ((displayed is not None and (displayed is True and i.states.is_displayed) or (
|
|
||||||
displayed is False and not i.states.is_displayed))
|
|
||||||
or (checked is not None and (checked is True and i.states.is_checked) or (
|
|
||||||
checked is False and not i.states.is_checked))
|
|
||||||
or (selected is not None and (selected is True and i.states.is_selected) or (
|
|
||||||
selected is False and not i.states.is_selected))
|
|
||||||
or (enabled is not None and (enabled is True and i.states.is_enabled) or (
|
|
||||||
enabled is False and not i.states.is_enabled))
|
|
||||||
or (clickable is not None and (clickable is True and i.states.is_clickable) or (
|
|
||||||
clickable is False and not i.states.is_clickable))
|
|
||||||
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))):
|
|
||||||
return i
|
|
||||||
|
|
||||||
return NoneElement(self.page, method='filter()', args={'get_all': get_all, 'displayed': displayed,
|
|
||||||
'checked': checked, 'selected': selected,
|
|
||||||
'enabled': enabled, 'clickable': clickable,
|
|
||||||
'have_rect': have_rect, 'have_text': have_text})
|
|
||||||
|
|
||||||
def _get_attr(self, name, value, method, get_all=False):
|
|
||||||
"""返回通过某个方法可获得某个值的元素,默认返回第一个
|
|
||||||
:param name: 属性名称
|
|
||||||
:param value: 属性值
|
|
||||||
:param method: 方法名称
|
|
||||||
:param get_all: 是否返回所有筛选到的元素
|
|
||||||
:return: 筛选结果
|
|
||||||
"""
|
|
||||||
if get_all:
|
|
||||||
r = ElementsList()
|
|
||||||
for i in self:
|
|
||||||
if getattr(i, method)(name) == value:
|
|
||||||
r.append(i)
|
|
||||||
return r
|
|
||||||
|
|
||||||
for i in self:
|
|
||||||
if getattr(i, method)(name) == value:
|
|
||||||
return i
|
|
||||||
|
|
||||||
return NoneElement(self.page, f'{method}()', args={'name': name, 'value': value, 'get_all': get_all})
|
|
||||||
|
|
||||||
def _any_state(self, name, is_not=False, get_all=False):
|
|
||||||
"""
|
|
||||||
:param name: 状态名称
|
|
||||||
:param is_not: 是否选择否定的
|
|
||||||
:return: 选中的列表
|
|
||||||
"""
|
|
||||||
if get_all:
|
|
||||||
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
|
|
||||||
|
|
||||||
if is_not:
|
|
||||||
for i in self:
|
|
||||||
if not getattr(i.states, name):
|
|
||||||
return i
|
|
||||||
else:
|
|
||||||
for i in self:
|
|
||||||
if getattr(i.states, name):
|
|
||||||
return i
|
|
||||||
|
|
||||||
return NoneElement(self.page, f'is_{name}()', args={'is_not': is_not, 'get_all': get_all})
|
|
||||||
|
|
||||||
|
|
||||||
def get_eles(locators, owner, any_one=False, first_ele=True, timeout=10):
|
|
||||||
"""传入多个定位符,获取多个ele
|
|
||||||
:param locators: 定位符组成的列表
|
|
||||||
:param owner: 页面或元素对象
|
|
||||||
:param any_one: 是否找到任何一个即返回
|
|
||||||
:param first_ele: 每个定位符是否只获取第一个元素
|
|
||||||
:param timeout: 超时时间(秒)
|
|
||||||
:return: 多个定位符组成的dict
|
|
||||||
"""
|
|
||||||
res = {loc: False for loc in locators}
|
|
||||||
end_time = perf_counter() + timeout
|
|
||||||
while perf_counter() <= end_time:
|
|
||||||
for loc in locators:
|
|
||||||
if res[loc] is not False:
|
|
||||||
continue
|
|
||||||
ele = owner.ele(loc, timeout=0) if first_ele else owner.eles(loc, timeout=0)
|
|
||||||
if ele:
|
|
||||||
res[loc] = ele
|
|
||||||
if any_one:
|
|
||||||
return res
|
|
||||||
if False not in res.values():
|
|
||||||
break
|
|
||||||
|
|
||||||
return res
|
|
||||||
|
@ -8,10 +8,8 @@
|
|||||||
from os import popen
|
from os import popen
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
from typing import Union, Tuple, List, Optional
|
from typing import Union, Tuple
|
||||||
|
|
||||||
from .._base.base import BaseParser
|
|
||||||
from .._elements.chromium_element import ChromiumElement
|
|
||||||
from .._pages.chromium_base import ChromiumBase
|
from .._pages.chromium_base import ChromiumBase
|
||||||
|
|
||||||
|
|
||||||
@ -48,69 +46,3 @@ def configs_to_here(file_name: Union[Path, str] = None) -> None: ...
|
|||||||
|
|
||||||
|
|
||||||
def raise_error(result: dict, ignore=None) -> None: ...
|
def raise_error(result: dict, ignore=None) -> None: ...
|
||||||
|
|
||||||
|
|
||||||
def get_eles(locators: Union[List[str], tuple],
|
|
||||||
owner: BaseParser,
|
|
||||||
any_one: bool = False,
|
|
||||||
first_ele: bool = True,
|
|
||||||
timeout: float = 10) -> dict: ...
|
|
||||||
|
|
||||||
|
|
||||||
class ElementsList(list):
|
|
||||||
page = ...
|
|
||||||
|
|
||||||
def displayed(self, get_all: bool = False) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def hidden(self, get_all: bool = False) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def checked(self, get_all: bool = False) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def not_checked(self, get_all: bool = False) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def selected(self, get_all: bool = False) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def not_selected(self, get_all: bool = False) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def enabled(self, get_all: bool = False) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def disabled(self, get_all: bool = False) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def clickable(self, get_all: bool = False) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def not_clickable(self, get_all: bool = False) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def have_rect(self, get_all: bool = False) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def no_rect(self, get_all: bool = False) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def have_text(self, get_all: bool = False) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def style(self, name: str, value: str, get_all: bool = False) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def property(self,
|
|
||||||
name: str,
|
|
||||||
value: str,
|
|
||||||
get_all: bool = False) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def attr(self, name: str, value: str, get_all: bool = False) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def filter(self,
|
|
||||||
get_all: bool = False,
|
|
||||||
displayed: Optional[bool] = None,
|
|
||||||
checked: Optional[bool] = None,
|
|
||||||
selected: Optional[bool] = None,
|
|
||||||
enabled: Optional[bool] = None,
|
|
||||||
clickable: Optional[bool] = None,
|
|
||||||
have_rect: Optional[bool] = None,
|
|
||||||
have_text: Optional[bool] = None) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def _get_attr(self,
|
|
||||||
name: str,
|
|
||||||
value: str,
|
|
||||||
method: str,
|
|
||||||
get_all: bool = False) -> Union[List[ChromiumElement], ChromiumElement]: ...
|
|
||||||
|
|
||||||
def _any_state(self, name: str, is_not: bool = False, get_all: bool = False) -> List[ChromiumElement]: ...
|
|
||||||
|
|
||||||
def __next__(self) -> ChromiumElement: ...
|
|
||||||
|
@ -14,7 +14,7 @@ from .._base.browser import Browser
|
|||||||
from .._base.driver import Driver
|
from .._base.driver import Driver
|
||||||
from .._elements.chromium_element import ChromiumElement
|
from .._elements.chromium_element import ChromiumElement
|
||||||
from .._elements.session_element import SessionElement
|
from .._elements.session_element import SessionElement
|
||||||
from .._functions.tools import ElementsList
|
from .._functions.elements import ElementsList
|
||||||
from .._pages.chromium_frame import ChromiumFrame
|
from .._pages.chromium_frame import ChromiumFrame
|
||||||
from .._pages.chromium_page import ChromiumPage
|
from .._pages.chromium_page import ChromiumPage
|
||||||
from .._units.actions import Actions
|
from .._units.actions import Actions
|
||||||
|
@ -19,7 +19,7 @@ from .._configs.chromium_options import ChromiumOptions
|
|||||||
from .._configs.session_options import SessionOptions
|
from .._configs.session_options import SessionOptions
|
||||||
from .._elements.chromium_element import ChromiumElement
|
from .._elements.chromium_element import ChromiumElement
|
||||||
from .._elements.session_element import SessionElement
|
from .._elements.session_element import SessionElement
|
||||||
from .._functions.tools import ElementsList
|
from .._functions.elements import ElementsList
|
||||||
from .._units.setter import WebPageSetter
|
from .._units.setter import WebPageSetter
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user