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 from ._configs.session_options import SessionOptions
__all__ = ['ChromiumPage', 'ChromiumOptions', 'SessionOptions', 'SessionPage', 'WebPage', '__version__'] __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): def _ele(self, locator, timeout=None, index=1, raise_err=None, method=None):
pass pass
@abstractmethod def _find_elements(self, locator, timeout=None, index=1, relative=False, raise_err=None):
def _find_elements(self, locator, timeout=None, index=1, raise_err=None):
pass pass
@ -89,10 +88,6 @@ class BaseElement(BaseParser):
r.args = {'locator': locator, 'index': index} r.args = {'locator': locator, 'index': index}
return r return r
@abstractmethod
def _find_elements(self, locator, timeout=None, index=1, relative=False, raise_err=None):
pass
class DrissionElement(BaseElement): class DrissionElement(BaseElement):
"""ChromiumElement 和 SessionElement的基类但不是ShadowRoot的基类""" """ChromiumElement 和 SessionElement的基类但不是ShadowRoot的基类"""
@ -341,12 +336,15 @@ class DrissionElement(BaseElement):
return return
@abstractmethod @abstractmethod
def attr(self, attr: str): def attr(self, name: str):
return '' return ''
def _get_ele_path(self, mode): def _get_ele_path(self, mode):
return '' return ''
def _find_elements(self, locator, timeout=None, index=1, relative=False, raise_err=None):
pass
class BasePage(BaseParser): class BasePage(BaseParser):
"""页面类的基类""" """页面类的基类"""
@ -380,11 +378,6 @@ class BasePage(BaseParser):
"""设置查找元素时等待的秒数""" """设置查找元素时等待的秒数"""
self._timeout = second self._timeout = second
@property
def cookies(self):
"""返回cookies"""
return self.get_cookies(True)
@property @property
def url_available(self): def url_available(self):
"""返回当前访问的url有效性""" """返回当前访问的url有效性"""
@ -416,7 +409,7 @@ class BasePage(BaseParser):
return return
@abstractmethod @abstractmethod
def get_cookies(self, as_dict=False, all_info=False): def cookies(self, as_dict=False, all_info=False):
return {} return {}
@abstractmethod @abstractmethod
@ -445,7 +438,3 @@ class BasePage(BaseParser):
r.method = method r.method = method
r.args = {'locator': locator, 'index': index} r.args = {'locator': locator, 'index': index}
return r 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 s_eles(self, locator: Union[Tuple[str, str], str]): ...
def _ele(self, def _ele(self,
locator, locator: Union[Tuple[str, str], str],
timeout: float = None, timeout: float = None,
index: Optional[int] = 1, index: Optional[int] = 1,
raise_err: bool = None, raise_err: bool = None,
method: str = None): ... method: str = None): ...
@abstractmethod
def _find_elements(self, def _find_elements(self,
locator, locator: Union[Tuple[str, str], str],
timeout: float = None, timeout: float = None,
index: Optional[int] = 1, index: Optional[int] = 1,
relative: bool = False,
raise_err: bool = None): ... raise_err: bool = None): ...
@ -65,14 +65,6 @@ class BaseElement(BaseParser):
raise_err: bool = None, raise_err: bool = None,
method: str = 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 parent(self, level_or_loc: Union[tuple, str, int] = 1): ...
def prev(self, index: int = 1) -> None: ... def prev(self, index: int = 1) -> None: ...
@ -109,57 +101,57 @@ class DrissionElement(BaseElement):
index: int = 1) -> Union[DrissionElement, None]: ... index: int = 1) -> Union[DrissionElement, None]: ...
def child(self, def child(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ... ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ...
def prev(self, def prev(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ... ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ...
def next(self, def next(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ... ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ...
def before(self, def before(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ... ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ...
def after(self, def after(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ... ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ...
def children(self, def children(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> List[Union[DrissionElement, str]]: ... ele_only: bool = True) -> List[Union[DrissionElement, str]]: ...
def prevs(self, def prevs(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> List[Union[DrissionElement, str]]: ... ele_only: bool = True) -> List[Union[DrissionElement, str]]: ...
def nexts(self, def nexts(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> List[Union[DrissionElement, str]]: ... ele_only: bool = True) -> List[Union[DrissionElement, str]]: ...
def befores(self, def befores(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> List[Union[DrissionElement, str]]: ... ele_only: bool = True) -> List[Union[DrissionElement, str]]: ...
def afters(self, def afters(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> List[Union[DrissionElement, str]]: ... ele_only: bool = True) -> List[Union[DrissionElement, str]]: ...
@ -167,14 +159,14 @@ class DrissionElement(BaseElement):
func: str, func: str,
direction: str, direction: str,
brother: bool, brother: bool,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> DrissionElement: ... ele_only: bool = True) -> DrissionElement: ...
def _get_relatives(self, def _get_relatives(self,
index: int = None, index: int = None,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
direction: str = 'following', direction: str = 'following',
brother: bool = True, brother: bool = True,
timeout: float = 0.5, timeout: float = 0.5,
@ -191,7 +183,7 @@ class DrissionElement(BaseElement):
def raw_text(self) -> str: ... def raw_text(self) -> str: ...
@abstractmethod @abstractmethod
def attr(self, attr: str) -> str: ... def attr(self, name: str) -> str: ...
def _get_ele_path(self, mode) -> str: ... def _get_ele_path(self, mode) -> str: ...
@ -217,9 +209,6 @@ class BasePage(BaseParser):
@timeout.setter @timeout.setter
def timeout(self, second: float) -> None: ... def timeout(self, second: float) -> None: ...
@property
def cookies(self) -> dict: ...
@property @property
def url_available(self) -> bool: ... def url_available(self) -> bool: ...
@ -240,7 +229,7 @@ class BasePage(BaseParser):
def user_agent(self) -> str: ... def user_agent(self) -> str: ...
@abstractmethod @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 @abstractmethod
def get(self, url: str, show_errmsg: bool = False, retry: int = None, interval: float = None): ... 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, index: Optional[int] = 1,
raise_err: bool = None, raise_err: bool = None,
method: str = 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) timeout = kwargs.pop('_timeout', 30)
result = self._send({'method': _method, 'params': kwargs}, timeout=timeout) result = self._send({'method': _method, 'params': kwargs}, timeout=timeout)
if 'result' not in result and 'error' in result: if 'result' not in result and 'error' in result:
kwargs['_timeout'] = timeout
return {'error': result['error']['message'], 'type': result.get('type', 'call_method_error'), return {'error': result['error']['message'], 'type': result.get('type', 'call_method_error'),
'method': _method, 'args': kwargs, 'timeout': timeout} 'method': _method, 'args': kwargs}
else: else:
return result['result'] return result['result']

View File

@ -26,7 +26,7 @@ class ChromiumOptions(object):
if read_file is not False: if read_file is not False:
ini_path = str(ini_path) if ini_path else None ini_path = str(ini_path) if ini_path else None
om = OptionsManager(ini_path) om = OptionsManager(ini_path)
self.ini_path = om.ini_path self.ini_path = str(Path(om.ini_path).absolute())
options = om.chromium_options options = om.chromium_options
self._download_path = om.paths.get('download_path', None) or None self._download_path = om.paths.get('download_path', None) or None
@ -56,7 +56,7 @@ class ChromiumOptions(object):
timeouts = om.timeouts timeouts = om.timeouts
self._timeouts = {'base': timeouts['base'], self._timeouts = {'base': timeouts['base'],
'pageLoad': timeouts['page_load'], 'page_load': timeouts['page_load'],
'script': timeouts['script']} 'script': timeouts['script']}
self._auto_port = options.get('auto_port', False) self._auto_port = options.get('auto_port', False)
@ -75,7 +75,7 @@ class ChromiumOptions(object):
self._extensions = [] self._extensions = []
self._prefs = {} self._prefs = {}
self._flags = {} 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._address = '127.0.0.1:9222'
self._load_mode = 'normal' self._load_mode = 'normal'
self._proxy = None self._proxy = None
@ -278,18 +278,18 @@ class ChromiumOptions(object):
self.clear_file_flags = True self.clear_file_flags = True
return self 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 base: 默认超时时间
:param pageLoad: 页面加载超时时间 :param page_load: 页面加载超时时间
:param script: 脚本运行超时时间 :param script: 脚本运行超时时间
:return: 当前对象 :return: 当前对象
""" """
base = base if base is not None else implicit base = base if base is not None else implicit
if base is not None: if base is not None:
self._timeouts['base'] = base self._timeouts['base'] = base
if pageLoad is not None: if page_load is not None:
self._timeouts['pageLoad'] = pageLoad self._timeouts['page_load'] = page_load
if script is not None: if script is not None:
self._timeouts['script'] = script self._timeouts['script'] = script
@ -545,7 +545,7 @@ class ChromiumOptions(object):
om.set_item('paths', 'tmp_path', self._tmp_path or '') om.set_item('paths', 'tmp_path', self._tmp_path or '')
# 设置timeout # 设置timeout
om.set_item('timeouts', 'base', self._timeouts['base']) 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('timeouts', 'script', self._timeouts['script'])
# 设置重试 # 设置重试
om.set_item('others', 'retry_times', self.retry_times) 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 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: ... script: float = None) -> ChromiumOptions: ...
def set_user(self, user: str = 'Default') -> 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} self._headers = {key.lower(): headers[key] for key in headers}
return self return self
def set_a_header(self, attr, value): def set_a_header(self, name, value):
"""设置headers中一个项 """设置headers中一个项
:param attr: 设置名称 :param name: 设置名称
:param value: 设置值 :param value: 设置值
:return: 返回当前对象 :return: 返回当前对象
""" """
if self._headers is None: if self._headers is None:
self._headers = {} self._headers = {}
self._headers[attr.lower()] = value self._headers[name.lower()] = value
return self return self
def remove_a_header(self, attr): def remove_a_header(self, name):
"""从headers中删除一个设置 """从headers中删除一个设置
:param attr: 要删除的设置 :param name: 要删除的设置
:return: 返回当前对象 :return: 返回当前对象
""" """
if self._headers is None: if self._headers is None:
return self return self
attr = attr.lower() self._headers.pop(name.lower(), None)
self._headers.pop(attr, None)
return self return self

View File

@ -51,9 +51,9 @@ class SessionOptions(object):
def set_headers(self, headers: Union[dict, None]) -> SessionOptions: ... 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 @property
def cookies(self) -> list: ... def cookies(self) -> list: ...

View File

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

View File

@ -8,7 +8,6 @@
from pathlib import Path from pathlib import Path
from typing import Union, Tuple, List, Any, Literal, Optional from typing import Union, Tuple, List, Any, Literal, Optional
from .none_element import NoneElement
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 .._pages.chromium_base import ChromiumBase from .._pages.chromium_base import ChromiumBase
@ -50,7 +49,7 @@ class ChromiumElement(DrissionElement):
def __call__(self, def __call__(self,
locator: Union[Tuple[str, str], str], locator: Union[Tuple[str, str], str],
index: int = 1, index: int = 1,
timeout: float = None) -> Union[ChromiumElement, NoneElement]: ... timeout: float = None) -> ChromiumElement: ...
def __eq__(self, other: ChromiumElement) -> bool: ... def __eq__(self, other: ChromiumElement) -> bool: ...
@ -73,7 +72,6 @@ class ChromiumElement(DrissionElement):
def raw_text(self) -> str: ... def raw_text(self) -> str: ...
# -----------------d模式独有属性------------------- # -----------------d模式独有属性-------------------
@property @property
def set(self) -> ChromiumElementSetter: ... def set(self) -> ChromiumElementSetter: ...
@ -100,60 +98,60 @@ class ChromiumElement(DrissionElement):
def parent(self, def parent(self,
level_or_loc: Union[tuple, str, int] = 1, level_or_loc: Union[tuple, str, int] = 1,
index: int = 1) -> Union[ChromiumElement, NoneElement]: ... index: int = 1) -> ChromiumElement: ...
def child(self, def child(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> Union[ChromiumElement, str, NoneElement]: ... ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def prev(self, def prev(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> Union[ChromiumElement, str, NoneElement]: ... ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def next(self, def next(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> Union[ChromiumElement, str, NoneElement]: ... ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def before(self, def before(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> Union[ChromiumElement, str, NoneElement]: ... ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def after(self, def after(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> Union[ChromiumElement, str, NoneElement]: ... ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def children(self, def children(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...
def prevs(self, def prevs(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...
def nexts(self, def nexts(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...
def befores(self, def befores(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...
def afters(self, def afters(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...
@ -163,13 +161,16 @@ class ChromiumElement(DrissionElement):
@property @property
def select(self) -> SelectElement: ... def select(self) -> SelectElement: ...
@property
def value(self) -> None: ...
def check(self, uncheck: bool = False, by_js: bool = False) -> 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: ... 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, def ele(self,
locator: Union[Tuple[str, str], str], locator: Union[Tuple[str, str], str],
index: int = 1, index: int = 1,
timeout: float = None) -> Union[ChromiumElement, NoneElement]: ... timeout: float = None) -> ChromiumElement: ...
def eles(self, def eles(self,
locator: Union[Tuple[str, str], str], locator: Union[Tuple[str, str], str],
@ -186,7 +187,7 @@ class ChromiumElement(DrissionElement):
def s_ele(self, def s_ele(self,
locator: Union[Tuple[str, str], str] = None, 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]: ... def s_eles(self, locator: Union[Tuple[str, str], str] = None) -> List[SessionElement]: ...
@ -195,12 +196,12 @@ class ChromiumElement(DrissionElement):
timeout: float = None, timeout: float = None,
index: Optional[int] = 1, index: Optional[int] = 1,
relative: bool = False, relative: bool = False,
raise_err: bool = False) -> Union[ChromiumElement, ChromiumFrame, NoneElement, raise_err: bool = False) -> Union[ChromiumElement, ChromiumFrame,
List[Union[ChromiumElement, ChromiumFrame]]]: ... List[Union[ChromiumElement, ChromiumFrame]]]: ...
def style(self, style: str, pseudo_ele: str = '') -> str: ... 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: ... 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 parent(self, level_or_loc: Union[str, int] = 1, index: int = 1) -> ChromiumElement: ...
def child(self, def child(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
index: int = 1) -> Union[ChromiumElement, NoneElement]: ... index: int = 1) -> ChromiumElement: ...
def next(self, def next(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
index: int = 1) -> Union[ChromiumElement, NoneElement]: ... index: int = 1) -> ChromiumElement: ...
def before(self, def before(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
index: int = 1) -> Union[ChromiumElement, NoneElement]: ... index: int = 1) -> ChromiumElement: ...
def after(self, def after(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
index: int = 1) -> Union[ChromiumElement, NoneElement]: ... 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, def ele(self,
locator: Union[Tuple[str, str], str], locator: Union[Tuple[str, str], str],
index: int = 1, index: int = 1,
timeout: float = None) -> Union[ChromiumElement, NoneElement]: ... timeout: float = None) -> ChromiumElement: ...
def eles(self, def eles(self,
locator: Union[Tuple[str, str], str], locator: Union[Tuple[str, str], str],
@ -307,7 +308,7 @@ class ShadowRoot(BaseElement):
def s_ele(self, def s_ele(self,
locator: Union[Tuple[str, str], str] = None, 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]: ... def s_eles(self, locator: Union[Tuple[str, str], str]) -> List[SessionElement]: ...
@ -316,7 +317,7 @@ class ShadowRoot(BaseElement):
timeout: float = None, timeout: float = None,
index: Optional[int] = 1, index: Optional[int] = 1,
relative: bool = False, 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]]]: ... List[Union[ChromiumElement, ChromiumFrame, str]]]: ...
def _get_node_id(self, obj_id: str) -> int: ... 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]], loc: Union[str, Tuple[str, str]],
index: Optional[int] = 1, index: Optional[int] = 1,
timeout: float = None, timeout: float = None,
relative: bool = True) -> Union[ChromiumElement, NoneElement, List[ChromiumElement]]: ... relative: bool = True) -> Union[ChromiumElement, List[ChromiumElement]]: ...
def find_by_xpath(ele: ChromiumElement, def find_by_xpath(ele: ChromiumElement,
xpath: str, xpath: str,
index: Optional[int], index: Optional[int],
timeout: float, timeout: float,
relative: bool = True) -> Union[ChromiumElement, List[ChromiumElement], NoneElement]: ... relative: bool = True) -> Union[ChromiumElement, List[ChromiumElement]]: ...
def find_by_css(ele: ChromiumElement, def find_by_css(ele: ChromiumElement,
selector: str, selector: str,
index: Optional[int], 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], def make_chromium_eles(page: Union[ChromiumBase, ChromiumPage, WebPage, ChromiumTab, ChromiumFrame],
_ids: Union[tuple, list, str, int], _ids: Union[tuple, list, str, int],
index: Optional[int] = 1, index: Optional[int] = 1,
is_obj_id: bool = True is_obj_id: bool = True
) -> Union[ChromiumElement, ChromiumFrame, NoneElement, ) -> Union[ChromiumElement, ChromiumFrame, List[Union[ChromiumElement, ChromiumFrame]]]: ...
List[Union[ChromiumElement, ChromiumFrame]]]: ...
def make_js_for_find_ele_by_xpath(xpath: str, type_txt: str, node_txt: str) -> str: ... 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._none_ele_return_value = False
self.method = method self.method = method
self.args = args self.args = args
self._get = None
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):
if not self._none_ele_return_value: if not self._none_ele_return_value:
@ -33,7 +34,7 @@ class NoneElement(object):
return self return self
else: else:
if item in ('size', 'link', 'css_path', 'xpath', 'comments', 'texts', 'tag', 'html', 'inner_html', 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 return self._none_ele_value
else: else:
raise ElementNotFoundError(None, self.method, self.args) raise ElementNotFoundError(None, self.method, self.args)

View File

@ -34,7 +34,7 @@ class SessionElement(DrissionElement):
return self._inner_ele return self._inner_ele
def __repr__(self): 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)}>' return f'<SessionElement {self.tag} {" ".join(attrs)}>'
def __call__(self, locator, timeout=None): def __call__(self, locator, timeout=None):
@ -188,13 +188,13 @@ class SessionElement(DrissionElement):
""" """
return super().afters(locator, timeout, ele_only=ele_only) return super().afters(locator, timeout, ele_only=ele_only)
def attr(self, attr): def attr(self, name):
"""返回attribute属性值 """返回attribute属性值
:param attr: 属性名 :param name: 属性名
:return: 属性值文本没有该属性返回None :return: 属性值文本没有该属性返回None
""" """
# 获取href属性时返回绝对url # 获取href属性时返回绝对url
if attr == 'href': if name == 'href':
link = self.inner_ele.get('href') link = self.inner_ele.get('href')
# 若为链接为None、js或邮件直接返回 # 若为链接为None、js或邮件直接返回
if not link or link.lower().startswith(('javascript:', 'mailto:')): if not link or link.lower().startswith(('javascript:', 'mailto:')):
@ -203,23 +203,23 @@ class SessionElement(DrissionElement):
else: # 其它情况直接返回绝对url else: # 其它情况直接返回绝对url
return make_absolute_link(link, self.page.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) return make_absolute_link(self.inner_ele.get('src'), self.page.url)
elif attr == 'text': elif name == 'text':
return self.text return self.text
elif attr == 'innerText': elif name == 'innerText':
return self.raw_text return self.raw_text
elif attr in ('html', 'outerHTML'): elif name in ('html', 'outerHTML'):
return self.html return self.html
elif attr == 'innerHTML': elif name == 'innerHTML':
return self.inner_html return self.inner_html
else: else:
return self.inner_ele.get(attr) return self.inner_ele.get(name)
def ele(self, locator, index=1, timeout=None): 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 lxml.html import HtmlElement
from .none_element import NoneElement
from .._base.base import DrissionElement, BaseElement from .._base.base import DrissionElement, BaseElement
from .._elements.chromium_element import ChromiumElement from .._elements.chromium_element import ChromiumElement
from .._pages.chromium_base import ChromiumBase from .._pages.chromium_base import ChromiumBase
@ -31,7 +30,7 @@ class SessionElement(DrissionElement):
def __call__(self, def __call__(self,
locator: Union[Tuple[str, str], str], locator: Union[Tuple[str, str], str],
index: int = 1, index: int = 1,
timeout: float = None) -> Union[SessionElement, NoneElement]: ... timeout: float = None) -> SessionElement: ...
def __eq__(self, other: SessionElement) -> bool: ... def __eq__(self, other: SessionElement) -> bool: ...
@ -55,69 +54,69 @@ class SessionElement(DrissionElement):
def parent(self, def parent(self,
level_or_loc: Union[tuple, str, int] = 1, level_or_loc: Union[tuple, str, int] = 1,
index: int = 1) -> Union[SessionElement, NoneElement]: ... index: int = 1) -> SessionElement: ...
def child(self, def child(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> Union[SessionElement, str, NoneElement]: ... ele_only: bool = True) -> Union[SessionElement, str]: ...
def prev(self, def prev(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> Union[SessionElement, str, NoneElement]: ... ele_only: bool = True) -> Union[SessionElement, str]: ...
def next(self, def next(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> Union[SessionElement, str, NoneElement]: ... ele_only: bool = True) -> Union[SessionElement, str]: ...
def before(self, def before(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> Union[SessionElement, str, NoneElement]: ... ele_only: bool = True) -> Union[SessionElement, str]: ...
def after(self, def after(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> Union[SessionElement, str, NoneElement]: ... ele_only: bool = True) -> Union[SessionElement, str]: ...
def children(self, def children(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> List[Union[SessionElement, str]]: ... ele_only: bool = True) -> List[Union[SessionElement, str]]: ...
def prevs(self, def prevs(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> List[Union[SessionElement, str]]: ... ele_only: bool = True) -> List[Union[SessionElement, str]]: ...
def nexts(self, def nexts(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> List[Union[SessionElement, str]]: ... ele_only: bool = True) -> List[Union[SessionElement, str]]: ...
def befores(self, def befores(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> List[Union[SessionElement, str]]: ... ele_only: bool = True) -> List[Union[SessionElement, str]]: ...
def afters(self, def afters(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> List[Union[SessionElement, str]]: ... 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, def ele(self,
locator: Union[Tuple[str, str], str], locator: Union[Tuple[str, str], str],
index: int = 1, index: int = 1,
timeout: float = None) -> Union[SessionElement, NoneElement]: ... timeout: float = None) -> SessionElement: ...
def eles(self, def eles(self,
locator: Union[Tuple[str, str], str], locator: Union[Tuple[str, str], str],
@ -125,7 +124,7 @@ class SessionElement(DrissionElement):
def s_ele(self, def s_ele(self,
locator: Union[Tuple[str, str], str] = None, 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]: ... def s_eles(self, locator: Union[Tuple[str, str], str]) -> List[SessionElement]: ...
@ -134,7 +133,7 @@ class SessionElement(DrissionElement):
timeout: float = None, timeout: float = None,
index: Optional[int] = 1, index: Optional[int] = 1,
relative: bool = False, 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: ... 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, def make_session_ele(html_or_ele: Union[str, SessionElement, SessionPage, ChromiumElement, BaseElement, ChromiumFrame,
ChromiumBase], ChromiumBase],
loc: Union[str, Tuple[str, str]] = None, 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: 返回是否接管的浏览器 :return: 返回是否接管的浏览器
""" """
address = option.address.replace('localhost', '127.0.0.1').lstrip('http://').lstrip('https://') 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(':') ip, port = address.split(':')
if ip != '127.0.0.1' or port_is_using(ip, port) or option.is_existing_only: 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_prefs(option)
set_flags(option) set_flags(option)
try: try:
_run_browser(port, chrome_path, args) _run_browser(port, browser_path, args)
# 传入的路径找不到主动在ini文件、注册表、系统变量中找 # 传入的路径找不到主动在ini文件、注册表、系统变量中找
except FileNotFoundError: 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('无法找到浏览器可执行文件路径,请手动配置。') raise FileNotFoundError('无法找到浏览器可执行文件路径,请手动配置。')
_run_browser(port, chrome_path, args) _run_browser(port, browser_path, args)
test_connect(ip, port) test_connect(ip, port)
return False return False
@ -219,7 +219,7 @@ def test_connect(ip, port, timeout=30):
def _run_browser(port, path: str, args) -> Popen: def _run_browser(port, path: str, args) -> Popen:
"""创建chrome进程 """创建浏览器进程
:param port: 端口号 :param port: 端口号
:param path: 浏览器路径 :param path: 浏览器路径
:param args: 启动参数 :param args: 启动参数
@ -282,12 +282,13 @@ def _remove_arg_from_dict(target_dict: dict, arg: str) -> None:
pass pass
def get_chrome_path(): def get_chrome_path(ini_path):
"""从ini文件或系统变量中获取chrome可执行文件的路径""" """从ini文件或系统变量中获取chrome可执行文件的路径"""
# -----------从ini文件中获取-------------- # -----------从ini文件中获取--------------
path = OptionsManager().chromium_options.get('browser_path', None) if ini_path:
if path and Path(path).is_file(): path = OptionsManager(ini_path).chromium_options.get('browser_path', None)
return str(path) if path and Path(path).is_file():
return str(path)
# -----------使用which获取----------- # -----------使用which获取-----------
from shutil import 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 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 pid = page.process_id
if not pid: if not pid:
return None 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 sw = SW_HIDE if hide else SW_SHOW
for hd in hds: for hd in hds:
ShowWindow(hd, sw) ShowWindow(hd, sw)
@ -141,7 +141,7 @@ def get_browser_progress_id(progress, address):
return txt.split(' ')[-1] return txt.split(' ')[-1]
def get_chrome_hwnds_from_pid(pid, title): def get_hwnds_from_pid(pid, title):
"""通过PID查询句柄ID """通过PID查询句柄ID
:param pid: 进程id :param pid: 进程id
:param title: 窗口标题 :param title: 窗口标题
@ -240,11 +240,11 @@ def raise_error(result, ignore=None):
elif error == 'Given expression does not evaluate to a function': elif error == 'Given expression does not evaluate to a function':
r = JavaScriptError(f'传入的js无法解析成函数\n{result["args"]["functionDeclaration"]}') r = JavaScriptError(f'传入的js无法解析成函数\n{result["args"]["functionDeclaration"]}')
elif error.endswith("' wasn't found"): 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'): elif result['type'] in ('call_method_error', 'timeout'):
from DrissionPage import __version__ from DrissionPage import __version__
from time import process_time 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请把错误信息和重现方法' \ f'版本:{__version__}\n运行时间:{process_time()}\n出现这个错误可能意味着程序有bug请把错误信息和重现方法' \
'告知作者,谢谢。\n报告网站https://gitee.com/g1879/DrissionPage/issues' '告知作者,谢谢。\n报告网站https://gitee.com/g1879/DrissionPage/issues'
r = TimeoutError(txt) if result['type'] == 'timeout' else CDPError(txt) 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_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): ... 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() func = func.strip()
if (func.startswith('function') or func.startswith('async ')) and func.endswith('}'): if (func.startswith('function') or func.startswith('async ')) and func.endswith('}'):
return True return True
elif '=>' in func: # elif '=>' in func:
return True # return True
return False return False
@ -361,3 +361,5 @@ def get_blob(page, url, as_bytes=True):
if as_bytes: if as_bytes:
from base64 import b64decode from base64 import b64decode
return b64decode(result.split(',', 1)[-1]) return b64decode(result.split(',', 1)[-1])
else:
return result

View File

@ -474,8 +474,8 @@ class ChromiumBase(BasePage):
show_errmsg=show_errmsg, timeout=timeout) show_errmsg=show_errmsg, timeout=timeout)
return self._url_available return self._url_available
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信息 """返回cookies信息
:param as_dict: 为True时返回由{name: value}键值对组成的dict为True时返回list且all_info无效 :param as_dict: 为True时返回由{name: value}键值对组成的dict为True时返回list且all_info无效
:param all_domains: 是否返回所有域的cookies :param all_domains: 是否返回所有域的cookies
:param all_info: 是否返回所有信息为False时只返回namevaluedomain :param all_info: 是否返回所有信息为False时只返回namevaluedomain
@ -722,8 +722,8 @@ class ChromiumBase(BasePage):
frames = self._ele(locator, timeout=timeout, index=None, raise_err=False) frames = self._ele(locator, timeout=timeout, index=None, raise_err=False)
return [i for i in frames if i._type == 'ChromiumFrame'] return [i for i in frames if i._type == 'ChromiumFrame']
def get_session_storage(self, item=None): def session_storage(self, item=None):
"""获取sessionStorage信息不设置item则获取全部 """返回sessionStorage信息不设置item则获取全部
:param item: 要获取的项不设置则返回全部 :param item: 要获取的项不设置则返回全部
:return: sessionStorage一个或所有项内容 :return: sessionStorage一个或所有项内容
""" """
@ -743,8 +743,8 @@ class ChromiumBase(BasePage):
''' '''
return {i['key']: i['val'] for i in self.run_js_loaded(js)} return {i['key']: i['val'] for i in self.run_js_loaded(js)}
def get_local_storage(self, item=None): def local_storage(self, item=None):
"""获取localStorage信息不设置item则获取全部 """返回localStorage信息不设置item则获取全部
:param item: 要获取的项目不设置则返回全部 :param item: 要获取的项目不设置则返回全部
:return: localStorage一个或所有项内容 :return: localStorage一个或所有项内容
""" """
@ -930,7 +930,11 @@ class ChromiumBase(BasePage):
:param interval: 重试间隔 :param interval: 重试间隔
:return: 重试次数和间隔组成的tuple :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 retry = retry if retry is not None else self.retry_times
interval = interval if interval is not None else self.retry_interval interval = interval if interval is not None else self.retry_interval
return retry, interval return retry, interval
@ -1033,11 +1037,12 @@ class ChromiumBase(BasePage):
pic_type = path.suffix.lower() pic_type = path.suffix.lower()
pic_type = 'jpeg' if pic_type == '.jpg' else pic_type[1:] pic_type = 'jpeg' if pic_type == '.jpg' else pic_type[1:]
width, height = self.rect.size
if full_page: 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} vp = {'x': 0, 'y': 0, 'width': width, 'height': height, 'scale': 1}
png = self.run_cdp_loaded('Page.captureScreenshot', format=pic_type, args = {'format': pic_type, 'captureBeyondViewport': True, 'clip': vp}
captureBeyondViewport=True, clip=vp)['data']
else: else:
if left_top and right_bottom: if left_top and right_bottom:
x, y = left_top x, y = left_top
@ -1051,11 +1056,14 @@ class ChromiumBase(BasePage):
x += 10 x += 10
vp = {'x': x, 'y': y, 'width': w, 'height': h, 'scale': 1} vp = {'x': x, 'y': y, 'width': w, 'height': h, 'scale': 1}
png = self.run_cdp_loaded('Page.captureScreenshot', format=pic_type, args = {'format': pic_type, 'captureBeyondViewport': v, 'clip': vp}
captureBeyondViewport=v, clip=vp)['data']
else: 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: if as_base64:
return png return png
@ -1095,6 +1103,15 @@ class ChromiumBase(BasePage):
"""返回页面总宽高,格式:(宽, 高)""" """返回页面总宽高,格式:(宽, 高)"""
return self.rect.size 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): class Timeout(object):
"""用于保存d模式timeout信息的类""" """用于保存d模式timeout信息的类"""

View File

@ -13,7 +13,6 @@ from .._base.base import BasePage
from .._base.browser import Browser 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.none_element import NoneElement
from .._elements.session_element import SessionElement from .._elements.session_element import SessionElement
from .._pages.chromium_frame import ChromiumFrame from .._pages.chromium_frame import ChromiumFrame
from .._pages.chromium_page import ChromiumPage from .._pages.chromium_page import ChromiumPage
@ -97,7 +96,7 @@ class ChromiumBase(BasePage):
def __call__(self, def __call__(self,
locator: Union[Tuple[str, str], str, ChromiumElement], locator: Union[Tuple[str, str], str, ChromiumElement],
index: int = 1, index: int = 1,
timeout: float = None) -> Union[ChromiumElement, NoneElement]: ... timeout: float = None) -> ChromiumElement: ...
@property @property
def _js_ready_state(self) -> str: ... 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, def get(self, url: str, show_errmsg: bool = False, retry: int = None,
interval: float = None, timeout: float = None) -> Union[None, bool]: ... interval: float = None, timeout: float = None) -> Union[None, bool]: ...
def get_cookies(self, as_dict: bool = False, all_domains: bool = False, def cookies(self, as_dict: bool = False, all_domains: bool = False, all_info: bool = False) -> Union[list, dict]: ...
all_info: bool = False) -> Union[list, dict]: ...
def ele(self, def ele(self,
locator: Union[Tuple[str, str], str, ChromiumElement, ChromiumFrame], locator: Union[Tuple[str, str], str, ChromiumElement, ChromiumFrame],
index: int = 1, index: int = 1,
timeout: float = None) -> Union[ChromiumElement, NoneElement]: ... timeout: float = None) -> ChromiumElement: ...
def eles(self, def eles(self,
locator: Union[Tuple[str, str], str], locator: Union[Tuple[str, str], str],
@ -191,7 +189,7 @@ class ChromiumBase(BasePage):
def s_ele(self, def s_ele(self,
locator: Union[Tuple[str, str], str] = None, 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]: ... def s_eles(self, locator: Union[Tuple[str, str], str]) -> List[SessionElement]: ...
@ -201,7 +199,7 @@ class ChromiumBase(BasePage):
index: Optional[int] = 1, index: Optional[int] = 1,
relative: bool = False, relative: bool = False,
raise_err: bool = None) \ 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: ... 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 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: ... 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) return self._frame_id == getattr(other, '_frame_id', None)
def __repr__(self): def __repr__(self):
attrs = self._frame_ele.attrs attrs = [f"{k}='{v}'" for k, v in self._frame_ele.attrs.items()]
attrs = [f"{attr}='{attrs[attr]}'" for attr in attrs]
return f'<ChromiumFrame {self.frame_ele.tag} {" ".join(attrs)}>' return f'<ChromiumFrame {self.frame_ele.tag} {" ".join(attrs)}>'
def _d_set_runtime_settings(self): def _d_set_runtime_settings(self):
@ -146,19 +145,6 @@ class ChromiumFrame(ChromiumBase):
if timeout <= 0: if timeout <= 0:
timeout = .5 timeout = .5
self._wait_loaded(timeout) 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._is_loading = False
self._reloading = False self._reloading = False
@ -208,7 +194,6 @@ class ChromiumFrame(ChromiumBase):
self._reload() self._reload()
# ----------挂件---------- # ----------挂件----------
@property @property
def scroll(self): def scroll(self):
"""返回用于滚动的对象""" """返回用于滚动的对象"""
@ -252,7 +237,7 @@ class ChromiumFrame(ChromiumBase):
self._listener = FrameListener(self) self._listener = FrameListener(self)
return self._listener return self._listener
# ----------挂件---------- # ----------挂件结束----------
@property @property
def _obj_id(self): def _obj_id(self):
@ -305,11 +290,6 @@ class ChromiumFrame(ChromiumBase):
r = self._ele('t:title', raise_err=False) r = self._ele('t:title', raise_err=False)
return r.text if r else None 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 @property
def attrs(self): def attrs(self):
"""返回frame元素所有attribute属性""" """返回frame元素所有attribute属性"""
@ -356,23 +336,57 @@ class ChromiumFrame(ChromiumBase):
except: except:
return None 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): def refresh(self):
"""刷新frame页面""" """刷新frame页面"""
self.doc_ele.run_js('this.location.reload();') self.doc_ele.run_js('this.location.reload();')
def attr(self, attr): def property(self, name):
"""返回frame元素attribute属性值 """返回frame元素一个property属性值
:param attr: 属性名 :param name: 属性名
:return: 属性值文本没有该属性返回None :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属性 """删除frame元素attribute属性
:param attr: 属性名 :param name: 属性名
:return: None :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): def run_js(self, script, *args, as_expr=False, timeout=None):
"""运行javascript代码 """运行javascript代码
@ -580,30 +594,3 @@ class ChromiumFrame(ChromiumBase):
def _is_inner_frame(self): def _is_inner_frame(self):
"""返回当前frame是否同域""" """返回当前frame是否同域"""
return self._frame_id in str(self._target_page.run_cdp('Page.getFrameTree')['frameTree']) 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 .chromium_tab import ChromiumTab
from .web_page import WebPage from .web_page import WebPage
from .._elements.chromium_element import ChromiumElement from .._elements.chromium_element import ChromiumElement
from .._elements.none_element import NoneElement
from .._units.listener import FrameListener from .._units.listener import FrameListener
from .._units.rect import FrameRect from .._units.rect import FrameRect
from .._units.scroller import FrameScroller from .._units.scroller import FrameScroller
@ -32,6 +31,7 @@ class ChromiumFrame(ChromiumBase):
self._target_page: ChromiumBase = ... self._target_page: ChromiumBase = ...
self.tab: ChromiumTab = ... self.tab: ChromiumTab = ...
self._tab_id: str = ... self._tab_id: str = ...
self._set: ChromiumFrameSetter = ...
self._frame_ele: ChromiumElement = ... self._frame_ele: ChromiumElement = ...
self._backend_id: int = ... self._backend_id: int = ...
self._doc_ele: ChromiumElement = ... self._doc_ele: ChromiumElement = ...
@ -45,7 +45,7 @@ class ChromiumFrame(ChromiumBase):
def __call__(self, def __call__(self,
locator: Union[Tuple[str, str], str], locator: Union[Tuple[str, str], str],
index: int = 1, index: int = 1,
timeout: float = None) -> Union[ChromiumElement, NoneElement]: ... timeout: float = None) -> ChromiumElement: ...
def __eq__(self, other: ChromiumFrame) -> bool: ... def __eq__(self, other: ChromiumFrame) -> bool: ...
@ -86,9 +86,6 @@ class ChromiumFrame(ChromiumBase):
@property @property
def title(self) -> str: ... def title(self) -> str: ...
@property
def cookies(self) -> dict: ...
@property @property
def attrs(self) -> dict: ... def attrs(self) -> dict: ...
@ -133,9 +130,11 @@ class ChromiumFrame(ChromiumBase):
def refresh(self) -> None: ... 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, def run_js(self,
script: str, script: str,
@ -144,50 +143,50 @@ class ChromiumFrame(ChromiumBase):
timeout: float = None) -> Any: ... timeout: float = None) -> Any: ...
def parent(self, def parent(self,
level_or_loc: Union[tuple, str, int] = 1, level_or_loc: Union[Tuple[str, str], str, int] = 1,
index: int = 1) -> Union[ChromiumElement, NoneElement]: ... index: int = 1) -> ChromiumElement: ...
def prev(self, def prev(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = 0, timeout: float = 0,
ele_only: bool = True) -> Union[ChromiumElement, NoneElement, str]: ... ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def next(self, def next(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = 0, timeout: float = 0,
ele_only: bool = True) -> Union[ChromiumElement, NoneElement, str]: ... ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def before(self, def before(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> Union[ChromiumElement, NoneElement, str]: ... ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def after(self, def after(self,
locator: Union[tuple, str, int] = '', locator: Union[Tuple[str, str], str, int] = '',
index: int = 1, index: int = 1,
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> Union[ChromiumElement, NoneElement, str]: ... ele_only: bool = True) -> Union[ChromiumElement, str]: ...
def prevs(self, def prevs(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = 0, timeout: float = 0,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...
def nexts(self, def nexts(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = 0, timeout: float = 0,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...
def befores(self, def befores(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...
def afters(self, def afters(self,
locator: Union[tuple, str] = '', locator: Union[Tuple[str, str], str] = '',
timeout: float = None, timeout: float = None,
ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ...

View File

@ -24,7 +24,7 @@ from ..errors import BrowserConnectError
class ChromiumPage(ChromiumBase): class ChromiumPage(ChromiumBase):
"""用于管理浏览器的类""" """用于管理浏览器的类"""
PAGES = {} _PAGES = {}
def __new__(cls, addr_or_opts=None, tab_id=None, timeout=None, addr_driver_opts=None): 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 addr_or_opts = addr_or_opts or addr_driver_opts
opt = handle_options(addr_or_opts) opt = handle_options(addr_or_opts)
is_exist, browser_id = run_browser(opt) is_exist, browser_id = run_browser(opt)
if browser_id in cls.PAGES: if browser_id in cls._PAGES:
r = cls.PAGES[browser_id] r = cls._PAGES[browser_id]
while not hasattr(r, '_frame_id'): while not hasattr(r, '_frame_id'):
sleep(.1) sleep(.1)
return r return r
@ -45,7 +45,7 @@ class ChromiumPage(ChromiumBase):
r._is_exist = is_exist r._is_exist = is_exist
r._browser_id = browser_id r._browser_id = browser_id
r.address = opt.address r.address = opt.address
cls.PAGES[browser_id] = r cls._PAGES[browser_id] = r
return r return r
def __init__(self, addr_or_opts=None, tab_id=None, timeout=None, addr_driver_opts=None): 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): 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'], script=self._chromium_options.timeouts['script'],
base=self._chromium_options.timeouts['base']) base=self._chromium_options.timeouts['base'])
if self._chromium_options.timeouts['base'] is not None: if self._chromium_options.timeouts['base'] is not None:
@ -255,7 +255,7 @@ class ChromiumPage(ChromiumBase):
def _on_disconnect(self): def _on_disconnect(self):
"""浏览器退出时执行""" """浏览器退出时执行"""
ChromiumPage.PAGES.pop(self._browser_id, None) ChromiumPage._PAGES.pop(self._browser_id, None)
def __repr__(self): def __repr__(self):
return f'<ChromiumPage browser_id={self.browser.id} tab_id={self.tab_id}>' 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): class ChromiumPage(ChromiumBase):
PAGES: dict = ... _PAGES: dict = ...
def __new__(cls, def __new__(cls,
addr_or_opts: Union[str, int, ChromiumOptions] = None, addr_or_opts: Union[str, int, ChromiumOptions] = None,
@ -55,9 +55,6 @@ class ChromiumPage(ChromiumBase):
@property @property
def wait(self) -> PageWaiter: ... def wait(self) -> PageWaiter: ...
@property
def main_tab(self) -> str: ...
@property @property
def latest_tab(self) -> str: ... def latest_tab(self) -> str: ...

View File

@ -20,20 +20,20 @@ from .._units.waiter import TabWaiter
class ChromiumTab(ChromiumBase): class ChromiumTab(ChromiumBase):
"""实现浏览器标签页的类""" """实现浏览器标签页的类"""
TABS = {} _TABS = {}
def __new__(cls, page, tab_id): def __new__(cls, page, tab_id):
""" """
:param page: ChromiumPage对象 :param page: ChromiumPage对象
:param tab_id: 要控制的标签页id :param tab_id: 要控制的标签页id
""" """
if Settings.singleton_tab_obj and tab_id in cls.TABS: if Settings.singleton_tab_obj and tab_id in cls._TABS:
r = cls.TABS[tab_id] r = cls._TABS[tab_id]
while not hasattr(r, '_frame_id'): while not hasattr(r, '_frame_id'):
sleep(.1) sleep(.1)
return r return r
r = object.__new__(cls) r = object.__new__(cls)
cls.TABS[tab_id] = r cls._TABS[tab_id] = r
return r return r
def __init__(self, page, tab_id): 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}>' return f'<ChromiumTab browser_id={self.browser.id} tab_id={self.tab_id}>'
def _on_disconnect(self): def _on_disconnect(self):
ChromiumTab.TABS.pop(self.tab_id, None) ChromiumTab._TABS.pop(self.tab_id, None)
class WebPageTab(SessionPage, ChromiumTab, BasePage): class WebPageTab(SessionPage, ChromiumTab, BasePage):
@ -188,11 +188,6 @@ class WebPageTab(SessionPage, ChromiumTab, BasePage):
"""返回当前模式,'s''d' """ """返回当前模式,'s''d' """
return self._mode return self._mode
@property
def cookies(self):
"""以dict方式返回cookies"""
return super().cookies
@property @property
def user_agent(self): def user_agent(self):
"""返回user agent""" """返回user agent"""
@ -357,15 +352,15 @@ class WebPageTab(SessionPage, ChromiumTab, BasePage):
user_agent = self.run_cdp('Runtime.evaluate', expression='navigator.userAgent;')['result']['value'] user_agent = self.run_cdp('Runtime.evaluate', expression='navigator.userAgent;')['result']['value']
self._headers.update({"User-Agent": user_agent}) 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): def cookies_to_browser(self):
"""把session对象的cookies复制到浏览器""" """把session对象的cookies复制到浏览器"""
if not self._has_driver: if not self._has_driver:
return 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 """返回cookies
:param as_dict: 是否以字典方式返回 :param as_dict: 是否以字典方式返回
:param all_domains: 是否返回所有域的cookies :param all_domains: 是否返回所有域的cookies
@ -373,9 +368,9 @@ class WebPageTab(SessionPage, ChromiumTab, BasePage):
:return: cookies信息 :return: cookies信息
""" """
if self._mode == 's': 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': 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): def close(self):
"""关闭当前标签页""" """关闭当前标签页"""
@ -400,3 +395,7 @@ class WebPageTab(SessionPage, ChromiumTab, BasePage):
def __repr__(self): def __repr__(self):
return f'<WebPageTab browser_id={self.browser.id} tab_id={self.tab_id}>' 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. @License : BSD 3-Clause.
""" """
from pathlib import Path from pathlib import Path
from threading import Lock
from typing import Union, Tuple, Any, List, Optional from typing import Union, Tuple, Any, List, Optional
from requests import Session, Response from requests import Session, Response
@ -18,7 +17,6 @@ from .session_page import SessionPage
from .web_page import WebPage from .web_page import WebPage
from .._base.browser import Browser from .._base.browser import Browser
from .._elements.chromium_element import ChromiumElement from .._elements.chromium_element import ChromiumElement
from .._elements.none_element import NoneElement
from .._elements.session_element import SessionElement from .._elements.session_element import SessionElement
from .._units.rect import TabRect from .._units.rect import TabRect
from .._units.setter import TabSetter, WebPageTabSetter from .._units.setter import TabSetter, WebPageTabSetter
@ -26,8 +24,7 @@ from .._units.waiter import TabWaiter
class ChromiumTab(ChromiumBase): class ChromiumTab(ChromiumBase):
TABS: dict = ... _TABS: dict = ...
LOCK: Lock = ...
def __new__(cls, page: ChromiumPage, tab_id: str): ... def __new__(cls, page: ChromiumPage, tab_id: str): ...
@ -82,7 +79,7 @@ class WebPageTab(SessionPage, ChromiumTab):
def __call__(self, def __call__(self,
locator: Union[Tuple[str, str], str, ChromiumElement, SessionElement], locator: Union[Tuple[str, str], str, ChromiumElement, SessionElement],
index: int = 1, index: int = 1,
timeout: float = None) -> Union[ChromiumElement, SessionElement, NoneElement]: ... timeout: float = None) -> Union[ChromiumElement, SessionElement]: ...
@property @property
def page(self) -> WebPage: ... def page(self) -> WebPage: ...
@ -111,9 +108,6 @@ class WebPageTab(SessionPage, ChromiumTab):
@property @property
def mode(self) -> str: ... def mode(self) -> str: ...
@property
def cookies(self) -> dict: ...
@property @property
def user_agent(self) -> str: ... def user_agent(self) -> str: ...
@ -152,7 +146,7 @@ class WebPageTab(SessionPage, ChromiumTab):
def ele(self, def ele(self,
locator: Union[Tuple[str, str], str, ChromiumElement, SessionElement], locator: Union[Tuple[str, str], str, ChromiumElement, SessionElement],
index: int = 1, index: int = 1,
timeout: float = None) -> Union[ChromiumElement, SessionElement, NoneElement]: ... timeout: float = None) -> Union[ChromiumElement, SessionElement]: ...
def eles(self, def eles(self,
locator: Union[Tuple[str, str], str], locator: Union[Tuple[str, str], str],
@ -160,7 +154,7 @@ class WebPageTab(SessionPage, ChromiumTab):
def s_ele(self, def s_ele(self,
locator: Union[Tuple[str, str], str] = None, 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]: ... 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 cookies_to_browser(self) -> None: ...
def get_cookies(self, as_dict: bool = False, all_domains: bool = False, def cookies(self, as_dict: bool = False, all_domains: bool = False,
all_info: bool = False) -> Union[dict, list]: ... all_info: bool = False) -> Union[dict, list]: ...
def close(self) -> None: ... def close(self) -> None: ...
@ -205,5 +199,5 @@ class WebPageTab(SessionPage, ChromiumTab):
index: Optional[int] = 1, index: Optional[int] = 1,
relative: bool = False, relative: bool = False,
raise_err: bool = None) \ raise_err: bool = None) \
-> Union[ChromiumElement, SessionElement, ChromiumFrame, NoneElement, List[SessionElement], List[ -> Union[ChromiumElement, SessionElement, ChromiumFrame, List[SessionElement], List[
Union[ChromiumElement, ChromiumFrame]]]: ... Union[ChromiumElement, ChromiumFrame]]]: ...

View File

@ -47,8 +47,11 @@ class SessionPage(BasePage):
:param session_or_options: SessionSessionOptions对象 :param session_or_options: SessionSessionOptions对象
:return: None :return: None
""" """
if not session_or_options or isinstance(session_or_options, SessionOptions): if not session_or_options:
self._session_options = session_or_options or SessionOptions(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): elif isinstance(session_or_options, Session):
self._session_options = SessionOptions() self._session_options = SessionOptions()
@ -208,7 +211,7 @@ class SessionPage(BasePage):
""" """
return self._ele(locator, index=None) 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 locator: 元素的定位信息可以是元素对象loc元组或查询字符串
:param timeout: 不起实际作用用于和父类对应 :param timeout: 不起实际作用用于和父类对应
@ -218,7 +221,7 @@ class SessionPage(BasePage):
""" """
return locator if isinstance(locator, SessionElement) else make_session_ele(self, locator, index=index) 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 """返回cookies
:param as_dict: 是否以字典方式返回False则以list返回 :param as_dict: 是否以字典方式返回False则以list返回
:param all_domains: 是否返回所有域的cookies :param all_domains: 是否返回所有域的cookies
@ -310,7 +313,7 @@ class SessionPage(BasePage):
parsed_url = urlparse(url) parsed_url = urlparse(url)
hostname = parsed_url.hostname hostname = parsed_url.hostname
scheme = parsed_url.scheme 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}' kwargs['headers']['Referer'] = self.url if self.url else f'{scheme}://{hostname}'
if 'Host' not in kwargs['headers']: if 'Host' not in kwargs['headers']:
kwargs['headers']['Host'] = hostname kwargs['headers']['Host'] = hostname
@ -364,10 +367,14 @@ class SessionPage(BasePage):
def __repr__(self): def __repr__(self):
return f'<SessionPage url={self.url}>' 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): def check_headers(kwargs, headers, arg):
"""检查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): def set_charset(response):

View File

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

View File

@ -126,11 +126,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
"""返回当前模式,'s''d' """ """返回当前模式,'s''d' """
return self._mode return self._mode
@property
def cookies(self):
"""以dict方式返回cookies"""
return super().cookies
@property @property
def user_agent(self): def user_agent(self):
"""返回user agent""" """返回user agent"""
@ -281,7 +276,9 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
if go: if go:
url = super(SessionPage, self).url url = super(SessionPage, self).url
if url.startswith('http'): 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): def cookies_to_session(self, copy_user_agent=True):
"""把driver对象的cookies复制到session对象 """把driver对象的cookies复制到session对象
@ -295,15 +292,15 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
user_agent = self.run_cdp('Runtime.evaluate', expression='navigator.userAgent;')['result']['value'] user_agent = self.run_cdp('Runtime.evaluate', expression='navigator.userAgent;')['result']['value']
self._headers.update({"User-Agent": user_agent}) 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): def cookies_to_browser(self):
"""把session对象的cookies复制到浏览器""" """把session对象的cookies复制到浏览器"""
if not self._has_driver: if not self._has_driver:
return 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 """返回cookies
:param as_dict: 是否以字典方式返回False以list形式返回 :param as_dict: 是否以字典方式返回False以list形式返回
:param all_domains: 是否返回所有域的cookies :param all_domains: 是否返回所有域的cookies
@ -311,9 +308,9 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
:return: cookies信息 :return: cookies信息
""" """
if self._mode == 's': 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': 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): def get_tab(self, id_or_num=None):
"""获取一个标签页对象 """获取一个标签页对象
@ -408,3 +405,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
def __repr__(self): def __repr__(self):
return f'<WebPage browser_id={self.browser.id} tab_id={self.tab_id}>' 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.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.none_element import NoneElement
from .._elements.session_element import SessionElement from .._elements.session_element import SessionElement
from .._units.setter import WebPageSetter from .._units.setter import WebPageSetter
@ -31,6 +30,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
chromium_options: Union[ChromiumOptions, bool] = None, chromium_options: Union[ChromiumOptions, bool] = None,
session_or_options: Union[Session, SessionOptions, bool] = None) -> None: session_or_options: Union[Session, SessionOptions, bool] = None) -> None:
self._mode: str = ... self._mode: str = ...
self._set: WebPageSetter = ...
self._has_driver: bool = ... self._has_driver: bool = ...
self._has_session: bool = ... self._has_session: bool = ...
self._session_options: Union[SessionOptions, None] = ... self._session_options: Union[SessionOptions, None] = ...
@ -39,7 +39,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
def __call__(self, def __call__(self,
locator: Union[Tuple[str, str], str, ChromiumElement, SessionElement], locator: Union[Tuple[str, str], str, ChromiumElement, SessionElement],
index: int = 1, index: int = 1,
timeout: float = None) -> Union[ChromiumElement, SessionElement, NoneElement]: ... timeout: float = None) -> Union[ChromiumElement, SessionElement]: ...
# -----------------共有属性和方法------------------- # -----------------共有属性和方法-------------------
@property @property
@ -66,9 +66,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
@property @property
def mode(self) -> str: ... def mode(self) -> str: ...
@property
def cookies(self) -> dict: ...
@property @property
def user_agent(self) -> str: ... def user_agent(self) -> str: ...
@ -107,7 +104,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
def ele(self, def ele(self,
locator: Union[Tuple[str, str], str, ChromiumElement, SessionElement], locator: Union[Tuple[str, str], str, ChromiumElement, SessionElement],
index: int = 1, index: int = 1,
timeout: float = None) -> Union[ChromiumElement, SessionElement, NoneElement]: ... timeout: float = None) -> Union[ChromiumElement, SessionElement]: ...
def eles(self, def eles(self,
locator: Union[Tuple[str, str], str], locator: Union[Tuple[str, str], str],
@ -115,7 +112,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
def s_ele(self, def s_ele(self,
locator: Union[Tuple[str, str], str] = None, 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]: ... 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 cookies_to_browser(self) -> None: ...
def get_cookies(self, def cookies(self,
as_dict: bool = False, as_dict: bool = False,
all_domains: bool = False, all_domains: bool = False,
all_info: bool = False) -> Union[dict, list]: ... all_info: bool = False) -> Union[dict, list]: ...
def get_tab(self, id_or_num: Union[str, WebPageTab, int] = None) -> WebPageTab: ... 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, index: Optional[int] = 1,
relative: bool = False, relative: bool = False,
raise_err: bool = None) \ raise_err: bool = None) \
-> Union[ChromiumElement, SessionElement, ChromiumFrame, NoneElement, List[SessionElement], -> Union[ChromiumElement, SessionElement, ChromiumFrame, List[SessionElement],
List[Union[ChromiumElement, ChromiumFrame]]]: ... List[Union[ChromiumElement, ChromiumFrame]]]: ...
def _set_start_options(self, def _set_start_options(self,

View File

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

View File

@ -100,6 +100,9 @@ class Listener(object):
Manifest, SignedExchange, Ping, CSPViolationReport, Preflight, Other Manifest, SignedExchange, Ping, CSPViolationReport, Preflight, Other
:return: None :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: if targets or is_regex is not None or method or res_type:
self.set_targets(targets, is_regex, method, res_type) self.set_targets(targets, is_regex, method, res_type)
self.clear() self.clear()

View File

@ -6,7 +6,7 @@
@License : BSD 3-Clause. @License : BSD 3-Clause.
""" """
from typing import Tuple, Union, List from typing import Tuple, Union
from .._elements.chromium_element import ChromiumElement from .._elements.chromium_element import ChromiumElement
from .._pages.chromium_base import ChromiumBase 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_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: ... 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_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, def cancel_by_option(self,
option: Union[ChromiumElement, List[ChromiumElement], Tuple[ChromiumElement]]) -> None: ... option: Union[ChromiumElement, List[ChromiumElement], Tuple[ChromiumElement]]) -> None: ...

View File

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

View File

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

View File

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

View File

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

View File

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