prop()改成property(),参数改为name;
get_src()改为src();
get_cookies()方法改成cookies();
删除cookies属性;
get_session_storage()、get_local_storage()改成session_storage()、local_storage();
pageLoad改成page_load;
set_a_header()、remove_a_header()、set.header()、set.attr()的参数改为name;
元素增加value属性和set.value()方法;
loc_or_ele、loc_or_str等改为locator;
提高截图jpg格式画质;
修复s模式timeout参数失效问题;
修复wait.has_rect()等出现的问题;
修复找不到浏览器路径时报ini错误问题
增加一些提示
This commit is contained in:
g1879 2024-01-27 14:40:11 +08:00
parent 9e4b39be55
commit c07d90195d
39 changed files with 399 additions and 398 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.3.5'
__version__ = '4.0.4'

View File

@ -43,8 +43,7 @@ class BaseParser(object):
def _ele(self, locator, timeout=None, index=1, raise_err=None, method=None):
pass
@abstractmethod
def _find_elements(self, locator, timeout=None, index=1, raise_err=None):
def _find_elements(self, locator, timeout=None, index=1, relative=False, raise_err=None):
pass
@ -89,10 +88,6 @@ class BaseElement(BaseParser):
r.args = {'locator': locator, 'index': index}
return r
@abstractmethod
def _find_elements(self, locator, timeout=None, index=1, relative=False, raise_err=None):
pass
class DrissionElement(BaseElement):
"""ChromiumElement 和 SessionElement的基类但不是ShadowRoot的基类"""
@ -341,12 +336,15 @@ class DrissionElement(BaseElement):
return
@abstractmethod
def attr(self, attr: str):
def attr(self, name: str):
return ''
def _get_ele_path(self, mode):
return ''
def _find_elements(self, locator, timeout=None, index=1, relative=False, raise_err=None):
pass
class BasePage(BaseParser):
"""页面类的基类"""
@ -380,11 +378,6 @@ class BasePage(BaseParser):
"""设置查找元素时等待的秒数"""
self._timeout = second
@property
def cookies(self):
"""返回cookies"""
return self.get_cookies(True)
@property
def url_available(self):
"""返回当前访问的url有效性"""
@ -416,7 +409,7 @@ class BasePage(BaseParser):
return
@abstractmethod
def get_cookies(self, as_dict=False, all_info=False):
def cookies(self, as_dict=False, all_info=False):
return {}
@abstractmethod
@ -445,7 +438,3 @@ class BasePage(BaseParser):
r.method = method
r.args = {'locator': locator, 'index': index}
return r
@abstractmethod
def _find_elements(self, locator, timeout=None, index=1, raise_err=None):
pass

View File

@ -34,17 +34,17 @@ class BaseParser(object):
def s_eles(self, locator: Union[Tuple[str, str], str]): ...
def _ele(self,
locator,
locator: Union[Tuple[str, str], str],
timeout: float = None,
index: Optional[int] = 1,
raise_err: bool = None,
method: str = None): ...
@abstractmethod
def _find_elements(self,
locator,
locator: Union[Tuple[str, str], str],
timeout: float = None,
index: Optional[int] = 1,
relative: bool = False,
raise_err: bool = None): ...
@ -65,14 +65,6 @@ class BaseElement(BaseParser):
raise_err: bool = None,
method: str = None): ...
@abstractmethod
def _find_elements(self,
locator,
timeout: float = None,
index: Optional[int] = 1,
relative: bool = False,
raise_err: bool = None): ...
def parent(self, level_or_loc: Union[tuple, str, int] = 1): ...
def prev(self, index: int = 1) -> None: ...
@ -109,57 +101,57 @@ class DrissionElement(BaseElement):
index: int = 1) -> Union[DrissionElement, None]: ...
def child(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ...
def prev(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ...
def next(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ...
def before(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ...
def after(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ...
def children(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = None,
ele_only: bool = True) -> List[Union[DrissionElement, str]]: ...
def prevs(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = None,
ele_only: bool = True) -> List[Union[DrissionElement, str]]: ...
def nexts(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = None,
ele_only: bool = True) -> List[Union[DrissionElement, str]]: ...
def befores(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = None,
ele_only: bool = True) -> List[Union[DrissionElement, str]]: ...
def afters(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = None,
ele_only: bool = True) -> List[Union[DrissionElement, str]]: ...
@ -167,14 +159,14 @@ class DrissionElement(BaseElement):
func: str,
direction: str,
brother: bool,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> DrissionElement: ...
def _get_relatives(self,
index: int = None,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
direction: str = 'following',
brother: bool = True,
timeout: float = 0.5,
@ -191,7 +183,7 @@ class DrissionElement(BaseElement):
def raw_text(self) -> str: ...
@abstractmethod
def attr(self, attr: str) -> str: ...
def attr(self, name: str) -> str: ...
def _get_ele_path(self, mode) -> str: ...
@ -217,9 +209,6 @@ class BasePage(BaseParser):
@timeout.setter
def timeout(self, second: float) -> None: ...
@property
def cookies(self) -> dict: ...
@property
def url_available(self) -> bool: ...
@ -240,7 +229,7 @@ class BasePage(BaseParser):
def user_agent(self) -> str: ...
@abstractmethod
def get_cookies(self, as_dict: bool = False, all_info: bool = False) -> Union[list, dict]: ...
def cookies(self, as_dict: bool = False, all_info: bool = False) -> Union[list, dict]: ...
@abstractmethod
def get(self, url: str, show_errmsg: bool = False, retry: int = None, interval: float = None): ...
@ -251,10 +240,3 @@ class BasePage(BaseParser):
index: Optional[int] = 1,
raise_err: bool = None,
method: str = None): ...
@abstractmethod
def _find_elements(self,
locator,
timeout: float = None,
index: Optional[int] = 1,
raise_err: bool = None): ...

View File

@ -189,8 +189,9 @@ class Driver(object):
timeout = kwargs.pop('_timeout', 30)
result = self._send({'method': _method, 'params': kwargs}, timeout=timeout)
if 'result' not in result and 'error' in result:
kwargs['_timeout'] = timeout
return {'error': result['error']['message'], 'type': result.get('type', 'call_method_error'),
'method': _method, 'args': kwargs, 'timeout': timeout}
'method': _method, 'args': kwargs}
else:
return result['result']

View File

@ -26,7 +26,7 @@ class ChromiumOptions(object):
if read_file is not False:
ini_path = str(ini_path) if ini_path else None
om = OptionsManager(ini_path)
self.ini_path = om.ini_path
self.ini_path = str(Path(om.ini_path).absolute())
options = om.chromium_options
self._download_path = om.paths.get('download_path', None) or None
@ -56,7 +56,7 @@ class ChromiumOptions(object):
timeouts = om.timeouts
self._timeouts = {'base': timeouts['base'],
'pageLoad': timeouts['page_load'],
'page_load': timeouts['page_load'],
'script': timeouts['script']}
self._auto_port = options.get('auto_port', False)
@ -75,7 +75,7 @@ class ChromiumOptions(object):
self._extensions = []
self._prefs = {}
self._flags = {}
self._timeouts = {'base': 10, 'pageLoad': 30, 'script': 30}
self._timeouts = {'base': 10, 'page_load': 30, 'script': 30}
self._address = '127.0.0.1:9222'
self._load_mode = 'normal'
self._proxy = None
@ -278,18 +278,18 @@ class ChromiumOptions(object):
self.clear_file_flags = True
return self
def set_timeouts(self, base=None, pageLoad=None, script=None, implicit=None):
def set_timeouts(self, base=None, page_load=None, script=None, implicit=None):
"""设置超时时间,单位为秒
:param base: 默认超时时间
:param pageLoad: 页面加载超时时间
:param page_load: 页面加载超时时间
:param script: 脚本运行超时时间
:return: 当前对象
"""
base = base if base is not None else implicit
if base is not None:
self._timeouts['base'] = base
if pageLoad is not None:
self._timeouts['pageLoad'] = pageLoad
if page_load is not None:
self._timeouts['page_load'] = page_load
if script is not None:
self._timeouts['script'] = script
@ -545,7 +545,7 @@ class ChromiumOptions(object):
om.set_item('paths', 'tmp_path', self._tmp_path or '')
# 设置timeout
om.set_item('timeouts', 'base', self._timeouts['base'])
om.set_item('timeouts', 'page_load', self._timeouts['pageLoad'])
om.set_item('timeouts', 'page_load', self._timeouts['page_load'])
om.set_item('timeouts', 'script', self._timeouts['script'])
# 设置重试
om.set_item('others', 'retry_times', self.retry_times)

View File

@ -109,7 +109,9 @@ class ChromiumOptions(object):
def clear_flags_in_file(self) -> ChromiumOptions: ...
def set_timeouts(self, base: float = None, pageLoad: float = None,
def set_timeouts(self,
base: float = None,
page_load: float = None,
script: float = None) -> ChromiumOptions: ...
def set_user(self, user: str = 'Default') -> ChromiumOptions: ...

View File

@ -171,28 +171,27 @@ class SessionOptions(object):
self._headers = {key.lower(): headers[key] for key in headers}
return self
def set_a_header(self, attr, value):
def set_a_header(self, name, value):
"""设置headers中一个项
:param attr: 设置名称
:param name: 设置名称
:param value: 设置值
:return: 返回当前对象
"""
if self._headers is None:
self._headers = {}
self._headers[attr.lower()] = value
self._headers[name.lower()] = value
return self
def remove_a_header(self, attr):
def remove_a_header(self, name):
"""从headers中删除一个设置
:param attr: 要删除的设置
:param name: 要删除的设置
:return: 返回当前对象
"""
if self._headers is None:
return self
attr = attr.lower()
self._headers.pop(attr, None)
self._headers.pop(name.lower(), None)
return self

View File

@ -51,9 +51,9 @@ class SessionOptions(object):
def set_headers(self, headers: Union[dict, None]) -> SessionOptions: ...
def set_a_header(self, attr: str, value: str) -> SessionOptions: ...
def set_a_header(self, name: str, value: str) -> SessionOptions: ...
def remove_a_header(self, attr: str) -> SessionOptions: ...
def remove_a_header(self, name: str) -> SessionOptions: ...
@property
def cookies(self) -> list: ...

View File

@ -78,8 +78,7 @@ class ChromiumElement(DrissionElement):
self._doc_id = doc['objectId'] if doc else None
def __repr__(self):
attrs = self.attrs
attrs = [f"{attr}='{attrs[attr]}'" for attr in attrs]
attrs = [f"{k}='{v}'" for k, v in self.attrs.items()]
return f'<ChromiumElement {self.tag} {" ".join(attrs)}>'
def __call__(self, locator, index=1, timeout=None):
@ -128,10 +127,9 @@ class ChromiumElement(DrissionElement):
@property
def raw_text(self):
"""返回未格式化处理的元素内文本"""
return self.prop('innerText')
return self.property('innerText')
# -----------------d模式独有属性-------------------
@property
def set(self):
"""返回用于设置元素属性的对象"""
@ -206,6 +204,29 @@ class ChromiumElement(DrissionElement):
return self._select
@property
def value(self):
return self.property('value')
# -----即将废弃开始--------
@property
def location(self):
"""返回元素左上角的绝对坐标"""
return self.rect.location
@property
def size(self):
"""返回元素宽和高组成的元组"""
return self.rect.size
def prop(self, prop):
return self.property(prop)
def get_src(self, timeout=None, base64_to_bytes=True):
return self.src(timeout=timeout, base64_to_bytes=base64_to_bytes)
# -----即将废弃结束--------
def check(self, uncheck=False, by_js=False):
"""选中或取消选中当前元素
:param uncheck: 是否取消选中
@ -345,10 +366,10 @@ class ChromiumElement(DrissionElement):
if not link or link.lower().startswith(('javascript:', 'mailto:')):
return link
else:
return make_absolute_link(link, self.prop('baseURI'))
return make_absolute_link(link, self.property('baseURI'))
elif attr == 'src':
return make_absolute_link(attrs.get('src', None), self.prop('baseURI'))
return make_absolute_link(attrs.get('src', None), self.property('baseURI'))
elif attr == 'text':
return self.text
@ -365,20 +386,20 @@ class ChromiumElement(DrissionElement):
else:
return attrs.get(attr, None)
def remove_attr(self, attr):
def remove_attr(self, name):
"""删除元素一个attribute属性
:param attr: 属性名
:param name: 属性名
:return: None
"""
self.run_js(f'this.removeAttribute("{attr}");')
self.run_js(f'this.removeAttribute("{name}");')
def prop(self, prop):
def property(self, name):
"""获取一个property属性值
:param prop: 属性名
:param name: 属性名
:return: 属性值文本
"""
try:
value = self.run_js(f'return this.{prop};')
value = self.run_js(f'return this.{name};')
return format_html(value) if isinstance(value, str) else value
except:
return None
@ -467,7 +488,7 @@ class ChromiumElement(DrissionElement):
pseudo_ele = f', "{pseudo_ele}"' if pseudo_ele.startswith(':') else f', "::{pseudo_ele}"'
return self.run_js(f'return window.getComputedStyle(this{pseudo_ele}).getPropertyValue("{style}");')
def get_src(self, timeout=None, base64_to_bytes=True):
def src(self, timeout=None, base64_to_bytes=True):
"""返回元素src资源base64的可转为bytes返回其它返回str
:param timeout: 等待资源加载的超时时间
:param base64_to_bytes: 为True时如果是base64数据转换为bytes格式
@ -501,7 +522,7 @@ class ChromiumElement(DrissionElement):
break
else:
src = self.prop('currentSrc')
src = self.property('currentSrc')
if not src:
continue
@ -533,7 +554,7 @@ class ChromiumElement(DrissionElement):
:param timeout: 等待资源加载的超时时间
:return: 返回保存路径
"""
data = self.get_src(timeout=timeout)
data = self.src(timeout=timeout)
if not data:
raise NoResourceError
@ -543,7 +564,7 @@ class ChromiumElement(DrissionElement):
if src.lower().startswith('data:image'):
r = search(r'data:image/(.*?);base64,', src)
name = f'img.{r.group(1)}' if r else None
name = name or basename(self.prop('currentSrc'))
name = name or basename(self.property('currentSrc'))
path = get_usable_path(f'{path}{sep}{name}').absolute()
write_type = 'wb' if isinstance(data, bytes) else 'w'
@ -595,7 +616,7 @@ class ChromiumElement(DrissionElement):
self.clear(True)
if isinstance(vals, (list, tuple)):
vals = ''.join([str(i) for i in vals])
self.set.prop('value', str(vals))
self.set.property('value', str(vals))
self.run_js('this.dispatchEvent(new Event("change", {bubbles: true}));')
return
@ -751,18 +772,6 @@ class ChromiumElement(DrissionElement):
files = [str(Path(i).absolute()) for i in files]
self.page.run_cdp('DOM.setFileInputFiles', files=files, backendNodeId=self._backend_id)
# -------------即将废弃-------------
@property
def location(self):
"""返回元素左上角的绝对坐标"""
return self.rect.location
@property
def size(self):
"""返回元素宽和高组成的元组"""
return self.rect.size
class ShadowRoot(BaseElement):
"""ShadowRoot是用于处理ShadowRoot的类使用方法和ChromiumElement基本一致"""
@ -1421,7 +1430,7 @@ def run_js(page_or_ele, script, as_expr, timeout, args=None):
else:
raise ElementLostError('原来获取到的元素对象已不在页面内。')
if res is None and page.states.has_alert: # 存在alert的情况
if res is None and page.states.has_alert:
return None
exceptionDetails = res.get('exceptionDetails')

View File

@ -8,7 +8,6 @@
from pathlib import Path
from typing import Union, Tuple, List, Any, Literal, Optional
from .none_element import NoneElement
from .._base.base import DrissionElement, BaseElement
from .._elements.session_element import SessionElement
from .._pages.chromium_base import ChromiumBase
@ -50,7 +49,7 @@ class ChromiumElement(DrissionElement):
def __call__(self,
locator: Union[Tuple[str, str], str],
index: int = 1,
timeout: float = None) -> Union[ChromiumElement, NoneElement]: ...
timeout: float = None) -> ChromiumElement: ...
def __eq__(self, other: ChromiumElement) -> bool: ...
@ -73,7 +72,6 @@ class ChromiumElement(DrissionElement):
def raw_text(self) -> str: ...
# -----------------d模式独有属性-------------------
@property
def set(self) -> ChromiumElementSetter: ...
@ -100,60 +98,60 @@ class ChromiumElement(DrissionElement):
def parent(self,
level_or_loc: Union[tuple, str, int] = 1,
index: int = 1) -> Union[ChromiumElement, NoneElement]: ...
index: int = 1) -> ChromiumElement: ...
def child(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> Union[ChromiumElement, str, NoneElement]: ...
ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def prev(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> Union[ChromiumElement, str, NoneElement]: ...
ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def next(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> Union[ChromiumElement, str, NoneElement]: ...
ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def before(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> Union[ChromiumElement, str, NoneElement]: ...
ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def after(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> Union[ChromiumElement, str, NoneElement]: ...
ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def children(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = None,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...
def prevs(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = None,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...
def nexts(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = None,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...
def befores(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = None,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...
def afters(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = None,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...
@ -163,13 +161,16 @@ class ChromiumElement(DrissionElement):
@property
def select(self) -> SelectElement: ...
@property
def value(self) -> None: ...
def check(self, uncheck: bool = False, by_js: bool = False) -> None: ...
def attr(self, attr: str) -> Union[str, None]: ...
def attr(self, name: str) -> Union[str, None]: ...
def remove_attr(self, attr: str) -> None: ...
def remove_attr(self, name: str) -> None: ...
def prop(self, prop: str) -> Union[str, int, None]: ...
def property(self, name: str) -> Union[str, int, None]: ...
def run_js(self, script: str, *args, as_expr: bool = False, timeout: float = None) -> Any: ...
@ -178,7 +179,7 @@ class ChromiumElement(DrissionElement):
def ele(self,
locator: Union[Tuple[str, str], str],
index: int = 1,
timeout: float = None) -> Union[ChromiumElement, NoneElement]: ...
timeout: float = None) -> ChromiumElement: ...
def eles(self,
locator: Union[Tuple[str, str], str],
@ -186,7 +187,7 @@ class ChromiumElement(DrissionElement):
def s_ele(self,
locator: Union[Tuple[str, str], str] = None,
index: int = 1) -> Union[SessionElement, NoneElement]: ...
index: int = 1) -> SessionElement: ...
def s_eles(self, locator: Union[Tuple[str, str], str] = None) -> List[SessionElement]: ...
@ -195,12 +196,12 @@ class ChromiumElement(DrissionElement):
timeout: float = None,
index: Optional[int] = 1,
relative: bool = False,
raise_err: bool = False) -> Union[ChromiumElement, ChromiumFrame, NoneElement,
raise_err: bool = False) -> Union[ChromiumElement, ChromiumFrame,
List[Union[ChromiumElement, ChromiumFrame]]]: ...
def style(self, style: str, pseudo_ele: str = '') -> str: ...
def get_src(self, timeout: float = None, base64_to_bytes: bool = True) -> Union[bytes, str, None]: ...
def src(self, timeout: float = None, base64_to_bytes: bool = True) -> Union[bytes, str, None]: ...
def save(self, path: [str, bool] = None, name: str = None, timeout: float = None) -> str: ...
@ -273,33 +274,33 @@ class ShadowRoot(BaseElement):
def parent(self, level_or_loc: Union[str, int] = 1, index: int = 1) -> ChromiumElement: ...
def child(self,
locator: Union[tuple, str] = '',
index: int = 1) -> Union[ChromiumElement, NoneElement]: ...
locator: Union[Tuple[str, str], str] = '',
index: int = 1) -> ChromiumElement: ...
def next(self,
locator: Union[tuple, str] = '',
index: int = 1) -> Union[ChromiumElement, NoneElement]: ...
locator: Union[Tuple[str, str], str] = '',
index: int = 1) -> ChromiumElement: ...
def before(self,
locator: Union[tuple, str] = '',
index: int = 1) -> Union[ChromiumElement, NoneElement]: ...
locator: Union[Tuple[str, str], str] = '',
index: int = 1) -> ChromiumElement: ...
def after(self,
locator: Union[tuple, str] = '',
index: int = 1) -> Union[ChromiumElement, NoneElement]: ...
locator: Union[Tuple[str, str], str] = '',
index: int = 1) -> ChromiumElement: ...
def children(self, locator: Union[tuple, str] = '') -> List[ChromiumElement]: ...
def children(self, locator: Union[Tuple[str, str], str] = '') -> List[ChromiumElement]: ...
def nexts(self, locator: Union[tuple, str] = '') -> List[ChromiumElement]: ...
def nexts(self, locator: Union[Tuple[str, str], str] = '') -> List[ChromiumElement]: ...
def befores(self, locator: Union[tuple, str] = '') -> List[ChromiumElement]: ...
def befores(self, locator: Union[Tuple[str, str], str] = '') -> List[ChromiumElement]: ...
def afters(self, locator: Union[tuple, str] = '') -> List[ChromiumElement]: ...
def afters(self, locator: Union[Tuple[str, str], str] = '') -> List[ChromiumElement]: ...
def ele(self,
locator: Union[Tuple[str, str], str],
index: int = 1,
timeout: float = None) -> Union[ChromiumElement, NoneElement]: ...
timeout: float = None) -> ChromiumElement: ...
def eles(self,
locator: Union[Tuple[str, str], str],
@ -307,7 +308,7 @@ class ShadowRoot(BaseElement):
def s_ele(self,
locator: Union[Tuple[str, str], str] = None,
index: int = 1) -> Union[SessionElement, NoneElement]: ...
index: int = 1) -> SessionElement: ...
def s_eles(self, locator: Union[Tuple[str, str], str]) -> List[SessionElement]: ...
@ -316,7 +317,7 @@ class ShadowRoot(BaseElement):
timeout: float = None,
index: Optional[int] = 1,
relative: bool = False,
raise_err: bool = None) -> Union[ChromiumElement, ChromiumFrame, NoneElement, str,
raise_err: bool = None) -> Union[ChromiumElement, ChromiumFrame, str,
List[Union[ChromiumElement, ChromiumFrame, str]]]: ...
def _get_node_id(self, obj_id: str) -> int: ...
@ -330,28 +331,27 @@ def find_in_chromium_ele(ele: ChromiumElement,
loc: Union[str, Tuple[str, str]],
index: Optional[int] = 1,
timeout: float = None,
relative: bool = True) -> Union[ChromiumElement, NoneElement, List[ChromiumElement]]: ...
relative: bool = True) -> Union[ChromiumElement, List[ChromiumElement]]: ...
def find_by_xpath(ele: ChromiumElement,
xpath: str,
index: Optional[int],
timeout: float,
relative: bool = True) -> Union[ChromiumElement, List[ChromiumElement], NoneElement]: ...
relative: bool = True) -> Union[ChromiumElement, List[ChromiumElement]]: ...
def find_by_css(ele: ChromiumElement,
selector: str,
index: Optional[int],
timeout: float) -> Union[ChromiumElement, List[ChromiumElement], NoneElement]: ...
timeout: float) -> Union[ChromiumElement, List[ChromiumElement],]: ...
def make_chromium_eles(page: Union[ChromiumBase, ChromiumPage, WebPage, ChromiumTab, ChromiumFrame],
_ids: Union[tuple, list, str, int],
index: Optional[int] = 1,
is_obj_id: bool = True
) -> Union[ChromiumElement, ChromiumFrame, NoneElement,
List[Union[ChromiumElement, ChromiumFrame]]]: ...
) -> Union[ChromiumElement, ChromiumFrame, List[Union[ChromiumElement, ChromiumFrame]]]: ...
def make_js_for_find_ele_by_xpath(xpath: str, type_txt: str, node_txt: str) -> str: ...

View File

@ -18,6 +18,7 @@ class NoneElement(object):
self._none_ele_return_value = False
self.method = method
self.args = args
self._get = None
def __call__(self, *args, **kwargs):
if not self._none_ele_return_value:
@ -33,7 +34,7 @@ class NoneElement(object):
return self
else:
if item in ('size', 'link', 'css_path', 'xpath', 'comments', 'texts', 'tag', 'html', 'inner_html',
'attrs', 'text', 'raw_text'):
'attrs', 'text', 'raw_text', 'value', 'attr', 'style', 'src', 'property'):
return self._none_ele_value
else:
raise ElementNotFoundError(None, self.method, self.args)

View File

@ -34,7 +34,7 @@ class SessionElement(DrissionElement):
return self._inner_ele
def __repr__(self):
attrs = [f"{attr}='{self.attrs[attr]}'" for attr in self.attrs]
attrs = [f"{k}='{v}'" for k, v in self.attrs.items()]
return f'<SessionElement {self.tag} {" ".join(attrs)}>'
def __call__(self, locator, timeout=None):
@ -188,13 +188,13 @@ class SessionElement(DrissionElement):
"""
return super().afters(locator, timeout, ele_only=ele_only)
def attr(self, attr):
def attr(self, name):
"""返回attribute属性值
:param attr: 属性名
:param name: 属性名
:return: 属性值文本没有该属性返回None
"""
# 获取href属性时返回绝对url
if attr == 'href':
if name == 'href':
link = self.inner_ele.get('href')
# 若为链接为None、js或邮件直接返回
if not link or link.lower().startswith(('javascript:', 'mailto:')):
@ -203,23 +203,23 @@ class SessionElement(DrissionElement):
else: # 其它情况直接返回绝对url
return make_absolute_link(link, self.page.url)
elif attr == 'src':
elif name == 'src':
return make_absolute_link(self.inner_ele.get('src'), self.page.url)
elif attr == 'text':
elif name == 'text':
return self.text
elif attr == 'innerText':
elif name == 'innerText':
return self.raw_text
elif attr in ('html', 'outerHTML'):
elif name in ('html', 'outerHTML'):
return self.html
elif attr == 'innerHTML':
elif name == 'innerHTML':
return self.inner_html
else:
return self.inner_ele.get(attr)
return self.inner_ele.get(name)
def ele(self, locator, index=1, timeout=None):
"""返回当前元素下级符合条件的一个元素、属性或节点文本

View File

@ -9,7 +9,6 @@ from typing import Union, List, Tuple, Optional
from lxml.html import HtmlElement
from .none_element import NoneElement
from .._base.base import DrissionElement, BaseElement
from .._elements.chromium_element import ChromiumElement
from .._pages.chromium_base import ChromiumBase
@ -31,7 +30,7 @@ class SessionElement(DrissionElement):
def __call__(self,
locator: Union[Tuple[str, str], str],
index: int = 1,
timeout: float = None) -> Union[SessionElement, NoneElement]: ...
timeout: float = None) -> SessionElement: ...
def __eq__(self, other: SessionElement) -> bool: ...
@ -55,69 +54,69 @@ class SessionElement(DrissionElement):
def parent(self,
level_or_loc: Union[tuple, str, int] = 1,
index: int = 1) -> Union[SessionElement, NoneElement]: ...
index: int = 1) -> SessionElement: ...
def child(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> Union[SessionElement, str, NoneElement]: ...
ele_only: bool = True) -> Union[SessionElement, str]: ...
def prev(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> Union[SessionElement, str, NoneElement]: ...
ele_only: bool = True) -> Union[SessionElement, str]: ...
def next(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> Union[SessionElement, str, NoneElement]: ...
ele_only: bool = True) -> Union[SessionElement, str]: ...
def before(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> Union[SessionElement, str, NoneElement]: ...
ele_only: bool = True) -> Union[SessionElement, str]: ...
def after(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> Union[SessionElement, str, NoneElement]: ...
ele_only: bool = True) -> Union[SessionElement, str]: ...
def children(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = None,
ele_only: bool = True) -> List[Union[SessionElement, str]]: ...
def prevs(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = None,
ele_only: bool = True) -> List[Union[SessionElement, str]]: ...
def nexts(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = None,
ele_only: bool = True) -> List[Union[SessionElement, str]]: ...
def befores(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = None,
ele_only: bool = True) -> List[Union[SessionElement, str]]: ...
def afters(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = None,
ele_only: bool = True) -> List[Union[SessionElement, str]]: ...
def attr(self, attr: str) -> Optional[str]: ...
def attr(self, name: str) -> Optional[str]: ...
def ele(self,
locator: Union[Tuple[str, str], str],
index: int = 1,
timeout: float = None) -> Union[SessionElement, NoneElement]: ...
timeout: float = None) -> SessionElement: ...
def eles(self,
locator: Union[Tuple[str, str], str],
@ -125,7 +124,7 @@ class SessionElement(DrissionElement):
def s_ele(self,
locator: Union[Tuple[str, str], str] = None,
index: int = 1) -> Union[SessionElement, NoneElement]: ...
index: int = 1) -> SessionElement: ...
def s_eles(self, locator: Union[Tuple[str, str], str]) -> List[SessionElement]: ...
@ -134,7 +133,7 @@ class SessionElement(DrissionElement):
timeout: float = None,
index: Optional[int] = 1,
relative: bool = False,
raise_err: bool = None) -> Union[SessionElement, NoneElement, List[SessionElement]]: ...
raise_err: bool = None) -> Union[SessionElement, List[SessionElement]]: ...
def _get_ele_path(self, mode: str) -> str: ...
@ -142,4 +141,4 @@ 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, NoneElement, List[SessionElement]]: ...
index: Optional[int] = 1) -> Union[SessionElement, List[SessionElement]]: ...

View File

@ -26,7 +26,7 @@ def connect_browser(option):
:return: 返回是否接管的浏览器
"""
address = option.address.replace('localhost', '127.0.0.1').lstrip('http://').lstrip('https://')
chrome_path = option.browser_path
browser_path = option.browser_path
ip, port = address.split(':')
if ip != '127.0.0.1' or port_is_using(ip, port) or option.is_existing_only:
@ -43,16 +43,16 @@ def connect_browser(option):
set_prefs(option)
set_flags(option)
try:
_run_browser(port, chrome_path, args)
_run_browser(port, browser_path, args)
# 传入的路径找不到主动在ini文件、注册表、系统变量中找
except FileNotFoundError:
chrome_path = get_chrome_path()
browser_path = get_chrome_path(option.ini_path)
if not chrome_path:
if not browser_path:
raise FileNotFoundError('无法找到浏览器可执行文件路径,请手动配置。')
_run_browser(port, chrome_path, args)
_run_browser(port, browser_path, args)
test_connect(ip, port)
return False
@ -219,7 +219,7 @@ def test_connect(ip, port, timeout=30):
def _run_browser(port, path: str, args) -> Popen:
"""创建chrome进程
"""创建浏览器进程
:param port: 端口号
:param path: 浏览器路径
:param args: 启动参数
@ -282,12 +282,13 @@ def _remove_arg_from_dict(target_dict: dict, arg: str) -> None:
pass
def get_chrome_path():
def get_chrome_path(ini_path):
"""从ini文件或系统变量中获取chrome可执行文件的路径"""
# -----------从ini文件中获取--------------
path = OptionsManager().chromium_options.get('browser_path', None)
if path and Path(path).is_file():
return str(path)
if ini_path:
path = OptionsManager(ini_path).chromium_options.get('browser_path', None)
if path and Path(path).is_file():
return str(path)
# -----------使用which获取-----------
from shutil import which

View File

@ -25,4 +25,4 @@ def set_flags(opt: ChromiumOptions) -> None: ...
def test_connect(ip: str, port: Union[int, str], timeout: float = 30) -> None: ...
def get_chrome_path() -> Union[str, None]: ...
def get_chrome_path(ini_path: str) -> Union[str, None]: ...

View File

@ -112,7 +112,7 @@ def show_or_hide_browser(page, hide=True):
pid = page.process_id
if not pid:
return None
hds = get_chrome_hwnds_from_pid(pid, page.title)
hds = get_hwnds_from_pid(pid, page.title)
sw = SW_HIDE if hide else SW_SHOW
for hd in hds:
ShowWindow(hd, sw)
@ -141,7 +141,7 @@ def get_browser_progress_id(progress, address):
return txt.split(' ')[-1]
def get_chrome_hwnds_from_pid(pid, title):
def get_hwnds_from_pid(pid, title):
"""通过PID查询句柄ID
:param pid: 进程id
:param title: 窗口标题
@ -240,11 +240,11 @@ def raise_error(result, ignore=None):
elif error == 'Given expression does not evaluate to a function':
r = JavaScriptError(f'传入的js无法解析成函数\n{result["args"]["functionDeclaration"]}')
elif error.endswith("' wasn't found"):
r = RuntimeError(f'你的浏览器可能太旧。\nmethod{result["method"]}\nargs{result["args"]}')
r = RuntimeError(f'你的浏览器可能太旧。\n方法{result["method"]}\n参数{result["args"]}')
elif result['type'] in ('call_method_error', 'timeout'):
from DrissionPage import __version__
from time import process_time
txt = f'\n错误:{result["error"]}\nmethod{result["method"]}\nargs{result["args"]}\n' \
txt = f'\n错误:{result["error"]}\n方法{result["method"]}\n参数{result["args"]}\n' \
f'版本:{__version__}\n运行时间:{process_time()}\n出现这个错误可能意味着程序有bug请把错误信息和重现方法' \
'告知作者,谢谢。\n报告网站https://gitee.com/g1879/DrissionPage/issues'
r = TimeoutError(txt) if result['type'] == 'timeout' else CDPError(txt)

View File

@ -36,7 +36,7 @@ def show_or_hide_browser(page: ChromiumPage, hide: bool = True) -> None: ...
def get_browser_progress_id(progress: Union[popen, None], address: str) -> Union[str, None]: ...
def get_chrome_hwnds_from_pid(pid: Union[str, int], title: str) -> list: ...
def get_hwnds_from_pid(pid: Union[str, int], title: str) -> list: ...
def wait_until(function: callable, kwargs: dict = None, timeout: float = 10): ...

View File

@ -161,8 +161,8 @@ def is_js_func(func):
func = func.strip()
if (func.startswith('function') or func.startswith('async ')) and func.endswith('}'):
return True
elif '=>' in func:
return True
# elif '=>' in func:
# return True
return False
@ -361,3 +361,5 @@ def get_blob(page, url, as_bytes=True):
if as_bytes:
from base64 import b64decode
return b64decode(result.split(',', 1)[-1])
else:
return result

View File

@ -474,8 +474,8 @@ class ChromiumBase(BasePage):
show_errmsg=show_errmsg, timeout=timeout)
return self._url_available
def get_cookies(self, as_dict=False, all_domains=False, all_info=False):
"""获取cookies信息
def cookies(self, as_dict=False, all_domains=False, all_info=False):
"""返回cookies信息
:param as_dict: 为True时返回由{name: value}键值对组成的dict为True时返回list且all_info无效
:param all_domains: 是否返回所有域的cookies
:param all_info: 是否返回所有信息为False时只返回namevaluedomain
@ -722,8 +722,8 @@ class ChromiumBase(BasePage):
frames = self._ele(locator, timeout=timeout, index=None, raise_err=False)
return [i for i in frames if i._type == 'ChromiumFrame']
def get_session_storage(self, item=None):
"""获取sessionStorage信息不设置item则获取全部
def session_storage(self, item=None):
"""返回sessionStorage信息不设置item则获取全部
:param item: 要获取的项不设置则返回全部
:return: sessionStorage一个或所有项内容
"""
@ -743,8 +743,8 @@ class ChromiumBase(BasePage):
'''
return {i['key']: i['val'] for i in self.run_js_loaded(js)}
def get_local_storage(self, item=None):
"""获取localStorage信息不设置item则获取全部
def local_storage(self, item=None):
"""返回localStorage信息不设置item则获取全部
:param item: 要获取的项目不设置则返回全部
:return: localStorage一个或所有项内容
"""
@ -930,7 +930,11 @@ class ChromiumBase(BasePage):
:param interval: 重试间隔
:return: 重试次数和间隔组成的tuple
"""
self._url = quote(url, safe='-_.~!*\'"();:@&=+$,/\\?#[]%') or 'chrome://newtab/'
p = Path(url)
if p.exists():
self._url = str(p.absolute())
else:
self._url = quote(url, safe='-_.~!*\'"();:@&=+$,/\\?#[]%') or 'chrome://newtab/'
retry = retry if retry is not None else self.retry_times
interval = interval if interval is not None else self.retry_interval
return retry, interval
@ -1033,11 +1037,12 @@ class ChromiumBase(BasePage):
pic_type = path.suffix.lower()
pic_type = 'jpeg' if pic_type == '.jpg' else pic_type[1:]
width, height = self.rect.size
if full_page:
width, height = self.rect.size
if width == 0 or height == 0:
raise RuntimeError('页面大小为0请尝试等待页面加载完成。')
vp = {'x': 0, 'y': 0, 'width': width, 'height': height, 'scale': 1}
png = self.run_cdp_loaded('Page.captureScreenshot', format=pic_type,
captureBeyondViewport=True, clip=vp)['data']
args = {'format': pic_type, 'captureBeyondViewport': True, 'clip': vp}
else:
if left_top and right_bottom:
x, y = left_top
@ -1051,11 +1056,14 @@ class ChromiumBase(BasePage):
x += 10
vp = {'x': x, 'y': y, 'width': w, 'height': h, 'scale': 1}
png = self.run_cdp_loaded('Page.captureScreenshot', format=pic_type,
captureBeyondViewport=v, clip=vp)['data']
args = {'format': pic_type, 'captureBeyondViewport': v, 'clip': vp}
else:
png = self.run_cdp_loaded('Page.captureScreenshot', format=pic_type)['data']
args = {'format': pic_type}
if pic_type == 'jpeg':
args['quality'] = 100
png = self.run_cdp_loaded('Page.captureScreenshot', **args)['data']
if as_base64:
return png
@ -1095,6 +1103,15 @@ class ChromiumBase(BasePage):
"""返回页面总宽高,格式:(宽, 高)"""
return self.rect.size
def get_session_storage(self, item=None):
return self.session_storage(item)
def get_local_storage(self, item=None):
return self.local_storage(item)
def get_cookies(self, as_dict=False, all_domains=False, all_info=False):
return self.cookies(as_dict=as_dict, all_domains=all_domains, all_info=all_info)
class Timeout(object):
"""用于保存d模式timeout信息的类"""

View File

@ -13,7 +13,6 @@ from .._base.base import BasePage
from .._base.browser import Browser
from .._base.driver import Driver
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
@ -97,7 +96,7 @@ class ChromiumBase(BasePage):
def __call__(self,
locator: Union[Tuple[str, str], str, ChromiumElement],
index: int = 1,
timeout: float = None) -> Union[ChromiumElement, NoneElement]: ...
timeout: float = None) -> ChromiumElement: ...
@property
def _js_ready_state(self) -> str: ...
@ -177,13 +176,12 @@ class ChromiumBase(BasePage):
def get(self, url: str, show_errmsg: bool = False, retry: int = None,
interval: float = None, timeout: float = None) -> Union[None, bool]: ...
def get_cookies(self, as_dict: bool = False, all_domains: bool = False,
all_info: bool = False) -> Union[list, dict]: ...
def cookies(self, as_dict: bool = False, all_domains: bool = False, all_info: bool = False) -> Union[list, dict]: ...
def ele(self,
locator: Union[Tuple[str, str], str, ChromiumElement, ChromiumFrame],
index: int = 1,
timeout: float = None) -> Union[ChromiumElement, NoneElement]: ...
timeout: float = None) -> ChromiumElement: ...
def eles(self,
locator: Union[Tuple[str, str], str],
@ -191,7 +189,7 @@ class ChromiumBase(BasePage):
def s_ele(self,
locator: Union[Tuple[str, str], str] = None,
index: int = 1) -> Union[SessionElement, NoneElement]: ...
index: int = 1) -> SessionElement: ...
def s_eles(self, locator: Union[Tuple[str, str], str]) -> List[SessionElement]: ...
@ -201,7 +199,7 @@ class ChromiumBase(BasePage):
index: Optional[int] = 1,
relative: bool = False,
raise_err: bool = None) \
-> Union[ChromiumElement, ChromiumFrame, NoneElement, List[Union[ChromiumElement, ChromiumFrame]]]: ...
-> Union[ChromiumElement, ChromiumFrame, List[Union[ChromiumElement, ChromiumFrame]]]: ...
def refresh(self, ignore_cache: bool = False) -> None: ...
@ -223,9 +221,9 @@ class ChromiumBase(BasePage):
def run_cdp_loaded(self, cmd: str, **cmd_args) -> dict: ...
def get_session_storage(self, item: str = None) -> Union[str, dict, None]: ...
def session_storage(self, item: str = None) -> Union[str, dict, None]: ...
def get_local_storage(self, item: str = None) -> Union[str, dict, None]: ...
def local_storage(self, item: str = None) -> Union[str, dict, None]: ...
def add_init_js(self, script: str) -> str: ...

View File

@ -78,8 +78,7 @@ class ChromiumFrame(ChromiumBase):
return self._frame_id == getattr(other, '_frame_id', None)
def __repr__(self):
attrs = self._frame_ele.attrs
attrs = [f"{attr}='{attrs[attr]}'" for attr in attrs]
attrs = [f"{k}='{v}'" for k, v in self._frame_ele.attrs.items()]
return f'<ChromiumFrame {self.frame_ele.tag} {" ".join(attrs)}>'
def _d_set_runtime_settings(self):
@ -146,19 +145,6 @@ class ChromiumFrame(ChromiumBase):
if timeout <= 0:
timeout = .5
self._wait_loaded(timeout)
# while perf_counter() < end_time:
# try:
# obj_id = super().run_js('document;', as_expr=True)['objectId']
# self.doc_ele = ChromiumElement(self, obj_id=obj_id)
# break
# except Exception as e:
# sleep(.1)
# if self._debug:
# print(f'获取doc失败重试 {e}')
# else:
# raise GetDocumentError
# self.driver._debug = d_debug
self._is_loading = False
self._reloading = False
@ -208,7 +194,6 @@ class ChromiumFrame(ChromiumBase):
self._reload()
# ----------挂件----------
@property
def scroll(self):
"""返回用于滚动的对象"""
@ -252,7 +237,7 @@ class ChromiumFrame(ChromiumBase):
self._listener = FrameListener(self)
return self._listener
# ----------挂件----------
# ----------挂件结束----------
@property
def _obj_id(self):
@ -305,11 +290,6 @@ class ChromiumFrame(ChromiumBase):
r = self._ele('t:title', raise_err=False)
return r.text if r else None
@property
def cookies(self):
"""以dict格式返回cookies"""
return super().cookies if self._is_diff_domain else self.doc_ele.run_js('return this.cookie;')
@property
def attrs(self):
"""返回frame元素所有attribute属性"""
@ -356,23 +336,57 @@ class ChromiumFrame(ChromiumBase):
except:
return None
# ----------------即将废弃-----------------
@property
def is_alive(self):
"""返回是否仍可用"""
return self.states.is_alive
@property
def page_size(self):
"""返回frame内页面尺寸格式(宽,, 高)"""
return self.rect.size
@property
def size(self):
"""返回frame元素大小"""
return self.frame_ele.rect.size
@property
def location(self):
"""返回frame元素左上角的绝对坐标"""
return self.frame_ele.rect.location
@property
def locations(self):
"""返回用于获取元素位置的对象"""
return self.frame_ele.rect
# ----------------即将废弃结束-----------------
def refresh(self):
"""刷新frame页面"""
self.doc_ele.run_js('this.location.reload();')
def attr(self, attr):
"""返回frame元素attribute属性值
:param attr: 属性名
def property(self, name):
"""返回frame元素一个property属性值
:param name: 属性名
:return: 属性值文本没有该属性返回None
"""
return self.frame_ele.attr(attr)
return self.frame_ele.property(name)
def remove_attr(self, attr):
def attr(self, name):
"""返回frame元素一个attribute属性值
:param name: 属性名
:return: 属性值文本没有该属性返回None
"""
return self.frame_ele.attr(name)
def remove_attr(self, name):
"""删除frame元素attribute属性
:param attr: 属性名
:param name: 属性名
:return: None
"""
self.frame_ele.remove_attr(attr)
self.frame_ele.remove_attr(name)
def run_js(self, script, *args, as_expr=False, timeout=None):
"""运行javascript代码
@ -580,30 +594,3 @@ class ChromiumFrame(ChromiumBase):
def _is_inner_frame(self):
"""返回当前frame是否同域"""
return self._frame_id in str(self._target_page.run_cdp('Page.getFrameTree')['frameTree'])
# ----------------即将废弃-----------------
@property
def is_alive(self):
"""返回是否仍可用"""
return self.states.is_alive
@property
def page_size(self):
"""返回frame内页面尺寸格式(宽,, 高)"""
return self.rect.size
@property
def size(self):
"""返回frame元素大小"""
return self.frame_ele.rect.size
@property
def location(self):
"""返回frame元素左上角的绝对坐标"""
return self.frame_ele.rect.location
@property
def locations(self):
"""返回用于获取元素位置的对象"""
return self.frame_ele.rect

View File

@ -13,7 +13,6 @@ from .chromium_page import ChromiumPage
from .chromium_tab import ChromiumTab
from .web_page import WebPage
from .._elements.chromium_element import ChromiumElement
from .._elements.none_element import NoneElement
from .._units.listener import FrameListener
from .._units.rect import FrameRect
from .._units.scroller import FrameScroller
@ -32,6 +31,7 @@ class ChromiumFrame(ChromiumBase):
self._target_page: ChromiumBase = ...
self.tab: ChromiumTab = ...
self._tab_id: str = ...
self._set: ChromiumFrameSetter = ...
self._frame_ele: ChromiumElement = ...
self._backend_id: int = ...
self._doc_ele: ChromiumElement = ...
@ -45,7 +45,7 @@ class ChromiumFrame(ChromiumBase):
def __call__(self,
locator: Union[Tuple[str, str], str],
index: int = 1,
timeout: float = None) -> Union[ChromiumElement, NoneElement]: ...
timeout: float = None) -> ChromiumElement: ...
def __eq__(self, other: ChromiumFrame) -> bool: ...
@ -86,9 +86,6 @@ class ChromiumFrame(ChromiumBase):
@property
def title(self) -> str: ...
@property
def cookies(self) -> dict: ...
@property
def attrs(self) -> dict: ...
@ -133,9 +130,11 @@ class ChromiumFrame(ChromiumBase):
def refresh(self) -> None: ...
def attr(self, attr: str) -> Union[str, None]: ...
def property(self, name: str) -> Union[str, None]: ...
def remove_attr(self, attr: str) -> None: ...
def attr(self, name: str) -> Union[str, None]: ...
def remove_attr(self, name: str) -> None: ...
def run_js(self,
script: str,
@ -144,50 +143,50 @@ class ChromiumFrame(ChromiumBase):
timeout: float = None) -> Any: ...
def parent(self,
level_or_loc: Union[tuple, str, int] = 1,
index: int = 1) -> Union[ChromiumElement, NoneElement]: ...
level_or_loc: Union[Tuple[str, str], str, int] = 1,
index: int = 1) -> ChromiumElement: ...
def prev(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = 0,
ele_only: bool = True) -> Union[ChromiumElement, NoneElement, str]: ...
ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def next(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = 0,
ele_only: bool = True) -> Union[ChromiumElement, NoneElement, str]: ...
ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def before(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> Union[ChromiumElement, NoneElement, str]: ...
ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def after(self,
locator: Union[tuple, str, int] = '',
locator: Union[Tuple[str, str], str, int] = '',
index: int = 1,
timeout: float = None,
ele_only: bool = True) -> Union[ChromiumElement, NoneElement, str]: ...
ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def prevs(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = 0,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...
def nexts(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = 0,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...
def befores(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = None,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...
def afters(self,
locator: Union[tuple, str] = '',
locator: Union[Tuple[str, str], str] = '',
timeout: float = None,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...

View File

@ -24,7 +24,7 @@ from ..errors import BrowserConnectError
class ChromiumPage(ChromiumBase):
"""用于管理浏览器的类"""
PAGES = {}
_PAGES = {}
def __new__(cls, addr_or_opts=None, tab_id=None, timeout=None, addr_driver_opts=None):
"""
@ -35,8 +35,8 @@ class ChromiumPage(ChromiumBase):
addr_or_opts = addr_or_opts or addr_driver_opts
opt = handle_options(addr_or_opts)
is_exist, browser_id = run_browser(opt)
if browser_id in cls.PAGES:
r = cls.PAGES[browser_id]
if browser_id in cls._PAGES:
r = cls._PAGES[browser_id]
while not hasattr(r, '_frame_id'):
sleep(.1)
return r
@ -45,7 +45,7 @@ class ChromiumPage(ChromiumBase):
r._is_exist = is_exist
r._browser_id = browser_id
r.address = opt.address
cls.PAGES[browser_id] = r
cls._PAGES[browser_id] = r
return r
def __init__(self, addr_or_opts=None, tab_id=None, timeout=None, addr_driver_opts=None):
@ -79,7 +79,7 @@ class ChromiumPage(ChromiumBase):
def _d_set_runtime_settings(self):
"""设置运行时用到的属性"""
self._timeouts = Timeout(self, page_load=self._chromium_options.timeouts['pageLoad'],
self._timeouts = Timeout(self, page_load=self._chromium_options.timeouts['page_load'],
script=self._chromium_options.timeouts['script'],
base=self._chromium_options.timeouts['base'])
if self._chromium_options.timeouts['base'] is not None:
@ -255,7 +255,7 @@ class ChromiumPage(ChromiumBase):
def _on_disconnect(self):
"""浏览器退出时执行"""
ChromiumPage.PAGES.pop(self._browser_id, None)
ChromiumPage._PAGES.pop(self._browser_id, None)
def __repr__(self):
return f'<ChromiumPage browser_id={self.browser.id} tab_id={self.tab_id}>'

View File

@ -19,7 +19,7 @@ from .._units.waiter import PageWaiter
class ChromiumPage(ChromiumBase):
PAGES: dict = ...
_PAGES: dict = ...
def __new__(cls,
addr_or_opts: Union[str, int, ChromiumOptions] = None,
@ -55,9 +55,6 @@ class ChromiumPage(ChromiumBase):
@property
def wait(self) -> PageWaiter: ...
@property
def main_tab(self) -> str: ...
@property
def latest_tab(self) -> str: ...

View File

@ -20,20 +20,20 @@ from .._units.waiter import TabWaiter
class ChromiumTab(ChromiumBase):
"""实现浏览器标签页的类"""
TABS = {}
_TABS = {}
def __new__(cls, page, tab_id):
"""
:param page: ChromiumPage对象
:param tab_id: 要控制的标签页id
"""
if Settings.singleton_tab_obj and tab_id in cls.TABS:
r = cls.TABS[tab_id]
if Settings.singleton_tab_obj and tab_id in cls._TABS:
r = cls._TABS[tab_id]
while not hasattr(r, '_frame_id'):
sleep(.1)
return r
r = object.__new__(cls)
cls.TABS[tab_id] = r
cls._TABS[tab_id] = r
return r
def __init__(self, page, tab_id):
@ -96,7 +96,7 @@ class ChromiumTab(ChromiumBase):
return f'<ChromiumTab browser_id={self.browser.id} tab_id={self.tab_id}>'
def _on_disconnect(self):
ChromiumTab.TABS.pop(self.tab_id, None)
ChromiumTab._TABS.pop(self.tab_id, None)
class WebPageTab(SessionPage, ChromiumTab, BasePage):
@ -188,11 +188,6 @@ class WebPageTab(SessionPage, ChromiumTab, BasePage):
"""返回当前模式,'s''d' """
return self._mode
@property
def cookies(self):
"""以dict方式返回cookies"""
return super().cookies
@property
def user_agent(self):
"""返回user agent"""
@ -357,15 +352,15 @@ class WebPageTab(SessionPage, ChromiumTab, BasePage):
user_agent = self.run_cdp('Runtime.evaluate', expression='navigator.userAgent;')['result']['value']
self._headers.update({"User-Agent": user_agent})
set_session_cookies(self.session, super(SessionPage, self).get_cookies())
set_session_cookies(self.session, super(SessionPage, self).cookies())
def cookies_to_browser(self):
"""把session对象的cookies复制到浏览器"""
if not self._has_driver:
return
set_browser_cookies(self, super().get_cookies())
set_browser_cookies(self, super().cookies())
def get_cookies(self, as_dict=False, all_domains=False, all_info=False):
def cookies(self, as_dict=False, all_domains=False, all_info=False):
"""返回cookies
:param as_dict: 是否以字典方式返回
:param all_domains: 是否返回所有域的cookies
@ -373,9 +368,9 @@ class WebPageTab(SessionPage, ChromiumTab, BasePage):
:return: cookies信息
"""
if self._mode == 's':
return super().get_cookies(as_dict, all_domains, all_info)
return super().cookies(as_dict, all_domains, all_info)
elif self._mode == 'd':
return super(SessionPage, self).get_cookies(as_dict, all_domains, all_info)
return super(SessionPage, self).cookies(as_dict, all_domains, all_info)
def close(self):
"""关闭当前标签页"""
@ -400,3 +395,7 @@ class WebPageTab(SessionPage, ChromiumTab, BasePage):
def __repr__(self):
return f'<WebPageTab browser_id={self.browser.id} tab_id={self.tab_id}>'
# --------即将废弃-------
def get_cookies(self, as_dict=False, all_domains=False, all_info=False):
return self.cookies(as_dict=as_dict, all_domains=all_domains, all_info=all_info)

View File

@ -6,7 +6,6 @@
@License : BSD 3-Clause.
"""
from pathlib import Path
from threading import Lock
from typing import Union, Tuple, Any, List, Optional
from requests import Session, Response
@ -18,7 +17,6 @@ from .session_page import SessionPage
from .web_page import WebPage
from .._base.browser import Browser
from .._elements.chromium_element import ChromiumElement
from .._elements.none_element import NoneElement
from .._elements.session_element import SessionElement
from .._units.rect import TabRect
from .._units.setter import TabSetter, WebPageTabSetter
@ -26,8 +24,7 @@ from .._units.waiter import TabWaiter
class ChromiumTab(ChromiumBase):
TABS: dict = ...
LOCK: Lock = ...
_TABS: dict = ...
def __new__(cls, page: ChromiumPage, tab_id: str): ...
@ -82,7 +79,7 @@ class WebPageTab(SessionPage, ChromiumTab):
def __call__(self,
locator: Union[Tuple[str, str], str, ChromiumElement, SessionElement],
index: int = 1,
timeout: float = None) -> Union[ChromiumElement, SessionElement, NoneElement]: ...
timeout: float = None) -> Union[ChromiumElement, SessionElement]: ...
@property
def page(self) -> WebPage: ...
@ -111,9 +108,6 @@ class WebPageTab(SessionPage, ChromiumTab):
@property
def mode(self) -> str: ...
@property
def cookies(self) -> dict: ...
@property
def user_agent(self) -> str: ...
@ -152,7 +146,7 @@ class WebPageTab(SessionPage, ChromiumTab):
def ele(self,
locator: Union[Tuple[str, str], str, ChromiumElement, SessionElement],
index: int = 1,
timeout: float = None) -> Union[ChromiumElement, SessionElement, NoneElement]: ...
timeout: float = None) -> Union[ChromiumElement, SessionElement]: ...
def eles(self,
locator: Union[Tuple[str, str], str],
@ -160,7 +154,7 @@ class WebPageTab(SessionPage, ChromiumTab):
def s_ele(self,
locator: Union[Tuple[str, str], str] = None,
index: int = 1) -> Union[SessionElement, NoneElement]: ...
index: int = 1) -> SessionElement: ...
def s_eles(self, locator: Union[Tuple[str, str], str]) -> List[SessionElement]: ...
@ -170,8 +164,8 @@ class WebPageTab(SessionPage, ChromiumTab):
def cookies_to_browser(self) -> None: ...
def get_cookies(self, as_dict: bool = False, all_domains: bool = False,
all_info: bool = False) -> Union[dict, list]: ...
def cookies(self, as_dict: bool = False, all_domains: bool = False,
all_info: bool = False) -> Union[dict, list]: ...
def close(self) -> None: ...
@ -205,5 +199,5 @@ class WebPageTab(SessionPage, ChromiumTab):
index: Optional[int] = 1,
relative: bool = False,
raise_err: bool = None) \
-> Union[ChromiumElement, SessionElement, ChromiumFrame, NoneElement, List[SessionElement], List[
-> Union[ChromiumElement, SessionElement, ChromiumFrame, List[SessionElement], List[
Union[ChromiumElement, ChromiumFrame]]]: ...

View File

@ -47,8 +47,11 @@ class SessionPage(BasePage):
:param session_or_options: SessionSessionOptions对象
:return: None
"""
if not session_or_options or isinstance(session_or_options, SessionOptions):
self._session_options = session_or_options or SessionOptions(session_or_options)
if not session_or_options:
self._session_options = SessionOptions(session_or_options)
elif isinstance(session_or_options, SessionOptions):
self._session_options = session_or_options
elif isinstance(session_or_options, Session):
self._session_options = SessionOptions()
@ -208,7 +211,7 @@ class SessionPage(BasePage):
"""
return self._ele(locator, index=None)
def _find_elements(self, locator, timeout=None, index=1, raise_err=None):
def _find_elements(self, locator, timeout=None, index=1, relative=True, raise_err=None):
"""返回页面中符合条件的元素、属性或节点文本,默认返回第一个
:param locator: 元素的定位信息可以是元素对象loc元组或查询字符串
:param timeout: 不起实际作用用于和父类对应
@ -218,7 +221,7 @@ class SessionPage(BasePage):
"""
return locator if isinstance(locator, SessionElement) else make_session_ele(self, locator, index=index)
def get_cookies(self, as_dict=False, all_domains=False, all_info=False):
def cookies(self, as_dict=False, all_domains=False, all_info=False):
"""返回cookies
:param as_dict: 是否以字典方式返回False则以list返回
:param all_domains: 是否返回所有域的cookies
@ -310,7 +313,7 @@ class SessionPage(BasePage):
parsed_url = urlparse(url)
hostname = parsed_url.hostname
scheme = parsed_url.scheme
if not check_headers(kwargs, self._headers, 'Referer'):
if not check_headers(kwargs['headers'], self._headers, 'Referer'):
kwargs['headers']['Referer'] = self.url if self.url else f'{scheme}://{hostname}'
if 'Host' not in kwargs['headers']:
kwargs['headers']['Host'] = hostname
@ -364,10 +367,14 @@ class SessionPage(BasePage):
def __repr__(self):
return f'<SessionPage url={self.url}>'
# ---------即将废弃---------
def get_cookies(self, as_dict=False, all_domains=False, all_info=False):
return self.cookies(as_dict=as_dict, all_domains=all_domains, all_info=all_info)
def check_headers(kwargs, headers, arg):
"""检查kwargs或headers中是否有arg所示属性"""
return arg in kwargs['headers'] or arg in headers
return arg in kwargs or arg in headers
def set_charset(response):

View File

@ -13,7 +13,6 @@ from requests.structures import CaseInsensitiveDict
from .._base.base import BasePage
from .._configs.session_options import SessionOptions
from .._elements.none_element import NoneElement
from .._elements.session_element import SessionElement
from .._units.setter import SessionPageSetter
@ -43,7 +42,7 @@ class SessionPage(BasePage):
def __call__(self,
locator: Union[Tuple[str, str], str, SessionElement],
index: int = 1,
timeout: float = None) -> Union[SessionElement, NoneElement]: ...
timeout: float = None) -> SessionElement: ...
# -----------------共有属性和方法-------------------
@property
@ -93,7 +92,7 @@ class SessionPage(BasePage):
def ele(self,
locator: Union[Tuple[str, str], str, SessionElement],
index: int = 1,
timeout: float = None) -> Union[SessionElement, NoneElement]: ...
timeout: float = None) -> SessionElement: ...
def eles(self,
locator: Union[Tuple[str, str], str],
@ -101,7 +100,7 @@ class SessionPage(BasePage):
def s_ele(self,
locator: Union[Tuple[str, str], str, SessionElement] = None,
index: int = 1) -> Union[SessionElement, NoneElement]: ...
index: int = 1) -> SessionElement: ...
def s_eles(self, loc: Union[Tuple[str, str], str]) -> List[SessionElement]: ...
@ -109,10 +108,11 @@ class SessionPage(BasePage):
locator: Union[Tuple[str, str], str, SessionElement],
timeout: float = None,
index: Optional[int] = 1,
relative: bool = True,
raise_err: bool = None) \
-> Union[SessionElement, NoneElement, List[SessionElement]]: ...
-> Union[SessionElement, List[SessionElement]]: ...
def get_cookies(self,
def cookies(self,
as_dict: bool = False,
all_domains: bool = False,
all_info: bool = False) -> Union[dict, list]: ...

View File

@ -126,11 +126,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
"""返回当前模式,'s''d' """
return self._mode
@property
def cookies(self):
"""以dict方式返回cookies"""
return super().cookies
@property
def user_agent(self):
"""返回user agent"""
@ -281,7 +276,9 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
if go:
url = super(SessionPage, self).url
if url.startswith('http'):
self.get(url)
r = self.get(url)
if not r:
raise ConnectionError('s模式访问失败请设置go=False自行构造连接参数进行访问。')
def cookies_to_session(self, copy_user_agent=True):
"""把driver对象的cookies复制到session对象
@ -295,15 +292,15 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
user_agent = self.run_cdp('Runtime.evaluate', expression='navigator.userAgent;')['result']['value']
self._headers.update({"User-Agent": user_agent})
set_session_cookies(self.session, super(SessionPage, self).get_cookies())
set_session_cookies(self.session, super(SessionPage, self).cookies())
def cookies_to_browser(self):
"""把session对象的cookies复制到浏览器"""
if not self._has_driver:
return
set_browser_cookies(self, super().get_cookies())
set_browser_cookies(self, super().cookies())
def get_cookies(self, as_dict=False, all_domains=False, all_info=False):
def cookies(self, as_dict=False, all_domains=False, all_info=False):
"""返回cookies
:param as_dict: 是否以字典方式返回False以list形式返回
:param all_domains: 是否返回所有域的cookies
@ -311,9 +308,9 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
:return: cookies信息
"""
if self._mode == 's':
return super().get_cookies(as_dict, all_domains, all_info)
return super().cookies(as_dict, all_domains, all_info)
elif self._mode == 'd':
return super(SessionPage, self).get_cookies(as_dict, all_domains, all_info)
return super(SessionPage, self).cookies(as_dict, all_domains, all_info)
def get_tab(self, id_or_num=None):
"""获取一个标签页对象
@ -408,3 +405,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
def __repr__(self):
return f'<WebPage browser_id={self.browser.id} tab_id={self.tab_id}>'
# -------即将废弃--------
def get_cookies(self, as_dict=False, all_domains=False, all_info=False):
return self.cookies(as_dict=as_dict, all_domains=all_domains, all_info=all_info)

View File

@ -18,7 +18,6 @@ from .._base.driver import Driver
from .._configs.chromium_options import ChromiumOptions
from .._configs.session_options import SessionOptions
from .._elements.chromium_element import ChromiumElement
from .._elements.none_element import NoneElement
from .._elements.session_element import SessionElement
from .._units.setter import WebPageSetter
@ -31,6 +30,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
chromium_options: Union[ChromiumOptions, bool] = None,
session_or_options: Union[Session, SessionOptions, bool] = None) -> None:
self._mode: str = ...
self._set: WebPageSetter = ...
self._has_driver: bool = ...
self._has_session: bool = ...
self._session_options: Union[SessionOptions, None] = ...
@ -39,7 +39,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
def __call__(self,
locator: Union[Tuple[str, str], str, ChromiumElement, SessionElement],
index: int = 1,
timeout: float = None) -> Union[ChromiumElement, SessionElement, NoneElement]: ...
timeout: float = None) -> Union[ChromiumElement, SessionElement]: ...
# -----------------共有属性和方法-------------------
@property
@ -66,9 +66,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
@property
def mode(self) -> str: ...
@property
def cookies(self) -> dict: ...
@property
def user_agent(self) -> str: ...
@ -107,7 +104,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
def ele(self,
locator: Union[Tuple[str, str], str, ChromiumElement, SessionElement],
index: int = 1,
timeout: float = None) -> Union[ChromiumElement, SessionElement, NoneElement]: ...
timeout: float = None) -> Union[ChromiumElement, SessionElement]: ...
def eles(self,
locator: Union[Tuple[str, str], str],
@ -115,7 +112,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
def s_ele(self,
locator: Union[Tuple[str, str], str] = None,
index: int = 1) -> Union[SessionElement, NoneElement]: ...
index: int = 1) -> SessionElement: ...
def s_eles(self, locator: Union[Tuple[str, str], str]) -> List[SessionElement]: ...
@ -125,10 +122,10 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
def cookies_to_browser(self) -> None: ...
def get_cookies(self,
as_dict: bool = False,
all_domains: bool = False,
all_info: bool = False) -> Union[dict, list]: ...
def cookies(self,
as_dict: bool = False,
all_domains: bool = False,
all_info: bool = False) -> Union[dict, list]: ...
def get_tab(self, id_or_num: Union[str, WebPageTab, int] = None) -> WebPageTab: ...
@ -174,7 +171,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
index: Optional[int] = 1,
relative: bool = False,
raise_err: bool = None) \
-> Union[ChromiumElement, SessionElement, ChromiumFrame, NoneElement, List[SessionElement],
-> Union[ChromiumElement, SessionElement, ChromiumFrame, List[SessionElement],
List[Union[ChromiumElement, ChromiumFrame]]]: ...
def _set_start_options(self,

View File

@ -5,7 +5,7 @@
@Copyright: (c) 2024 by g1879, Inc. All Rights Reserved.
@License : BSD 3-Clause.
"""
from typing import Union, Optional
from typing import Optional
from .._elements.chromium_element import ChromiumElement

View File

@ -100,6 +100,9 @@ class Listener(object):
Manifest, SignedExchange, Ping, CSPViolationReport, Preflight, Other
:return: None
"""
if targets is not None:
if is_regex is None:
is_regex = False
if targets or is_regex is not None or method or res_type:
self.set_targets(targets, is_regex, method, res_type)
self.clear()

View File

@ -6,7 +6,7 @@
@License : BSD 3-Clause.
"""
from typing import Tuple, Union, List
from typing import Tuple, Union
from .._elements.chromium_element import ChromiumElement
from .._pages.chromium_base import ChromiumBase

View File

@ -38,7 +38,7 @@ class SelectElement(object):
def by_index(self, index: Union[int, list, tuple], timeout: float = None) -> bool: ...
def by_locator(self, locator: Union[str, Tuple[str, str]], timeout: float = None) -> bool: ...
def by_locator(self, locator: Union[Tuple[str, str], str], timeout: float = None) -> bool: ...
def by_option(self, option: Union[ChromiumElement, List[ChromiumElement], Tuple[ChromiumElement]]) -> None: ...
@ -48,7 +48,7 @@ class SelectElement(object):
def cancel_by_index(self, index: Union[int, list, tuple], timeout: float = None) -> bool: ...
def cancel_by_locator(self, locator: Union[str, Tuple[str, str]], timeout: float = None) -> bool: ...
def cancel_by_locator(self, locator: Union[Tuple[str, str], str], timeout: float = None) -> bool: ...
def cancel_by_option(self,
option: Union[ChromiumElement, List[ChromiumElement], Tuple[ChromiumElement]]) -> None: ...

View File

@ -293,13 +293,13 @@ class SessionPageSetter(BasePageSetter):
"""
self._page._headers = CaseInsensitiveDict(headers)
def header(self, attr, value):
def header(self, name, value):
"""设置headers中一个项
:param attr: 设置名称
:param name: 设置名称
:param value: 设置值
:return: None
"""
self._page._headers[attr] = value
self._page._headers[name] = value
def user_agent(self, ua):
"""设置user agent
@ -450,39 +450,46 @@ class ChromiumElementSetter(object):
"""
self._ele = ele
def attr(self, attr, value):
def attr(self, name, value):
"""设置元素attribute属性
:param attr: 属性名
:param name: 属性名
:param value: 属性值
:return: None
"""
self._ele.page.run_cdp('DOM.setAttributeValue', nodeId=self._ele._node_id, name=attr, value=str(value))
self._ele.page.run_cdp('DOM.setAttributeValue', nodeId=self._ele._node_id, name=name, value=str(value))
def prop(self, prop, value):
def property(self, name, value):
"""设置元素property属性
:param prop: 属性名
:param name: 属性名
:param value: 属性值
:return: None
"""
value = value.replace('"', r'\"')
self._ele.run_js(f'this.{prop}="{value}";')
self._ele.run_js(f'this.{name}="{value}";')
def innerHTML(self, html):
"""设置元素innerHTML
:param html: html文本
:return: None
"""
self.prop('innerHTML', html)
self.property('innerHTML', html)
def value(self, value):
"""设置元素value值
:param value: value值
:return: None
"""
self.property('value', value)
class ChromiumFrameSetter(ChromiumBaseSetter):
def attr(self, attr, value):
def attr(self, name, value):
"""设置frame元素attribute属性
:param attr: 属性名
:param name: 属性名
:param value: 属性值
:return: None
"""
self._page.frame_ele.set.attr(attr, value)
self._page.frame_ele.set.attr(name, value)
class LoadMode(object):

View File

@ -113,7 +113,7 @@ class SessionPageSetter(BasePageSetter):
def headers(self, headers: dict) -> None: ...
def header(self, attr: str, value: str) -> None: ...
def header(self, name: str, value: str) -> None: ...
def user_agent(self, ua: str) -> None: ...
@ -168,17 +168,19 @@ class ChromiumElementSetter(object):
def __init__(self, ele: ChromiumElement):
self._ele: ChromiumElement = ...
def attr(self, attr: str, value: str) -> None: ...
def attr(self, name: str, value: str) -> None: ...
def prop(self, prop: str, value: str) -> None: ...
def property(self, name: str, value: str) -> None: ...
def innerHTML(self, html: str) -> None: ...
def value(self, value: str) -> None: ...
class ChromiumFrameSetter(ChromiumBaseSetter):
_page: ChromiumFrame = ...
def attr(self, attr: str, value: str) -> None: ...
def attr(self, name: str, value: str) -> None: ...
class LoadMode(object):

View File

@ -29,8 +29,9 @@ class ElementStates(object):
@property
def is_displayed(self):
"""返回元素是否显示"""
return not (self._ele.style('visibility') == 'hidden' or self._ele.run_js('return this.offsetParent === null;')
or self._ele.style('display') == 'none' or self._ele.prop('hidden'))
return not (self._ele.style('visibility') == 'hidden' or
self._ele.run_js('return this.offsetParent === null;')
or self._ele.style('display') == 'none' or self._ele.property('hidden'))
@property
def is_enabled(self):

View File

@ -119,6 +119,8 @@ class BaseWaiter(object):
:param cancel_it: 是否取消该任务
:return: 成功返回任务对象失败返回False
"""
if not self._driver.browser._dl_mgr._running:
raise RuntimeError('使用下载管理功能前需显式设置下载路径使用set.download_path()方法、配置对象或ini文件均可')
self._driver.browser._dl_mgr.set_flag(self._driver.tab_id, False if cancel_it else True)
if timeout is None:
timeout = self._driver.timeout
@ -232,6 +234,8 @@ class TabWaiter(BaseWaiter):
:param cancel_if_timeout: 超时时是否取消剩余任务
:return: 是否等待成功
"""
if not self._driver.browser._dl_mgr._running:
raise RuntimeError('使用下载管理功能前需显式设置下载路径使用set.download_path()方法、配置对象或ini文件均可')
if not timeout:
while self._driver.browser._dl_mgr.get_tab_missions(self._driver.tab_id):
sleep(.5)
@ -290,6 +294,8 @@ class PageWaiter(TabWaiter):
:param cancel_if_timeout: 超时时是否取消剩余任务
:return: 是否等待成功
"""
if not self._driver.browser._dl_mgr._running:
raise RuntimeError('使用下载管理功能前需显式设置下载路径使用set.download_path()方法、配置对象或ini文件均可')
if not timeout:
while self._driver.browser._dl_mgr._missions:
sleep(.5)
@ -458,7 +464,8 @@ class ElementWaiter(object):
timeout = self._page.timeout
end_time = perf_counter() + timeout
while perf_counter() < end_time:
if self._ele.states.__getattribute__(attr) == mode:
a = self._ele.states.__getattribute__(attr)
if (a and mode) or (not a and not mode):
return True
sleep(.05)

View File

@ -5,7 +5,7 @@
@Copyright: (c) 2024 by g1879, Inc. All Rights Reserved.
@License : BSD 3-Clause.
"""
from typing import Union
from typing import Union, Tuple
from .downloader import DownloadMission
from .._elements.chromium_element import ChromiumElement
@ -34,7 +34,7 @@ class BaseWaiter(object):
raise_err: bool = None) -> bool: ...
def ele_loaded(self,
locator: Union[str, tuple],
locator: Union[Tuple[str, str], str],
timeout: float = None,
raise_err: bool = None) -> Union[bool, ChromiumElement]: ...