mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
Merge remote-tracking branch 'origin/dev' into dev
# Conflicts: # DrissionPage/_units/waiter.py
This commit is contained in:
commit
7c7ecc866c
@ -14,4 +14,4 @@ from ._pages.chromium_page import ChromiumPage
|
|||||||
from ._pages.mix_page import MixPage
|
from ._pages.mix_page import MixPage
|
||||||
from ._pages.mix_page import MixPage as WebPage
|
from ._pages.mix_page import MixPage as WebPage
|
||||||
|
|
||||||
__version__ = '4.1.0.0b11'
|
__version__ = '4.1.0.0b14'
|
||||||
|
@ -136,10 +136,11 @@ class DrissionElement(BaseElement):
|
|||||||
for x in self.eles('xpath:./text() | *')]
|
for x in self.eles('xpath:./text() | *')]
|
||||||
return [format_html(x.strip(' ').rstrip('\n')) for x in texts if x and sub('[\r\n\t ]', '', x) != '']
|
return [format_html(x.strip(' ').rstrip('\n')) for x in texts if x and sub('[\r\n\t ]', '', x) != '']
|
||||||
|
|
||||||
def parent(self, level_or_loc=1, index=1):
|
def parent(self, level_or_loc=1, index=1, timeout=None):
|
||||||
"""返回上面某一级父元素,可指定层数或用查询语法定位
|
"""返回上面某一级父元素,可指定层数或用查询语法定位
|
||||||
:param level_or_loc: 第几级父元素,1开始,或定位符
|
:param level_or_loc: 第几级父元素,1开始,或定位符
|
||||||
:param index: 当level_or_loc传入定位符,使用此参数选择第几个结果,1开始
|
:param index: 当level_or_loc传入定位符,使用此参数选择第几个结果,1开始
|
||||||
|
:param timeout: 时间(秒)
|
||||||
:return: 上级元素对象
|
:return: 上级元素对象
|
||||||
"""
|
"""
|
||||||
if isinstance(level_or_loc, int):
|
if isinstance(level_or_loc, int):
|
||||||
@ -154,7 +155,7 @@ class DrissionElement(BaseElement):
|
|||||||
else:
|
else:
|
||||||
raise TypeError('level_or_loc参数只能是tuple、int或str。')
|
raise TypeError('level_or_loc参数只能是tuple、int或str。')
|
||||||
|
|
||||||
return self._ele(loc, timeout=0, relative=True, raise_err=False, method='parent()')
|
return self._ele(loc, timeout=timeout, relative=True, raise_err=False, method='parent()')
|
||||||
|
|
||||||
def child(self, locator='', index=1, timeout=None, ele_only=True):
|
def child(self, locator='', index=1, timeout=None, ele_only=True):
|
||||||
"""返回直接子元素元素或节点组成的列表,可用查询语法筛选
|
"""返回直接子元素元素或节点组成的列表,可用查询语法筛选
|
||||||
|
@ -13,9 +13,10 @@ from DownloadKit import DownloadKit
|
|||||||
from .._elements.none_element import NoneElement
|
from .._elements.none_element import NoneElement
|
||||||
from .._elements.session_element import SessionElement
|
from .._elements.session_element import SessionElement
|
||||||
from .._functions.elements import SessionElementsList
|
from .._functions.elements import SessionElementsList
|
||||||
|
from .._pages.chromium_frame import ChromiumFrame
|
||||||
from .._pages.chromium_page import ChromiumPage
|
from .._pages.chromium_page import ChromiumPage
|
||||||
from .._pages.session_page import SessionPage
|
|
||||||
from .._pages.mix_page import MixPage
|
from .._pages.mix_page import MixPage
|
||||||
|
from .._pages.session_page import SessionPage
|
||||||
|
|
||||||
|
|
||||||
class BaseParser(object):
|
class BaseParser(object):
|
||||||
@ -82,6 +83,8 @@ class BaseElement(BaseParser):
|
|||||||
|
|
||||||
def nexts(self): ...
|
def nexts(self): ...
|
||||||
|
|
||||||
|
def get_frame(self, loc_or_ind, timeout=None) -> ChromiumFrame: ...
|
||||||
|
|
||||||
|
|
||||||
class DrissionElement(BaseElement):
|
class DrissionElement(BaseElement):
|
||||||
|
|
||||||
@ -103,7 +106,8 @@ class DrissionElement(BaseElement):
|
|||||||
|
|
||||||
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[DrissionElement, None]: ...
|
index: int = 1,
|
||||||
|
timeout: float = None) -> Union[DrissionElement, None]: ...
|
||||||
|
|
||||||
def child(self,
|
def child(self,
|
||||||
locator: Union[Tuple[str, str], str, int] = '',
|
locator: Union[Tuple[str, str], str, int] = '',
|
||||||
|
@ -81,7 +81,7 @@ class Chromium(object):
|
|||||||
self.address = self._chromium_options.address
|
self.address = self._chromium_options.address
|
||||||
self._driver = BrowserDriver(self.id, 'browser', self.address, self)
|
self._driver = BrowserDriver(self.id, 'browser', self.address, self)
|
||||||
|
|
||||||
if self.is_headless != self._chromium_options.is_headless or (
|
if (not self._chromium_options._ua_set and self.is_headless != self._chromium_options.is_headless) or (
|
||||||
self._is_exists and self._chromium_options._new_env):
|
self._is_exists and self._chromium_options._new_env):
|
||||||
self.quit(3, True)
|
self.quit(3, True)
|
||||||
connect_browser(self._chromium_options)
|
connect_browser(self._chromium_options)
|
||||||
|
@ -22,6 +22,7 @@ class ChromiumOptions(object):
|
|||||||
self._prefs_to_del = []
|
self._prefs_to_del = []
|
||||||
self.clear_file_flags = False
|
self.clear_file_flags = False
|
||||||
self._is_headless = False
|
self._is_headless = False
|
||||||
|
self._ua_set = False
|
||||||
|
|
||||||
if read_file is False:
|
if read_file is False:
|
||||||
ini_path = False
|
ini_path = False
|
||||||
|
@ -34,6 +34,7 @@ class ChromiumOptions(object):
|
|||||||
_retry_times: int = ...
|
_retry_times: int = ...
|
||||||
_retry_interval: float = ...
|
_retry_interval: float = ...
|
||||||
_is_headless: bool = ...
|
_is_headless: bool = ...
|
||||||
|
_ua_set: bool = ...
|
||||||
|
|
||||||
def __init__(self, read_file: [bool, None] = True, ini_path: Union[str, Path] = None): ...
|
def __init__(self, read_file: [bool, None] = True, ini_path: Union[str, Path] = None): ...
|
||||||
|
|
||||||
|
@ -232,13 +232,14 @@ class ChromiumElement(DrissionElement):
|
|||||||
if (is_checked and uncheck) or (not is_checked and not uncheck):
|
if (is_checked and uncheck) or (not is_checked and not uncheck):
|
||||||
self.click()
|
self.click()
|
||||||
|
|
||||||
def parent(self, level_or_loc=1, index=1):
|
def parent(self, level_or_loc=1, index=1, timeout=0):
|
||||||
"""返回上面某一级父元素,可指定层数或用查询语法定位
|
"""返回上面某一级父元素,可指定层数或用查询语法定位
|
||||||
:param level_or_loc: 第几级父元素,1开始,或定位符
|
:param level_or_loc: 第几级父元素,1开始,或定位符
|
||||||
:param index: 当level_or_loc传入定位符,使用此参数选择第几个结果,1开始
|
:param index: 当level_or_loc传入定位符,使用此参数选择第几个结果,1开始
|
||||||
|
:param timeout: 查找超时时间(秒)
|
||||||
:return: 上级元素对象
|
:return: 上级元素对象
|
||||||
"""
|
"""
|
||||||
return super().parent(level_or_loc, index)
|
return super().parent(level_or_loc, index, timeout=timeout)
|
||||||
|
|
||||||
def child(self, locator='', index=1, timeout=None, ele_only=True):
|
def child(self, locator='', index=1, timeout=None, ele_only=True):
|
||||||
"""返回当前元素的一个符合条件的直接子元素,可用查询语法筛选,可指定返回筛选结果的第几个
|
"""返回当前元素的一个符合条件的直接子元素,可用查询语法筛选,可指定返回筛选结果的第几个
|
||||||
@ -1041,10 +1042,11 @@ class ShadowRoot(BaseElement):
|
|||||||
Thread(target=run_js, args=(self, script, as_expr,
|
Thread(target=run_js, args=(self, script, as_expr,
|
||||||
self.owner.timeouts.script if timeout is None else timeout, args)).start()
|
self.owner.timeouts.script if timeout is None else timeout, args)).start()
|
||||||
|
|
||||||
def parent(self, level_or_loc=1, index=1):
|
def parent(self, level_or_loc=1, index=1, timeout=0):
|
||||||
"""返回上面某一级父元素,可指定层数或用查询语法定位
|
"""返回上面某一级父元素,可指定层数或用查询语法定位
|
||||||
:param level_or_loc: 第几级父元素,或定位符
|
:param level_or_loc: 第几级父元素,或定位符
|
||||||
:param index: 当level_or_loc传入定位符,使用此参数选择第几个结果
|
:param index: 当level_or_loc传入定位符,使用此参数选择第几个结果
|
||||||
|
:param timeout: 查找超时时间(秒)
|
||||||
:return: ChromiumElement对象
|
:return: ChromiumElement对象
|
||||||
"""
|
"""
|
||||||
if isinstance(level_or_loc, int):
|
if isinstance(level_or_loc, int):
|
||||||
@ -1061,12 +1063,13 @@ class ShadowRoot(BaseElement):
|
|||||||
else:
|
else:
|
||||||
raise TypeError('level_or_loc参数只能是tuple、int或str。')
|
raise TypeError('level_or_loc参数只能是tuple、int或str。')
|
||||||
|
|
||||||
return self.parent_ele._ele(loc, timeout=0, relative=True, raise_err=False, method='parent()')
|
return self.parent_ele._ele(loc, timeout=timeout, relative=True, raise_err=False, method='parent()')
|
||||||
|
|
||||||
def child(self, locator='', index=1):
|
def child(self, locator='', index=1, timeout=None):
|
||||||
"""返回直接子元素元素或节点组成的列表,可用查询语法筛选
|
"""返回直接子元素元素或节点组成的列表,可用查询语法筛选
|
||||||
:param locator: 用于筛选的查询语法
|
:param locator: 用于筛选的查询语法
|
||||||
:param index: 第几个查询结果,1开始
|
:param index: 第几个查询结果,1开始
|
||||||
|
:param timeout: 查找超时时间(秒)
|
||||||
:return: 直接子元素或节点文本组成的列表
|
:return: 直接子元素或节点文本组成的列表
|
||||||
"""
|
"""
|
||||||
if not locator:
|
if not locator:
|
||||||
@ -1078,14 +1081,16 @@ class ShadowRoot(BaseElement):
|
|||||||
loc = loc[1].lstrip('./')
|
loc = loc[1].lstrip('./')
|
||||||
|
|
||||||
loc = f'xpath:./{loc}'
|
loc = f'xpath:./{loc}'
|
||||||
ele = self._ele(loc, index=index, relative=True)
|
ele = self._ele(loc, index=index, relative=True, timeout=timeout)
|
||||||
|
|
||||||
return ele if ele else NoneElement(self.owner, 'child()', {'locator': locator, 'index': index})
|
return ele if ele else NoneElement(self.owner, 'child()',
|
||||||
|
{'locator': locator, 'index': index, 'timeout': timeout})
|
||||||
|
|
||||||
def next(self, locator='', index=1):
|
def next(self, locator='', index=1, timeout=None):
|
||||||
"""返回当前元素后面一个符合条件的同级元素,可用查询语法筛选,可指定返回筛选结果的第几个
|
"""返回当前元素后面一个符合条件的同级元素,可用查询语法筛选,可指定返回筛选结果的第几个
|
||||||
:param locator: 用于筛选的查询语法
|
:param locator: 用于筛选的查询语法
|
||||||
:param index: 第几个查询结果,1开始
|
:param index: 第几个查询结果,1开始
|
||||||
|
:param timeout: 查找超时时间(秒)
|
||||||
:return: ChromiumElement对象
|
:return: ChromiumElement对象
|
||||||
"""
|
"""
|
||||||
loc = get_loc(locator, True)
|
loc = get_loc(locator, True)
|
||||||
@ -1094,15 +1099,17 @@ class ShadowRoot(BaseElement):
|
|||||||
|
|
||||||
loc = loc[1].lstrip('./')
|
loc = loc[1].lstrip('./')
|
||||||
xpath = f'xpath:./{loc}'
|
xpath = f'xpath:./{loc}'
|
||||||
ele = self.parent_ele._ele(xpath, index=index, relative=True)
|
ele = self.parent_ele._ele(xpath, index=index, relative=True, timeout=timeout)
|
||||||
|
|
||||||
return ele if ele else NoneElement(self.owner, 'next()', {'locator': locator, 'index': index})
|
return ele if ele else NoneElement(self.owner, 'next()',
|
||||||
|
{'locator': locator, 'index': index, 'timeout': timeout})
|
||||||
|
|
||||||
def before(self, locator='', index=1):
|
def before(self, locator='', index=1, timeout=None):
|
||||||
"""返回文档中当前元素前面符合条件的一个元素,可用查询语法筛选,可指定返回筛选结果的第几个
|
"""返回文档中当前元素前面符合条件的一个元素,可用查询语法筛选,可指定返回筛选结果的第几个
|
||||||
查找范围不限同级元素,而是整个DOM文档
|
查找范围不限同级元素,而是整个DOM文档
|
||||||
:param locator: 用于筛选的查询语法
|
:param locator: 用于筛选的查询语法
|
||||||
:param index: 前面第几个查询结果,1开始
|
:param index: 前面第几个查询结果,1开始
|
||||||
|
:param timeout: 查找超时时间(秒)
|
||||||
:return: 本元素前面的某个元素或节点
|
:return: 本元素前面的某个元素或节点
|
||||||
"""
|
"""
|
||||||
loc = get_loc(locator, True)
|
loc = get_loc(locator, True)
|
||||||
@ -1111,23 +1118,27 @@ class ShadowRoot(BaseElement):
|
|||||||
|
|
||||||
loc = loc[1].lstrip('./')
|
loc = loc[1].lstrip('./')
|
||||||
xpath = f'xpath:./preceding::{loc}'
|
xpath = f'xpath:./preceding::{loc}'
|
||||||
ele = self.parent_ele._ele(xpath, index=index, relative=True)
|
ele = self.parent_ele._ele(xpath, index=index, relative=True, timeout=timeout)
|
||||||
|
|
||||||
return ele if ele else NoneElement(self.owner, 'before()', {'locator': locator, 'index': index})
|
return ele if ele else NoneElement(self.owner, 'before()',
|
||||||
|
{'locator': locator, 'index': index, 'timeout': timeout})
|
||||||
|
|
||||||
def after(self, locator='', index=1):
|
def after(self, locator='', index=1, timeout=None):
|
||||||
"""返回文档中此当前元素后面符合条件的一个元素,可用查询语法筛选,可指定返回筛选结果的第几个
|
"""返回文档中此当前元素后面符合条件的一个元素,可用查询语法筛选,可指定返回筛选结果的第几个
|
||||||
查找范围不限同级元素,而是整个DOM文档
|
查找范围不限同级元素,而是整个DOM文档
|
||||||
:param locator: 用于筛选的查询语法
|
:param locator: 用于筛选的查询语法
|
||||||
:param index: 后面第几个查询结果,1开始
|
:param index: 后面第几个查询结果,1开始
|
||||||
|
:param timeout: 查找超时时间(秒)
|
||||||
:return: 本元素后面的某个元素或节点
|
:return: 本元素后面的某个元素或节点
|
||||||
"""
|
"""
|
||||||
nodes = self.afters(locator=locator)
|
nodes = self.afters(locator=locator, timeout=timeout)
|
||||||
return nodes[index - 1] if nodes else NoneElement(self.owner, 'after()', {'locator': locator, 'index': index})
|
return nodes[index - 1] if nodes else NoneElement(self.owner, 'after()',
|
||||||
|
{'locator': locator, 'index': index, 'timeout': timeout})
|
||||||
|
|
||||||
def children(self, locator=''):
|
def children(self, locator='', timeout=None):
|
||||||
"""返回当前元素符合条件的直接子元素或节点组成的列表,可用查询语法筛选
|
"""返回当前元素符合条件的直接子元素或节点组成的列表,可用查询语法筛选
|
||||||
:param locator: 用于筛选的查询语法
|
:param locator: 用于筛选的查询语法
|
||||||
|
:param timeout: 查找超时时间(秒)
|
||||||
:return: 直接子元素或节点文本组成的列表
|
:return: 直接子元素或节点文本组成的列表
|
||||||
"""
|
"""
|
||||||
if not locator:
|
if not locator:
|
||||||
@ -1139,11 +1150,12 @@ class ShadowRoot(BaseElement):
|
|||||||
loc = loc[1].lstrip('./')
|
loc = loc[1].lstrip('./')
|
||||||
|
|
||||||
loc = f'xpath:./{loc}'
|
loc = f'xpath:./{loc}'
|
||||||
return self._ele(loc, index=None, relative=True)
|
return self._ele(loc, index=None, relative=True, timeout=timeout)
|
||||||
|
|
||||||
def nexts(self, locator=''):
|
def nexts(self, locator='', timeout=None):
|
||||||
"""返回当前元素后面符合条件的同级元素或节点组成的列表,可用查询语法筛选
|
"""返回当前元素后面符合条件的同级元素或节点组成的列表,可用查询语法筛选
|
||||||
:param locator: 用于筛选的查询语法
|
:param locator: 用于筛选的查询语法
|
||||||
|
:param timeout: 查找超时时间(秒)
|
||||||
:return: ChromiumElement对象组成的列表
|
:return: ChromiumElement对象组成的列表
|
||||||
"""
|
"""
|
||||||
loc = get_loc(locator, True)
|
loc = get_loc(locator, True)
|
||||||
@ -1152,12 +1164,13 @@ class ShadowRoot(BaseElement):
|
|||||||
|
|
||||||
loc = loc[1].lstrip('./')
|
loc = loc[1].lstrip('./')
|
||||||
xpath = f'xpath:./{loc}'
|
xpath = f'xpath:./{loc}'
|
||||||
return self.parent_ele._ele(xpath, index=None, relative=True)
|
return self.parent_ele._ele(xpath, index=None, relative=True, timeout=timeout)
|
||||||
|
|
||||||
def befores(self, locator=''):
|
def befores(self, locator='', timeout=None):
|
||||||
"""返回文档中当前元素前面符合条件的元素或节点组成的列表,可用查询语法筛选
|
"""返回文档中当前元素前面符合条件的元素或节点组成的列表,可用查询语法筛选
|
||||||
查找范围不限同级元素,而是整个DOM文档
|
查找范围不限同级元素,而是整个DOM文档
|
||||||
:param locator: 用于筛选的查询语法
|
:param locator: 用于筛选的查询语法
|
||||||
|
:param timeout: 查找超时时间(秒)
|
||||||
:return: 本元素前面的元素或节点组成的列表
|
:return: 本元素前面的元素或节点组成的列表
|
||||||
"""
|
"""
|
||||||
loc = get_loc(locator, True)
|
loc = get_loc(locator, True)
|
||||||
@ -1166,18 +1179,19 @@ class ShadowRoot(BaseElement):
|
|||||||
|
|
||||||
loc = loc[1].lstrip('./')
|
loc = loc[1].lstrip('./')
|
||||||
xpath = f'xpath:./preceding::{loc}'
|
xpath = f'xpath:./preceding::{loc}'
|
||||||
return self.parent_ele._ele(xpath, index=None, relative=True)
|
return self.parent_ele._ele(xpath, index=None, relative=True, timeout=timeout)
|
||||||
|
|
||||||
def afters(self, locator=''):
|
def afters(self, locator='', timeout=None):
|
||||||
"""返回文档中当前元素后面符合条件的元素或节点组成的列表,可用查询语法筛选
|
"""返回文档中当前元素后面符合条件的元素或节点组成的列表,可用查询语法筛选
|
||||||
查找范围不限同级元素,而是整个DOM文档
|
查找范围不限同级元素,而是整个DOM文档
|
||||||
:param locator: 用于筛选的查询语法
|
:param locator: 用于筛选的查询语法
|
||||||
|
:param timeout: 查找超时时间(秒)
|
||||||
:return: 本元素后面的元素或节点组成的列表
|
:return: 本元素后面的元素或节点组成的列表
|
||||||
"""
|
"""
|
||||||
eles1 = self.nexts(locator)
|
eles1 = self.nexts(locator)
|
||||||
loc = get_loc(locator, True)[1].lstrip('./')
|
loc = get_loc(locator, True)[1].lstrip('./')
|
||||||
xpath = f'xpath:./following::{loc}'
|
xpath = f'xpath:./following::{loc}'
|
||||||
return eles1 + self.parent_ele._ele(xpath, index=None, relative=True)
|
return eles1 + self.parent_ele._ele(xpath, index=None, relative=True, timeout=timeout)
|
||||||
|
|
||||||
def ele(self, locator, index=1, timeout=None):
|
def ele(self, locator, index=1, timeout=None):
|
||||||
"""返回当前元素下级符合条件的一个元素
|
"""返回当前元素下级符合条件的一个元素
|
||||||
@ -1251,7 +1265,10 @@ class ShadowRoot(BaseElement):
|
|||||||
css = []
|
css = []
|
||||||
for i in eles:
|
for i in eles:
|
||||||
c = i.css_path
|
c = i.css_path
|
||||||
if c.startswith('html:nth-child(1)>body:nth-child(1)>shadow_root:nth-child(1)'):
|
if c in ('html:nth-child(1)', 'html:nth-child(1)>body:nth-child(1)',
|
||||||
|
'html:nth-child(1)>body:nth-child(1)>shadow_root:nth-child(1)'):
|
||||||
|
continue
|
||||||
|
elif c.startswith('html:nth-child(1)>body:nth-child(1)>shadow_root:nth-child(1)'):
|
||||||
c = c[61:]
|
c = c[61:]
|
||||||
css.append(c)
|
css.append(c)
|
||||||
if index is not None:
|
if index is not None:
|
||||||
@ -1265,7 +1282,8 @@ class ShadowRoot(BaseElement):
|
|||||||
else:
|
else:
|
||||||
node_ids = [self.owner._run_cdp('DOM.querySelector', nodeId=self._node_id, selector=i)['nodeId']
|
node_ids = [self.owner._run_cdp('DOM.querySelector', nodeId=self._node_id, selector=i)['nodeId']
|
||||||
for i in css]
|
for i in css]
|
||||||
if 0 in node_ids:
|
node_ids = [i for i in node_ids if i]
|
||||||
|
if not node_ids:
|
||||||
return None
|
return None
|
||||||
r = make_chromium_eles(self.owner, _ids=node_ids, index=index, is_obj_id=False)
|
r = make_chromium_eles(self.owner, _ids=node_ids, index=index, is_obj_id=False)
|
||||||
return None if r is False else r
|
return None if r is False else r
|
||||||
@ -1476,6 +1494,8 @@ def make_chromium_eles(page, _ids, index=1, is_obj_id=True, ele_only=False):
|
|||||||
else: # 获取全部
|
else: # 获取全部
|
||||||
nodes = ChromiumElementsList(page=page)
|
nodes = ChromiumElementsList(page=page)
|
||||||
for obj_id in _ids:
|
for obj_id in _ids:
|
||||||
|
# if obj_id == 0:
|
||||||
|
# continue
|
||||||
tmp = get_node_func(page, obj_id, ele_only)
|
tmp = get_node_func(page, obj_id, ele_only)
|
||||||
if tmp is False:
|
if tmp is False:
|
||||||
return False
|
return False
|
||||||
|
@ -101,7 +101,8 @@ 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) -> ChromiumElement: ...
|
index: int = 1,
|
||||||
|
timeout: float = 0) -> ChromiumElement: ...
|
||||||
|
|
||||||
def child(self,
|
def child(self,
|
||||||
locator: Union[Tuple[str, str], str, int] = '',
|
locator: Union[Tuple[str, str], str, int] = '',
|
||||||
@ -309,31 +310,31 @@ class ShadowRoot(BaseElement):
|
|||||||
|
|
||||||
def run_async_js(self, script: str, *args, as_expr: bool = False, timeout: float = None) -> None: ...
|
def run_async_js(self, script: str, *args, as_expr: bool = False, timeout: float = None) -> None: ...
|
||||||
|
|
||||||
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, timeout: float = 0) -> ChromiumElement: ...
|
||||||
|
|
||||||
def child(self,
|
def child(self,
|
||||||
locator: Union[Tuple[str, str], str] = '',
|
locator: Union[Tuple[str, str], str] = '',
|
||||||
index: int = 1) -> ChromiumElement: ...
|
index: int = 1, timeout:float=None) -> ChromiumElement: ...
|
||||||
|
|
||||||
def next(self,
|
def next(self,
|
||||||
locator: Union[Tuple[str, str], str] = '',
|
locator: Union[Tuple[str, str], str] = '',
|
||||||
index: int = 1) -> ChromiumElement: ...
|
index: int = 1, timeout:float=None) -> ChromiumElement: ...
|
||||||
|
|
||||||
def before(self,
|
def before(self,
|
||||||
locator: Union[Tuple[str, str], str] = '',
|
locator: Union[Tuple[str, str], str] = '',
|
||||||
index: int = 1) -> ChromiumElement: ...
|
index: int = 1, timeout:float=None) -> ChromiumElement: ...
|
||||||
|
|
||||||
def after(self,
|
def after(self,
|
||||||
locator: Union[Tuple[str, str], str] = '',
|
locator: Union[Tuple[str, str], str] = '',
|
||||||
index: int = 1) -> ChromiumElement: ...
|
index: int = 1, timeout:float=None) -> ChromiumElement: ...
|
||||||
|
|
||||||
def children(self, locator: Union[Tuple[str, str], str] = '') -> List[ChromiumElement]: ...
|
def children(self, locator: Union[Tuple[str, str], str] = '', timeout:float=None) -> List[ChromiumElement]: ...
|
||||||
|
|
||||||
def nexts(self, locator: Union[Tuple[str, str], str] = '') -> List[ChromiumElement]: ...
|
def nexts(self, locator: Union[Tuple[str, str], str] = '', timeout:float=None) -> List[ChromiumElement]: ...
|
||||||
|
|
||||||
def befores(self, locator: Union[Tuple[str, str], str] = '') -> List[ChromiumElement]: ...
|
def befores(self, locator: Union[Tuple[str, str], str] = '', timeout:float=None) -> List[ChromiumElement]: ...
|
||||||
|
|
||||||
def afters(self, locator: Union[Tuple[str, str], str] = '') -> List[ChromiumElement]: ...
|
def afters(self, locator: Union[Tuple[str, str], str] = '', timeout:float=None) -> List[ChromiumElement]: ...
|
||||||
|
|
||||||
def ele(self,
|
def ele(self,
|
||||||
locator: Union[Tuple[str, str], str],
|
locator: Union[Tuple[str, str], str],
|
||||||
|
@ -81,6 +81,8 @@ def get_launch_args(opt):
|
|||||||
user_path = f'--user-data-dir={Path(i[16:]).absolute()}'
|
user_path = f'--user-data-dir={Path(i[16:]).absolute()}'
|
||||||
result.add(user_path)
|
result.add(user_path)
|
||||||
continue
|
continue
|
||||||
|
elif i.startswith('--user-agent='):
|
||||||
|
opt._ua_set = True
|
||||||
result.add(i)
|
result.add(i)
|
||||||
|
|
||||||
if not user_path and not opt.system_user_path:
|
if not user_path and not opt.system_user_path:
|
||||||
|
@ -170,6 +170,7 @@ class SessionFilter(SessionFilterOne):
|
|||||||
"""
|
"""
|
||||||
self._list = _text_all(self._list, SessionElementsList(page=self._list._page),
|
self._list = _text_all(self._list, SessionElementsList(page=self._list._page),
|
||||||
text=text, fuzzy=fuzzy, contain=contain)
|
text=text, fuzzy=fuzzy, contain=contain)
|
||||||
|
return self
|
||||||
|
|
||||||
def _get_attr(self, name, value, method, equal=True):
|
def _get_attr(self, name, value, method, equal=True):
|
||||||
"""返回通过某个方法可获得某个值的元素
|
"""返回通过某个方法可获得某个值的元素
|
||||||
@ -393,7 +394,7 @@ def get_eles(locators, owner, any_one=False, first_ele=True, timeout=10):
|
|||||||
for loc in locators:
|
for loc in locators:
|
||||||
if res[loc] is not False:
|
if res[loc] is not False:
|
||||||
continue
|
continue
|
||||||
ele = owner.ele(loc, timeout=0) if first_ele else owner.eles(loc, timeout=0)
|
ele = owner._ele(loc, timeout=0, raise_err=False, index=1 if first_ele else None)
|
||||||
if ele:
|
if ele:
|
||||||
res[loc] = ele
|
res[loc] = ele
|
||||||
if any_one:
|
if any_one:
|
||||||
|
@ -226,6 +226,8 @@ def raise_error(result, ignore=None, user=False):
|
|||||||
r = StorageError()
|
r = StorageError()
|
||||||
elif error == 'Sanitizing cookie failed':
|
elif error == 'Sanitizing cookie failed':
|
||||||
r = CookieFormatError(f'cookie格式不正确:{result["args"]}')
|
r = CookieFormatError(f'cookie格式不正确:{result["args"]}')
|
||||||
|
elif error == 'Invalid header name':
|
||||||
|
r = ValueError(f'header名不正确。\n参数:{result["args"]["headers"]}')
|
||||||
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"):
|
||||||
|
@ -136,7 +136,7 @@ def offset_scroll(ele, offset_x, offset_y):
|
|||||||
:param ele: 元素对象
|
:param ele: 元素对象
|
||||||
:param offset_x: 偏移量x
|
:param offset_x: 偏移量x
|
||||||
:param offset_y: 偏移量y
|
:param offset_y: 偏移量y
|
||||||
:return: 绝对坐标和相对坐标
|
:return: 相对坐标
|
||||||
"""
|
"""
|
||||||
loc_x, loc_y = ele.rect.location
|
loc_x, loc_y = ele.rect.location
|
||||||
cp_x, cp_y = ele.rect.click_point
|
cp_x, cp_y = ele.rect.click_point
|
||||||
@ -150,7 +150,7 @@ def offset_scroll(ele, offset_x, offset_y):
|
|||||||
ccp_x, ccp_y = ele.rect.viewport_click_point
|
ccp_x, ccp_y = ele.rect.viewport_click_point
|
||||||
cx = cl_x + offset_x if offset_x else ccp_x
|
cx = cl_x + offset_x if offset_x else ccp_x
|
||||||
cy = cl_y + offset_y if offset_y else ccp_y
|
cy = cl_y + offset_y if offset_y else ccp_y
|
||||||
return lx, ly, cx, cy
|
return cx, cy
|
||||||
|
|
||||||
|
|
||||||
def make_absolute_link(link, baseURI=None):
|
def make_absolute_link(link, baseURI=None):
|
||||||
@ -372,11 +372,15 @@ def format_headers(txt):
|
|||||||
"""
|
"""
|
||||||
if isinstance(txt, (dict, CaseInsensitiveDict)):
|
if isinstance(txt, (dict, CaseInsensitiveDict)):
|
||||||
for k, v in txt.items():
|
for k, v in txt.items():
|
||||||
txt[k] = str(v)
|
if k in (':method', ':scheme', ':authority', ':path'):
|
||||||
|
txt.pop(k)
|
||||||
|
else:
|
||||||
|
txt[k] = str(v)
|
||||||
return txt
|
return txt
|
||||||
headers = {}
|
headers = {}
|
||||||
for header in txt.split('\n'):
|
for header in txt.split('\n'):
|
||||||
if header:
|
if header:
|
||||||
name, value = header.split(': ', maxsplit=1)
|
name, value = header.split(': ', maxsplit=1)
|
||||||
headers[name] = value
|
if name not in (':method', ':scheme', ':authority', ':path'):
|
||||||
|
headers[name] = value
|
||||||
return headers
|
return headers
|
||||||
|
@ -24,7 +24,7 @@ def format_html(text: str) -> str: ...
|
|||||||
def location_in_viewport(page: ChromiumBase, loc_x: float, loc_y: float) -> bool: ...
|
def location_in_viewport(page: ChromiumBase, loc_x: float, loc_y: float) -> bool: ...
|
||||||
|
|
||||||
|
|
||||||
def offset_scroll(ele: ChromiumElement, offset_x: float, offset_y: float) -> Tuple[int, int, int, int]: ...
|
def offset_scroll(ele: ChromiumElement, offset_x: float, offset_y: float) -> Tuple[int, int]: ...
|
||||||
|
|
||||||
|
|
||||||
def make_absolute_link(link: str, baseURI: str = None) -> str: ...
|
def make_absolute_link(link: str, baseURI: str = None) -> str: ...
|
||||||
|
@ -10,6 +10,7 @@ from re import search, findall, DOTALL
|
|||||||
from time import sleep, perf_counter
|
from time import sleep, perf_counter
|
||||||
|
|
||||||
from .._elements.chromium_element import ChromiumElement
|
from .._elements.chromium_element import ChromiumElement
|
||||||
|
from .._functions.settings import Settings
|
||||||
from .._pages.chromium_base import ChromiumBase
|
from .._pages.chromium_base import ChromiumBase
|
||||||
from .._units.listener import FrameListener
|
from .._units.listener import FrameListener
|
||||||
from .._units.rect import FrameRect
|
from .._units.rect import FrameRect
|
||||||
@ -21,6 +22,24 @@ from ..errors import ContextLostError, ElementLostError, PageDisconnectedError,
|
|||||||
|
|
||||||
|
|
||||||
class ChromiumFrame(ChromiumBase):
|
class ChromiumFrame(ChromiumBase):
|
||||||
|
_Frames = {}
|
||||||
|
|
||||||
|
def __new__(cls, owner, ele, info=None):
|
||||||
|
"""
|
||||||
|
:param owner: frame所在的页面对象
|
||||||
|
:param ele: frame所在元素
|
||||||
|
:param info: frame所在元素信息
|
||||||
|
"""
|
||||||
|
node = info['node'] if info else owner._run_cdp('DOM.describeNode', backendNodeId=ele._backend_id)['node']
|
||||||
|
if Settings.singleton_tab_obj and node['frameId'] in cls._Frames:
|
||||||
|
r = cls._Frames[node['frameId']]
|
||||||
|
while not hasattr(r, '_frame_id'):
|
||||||
|
sleep(.1)
|
||||||
|
return r
|
||||||
|
r = object.__new__(cls)
|
||||||
|
cls._Frames[node['frameId']] = r
|
||||||
|
return r
|
||||||
|
|
||||||
def __init__(self, owner, ele, info=None):
|
def __init__(self, owner, ele, info=None):
|
||||||
"""
|
"""
|
||||||
:param owner: frame所在的页面对象
|
:param owner: frame所在的页面对象
|
||||||
@ -33,7 +52,7 @@ class ChromiumFrame(ChromiumBase):
|
|||||||
self._frame_ele = ele
|
self._frame_ele = ele
|
||||||
self._reloading = False
|
self._reloading = False
|
||||||
|
|
||||||
node = info['node'] if not info else owner._run_cdp('DOM.describeNode', backendNodeId=ele._backend_id)['node']
|
node = info['node'] if info else owner._run_cdp('DOM.describeNode', backendNodeId=ele._backend_id)['node']
|
||||||
self._frame_id = node['frameId']
|
self._frame_id = node['frameId']
|
||||||
if self._is_inner_frame():
|
if self._is_inner_frame():
|
||||||
self._is_diff_domain = False
|
self._is_diff_domain = False
|
||||||
@ -175,6 +194,7 @@ class ChromiumFrame(ChromiumBase):
|
|||||||
def _onFrameDetached(self, **kwargs):
|
def _onFrameDetached(self, **kwargs):
|
||||||
"""同域变异域"""
|
"""同域变异域"""
|
||||||
self.browser._frames.pop(kwargs['frameId'], None)
|
self.browser._frames.pop(kwargs['frameId'], None)
|
||||||
|
ChromiumFrame._Frames.pop(kwargs['frameId'], None)
|
||||||
if kwargs['frameId'] == self._frame_id:
|
if kwargs['frameId'] == self._frame_id:
|
||||||
self._reload()
|
self._reload()
|
||||||
|
|
||||||
@ -385,13 +405,14 @@ class ChromiumFrame(ChromiumBase):
|
|||||||
else:
|
else:
|
||||||
return self.doc_ele._run_js(script, *args, as_expr=as_expr, timeout=timeout)
|
return self.doc_ele._run_js(script, *args, as_expr=as_expr, timeout=timeout)
|
||||||
|
|
||||||
def parent(self, level_or_loc=1, index=1):
|
def parent(self, level_or_loc=1, index=1, timeout=0):
|
||||||
"""返回上面某一级父元素,可指定层数或用查询语法定位
|
"""返回上面某一级父元素,可指定层数或用查询语法定位
|
||||||
:param level_or_loc: 第几级父元素,1开始,或定位符
|
:param level_or_loc: 第几级父元素,1开始,或定位符
|
||||||
:param index: 当level_or_loc传入定位符,使用此参数选择第几个结果,1开始
|
:param index: 当level_or_loc传入定位符,使用此参数选择第几个结果,1开始
|
||||||
|
:param timeout: 查找超时时间(秒)
|
||||||
:return: 上级元素对象
|
:return: 上级元素对象
|
||||||
"""
|
"""
|
||||||
return self.frame_ele.parent(level_or_loc, index)
|
return self.frame_ele.parent(level_or_loc, index, timeout=timeout)
|
||||||
|
|
||||||
def prev(self, locator='', index=1, timeout=0, ele_only=True):
|
def prev(self, locator='', index=1, timeout=0, ele_only=True):
|
||||||
"""返回当前元素前面一个符合条件的同级元素,可用查询语法筛选,可指定返回筛选结果的第几个
|
"""返回当前元素前面一个符合条件的同级元素,可用查询语法筛选,可指定返回筛选结果的第几个
|
||||||
|
@ -21,6 +21,7 @@ from .._units.waiter import FrameWaiter
|
|||||||
|
|
||||||
|
|
||||||
class ChromiumFrame(ChromiumBase):
|
class ChromiumFrame(ChromiumBase):
|
||||||
|
_Frames: dict = ...
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
owner: Union[ChromiumTab, ChromiumFrame],
|
owner: Union[ChromiumTab, ChromiumFrame],
|
||||||
@ -156,7 +157,8 @@ class ChromiumFrame(ChromiumBase):
|
|||||||
|
|
||||||
def parent(self,
|
def parent(self,
|
||||||
level_or_loc: Union[Tuple[str, str], str, int] = 1,
|
level_or_loc: Union[Tuple[str, str], str, int] = 1,
|
||||||
index: int = 1) -> ChromiumElement: ...
|
index: int = 1,
|
||||||
|
timeout: float = 0) -> ChromiumElement: ...
|
||||||
|
|
||||||
def prev(self,
|
def prev(self,
|
||||||
locator: Union[Tuple[str, str], str, int] = '',
|
locator: Union[Tuple[str, str], str, int] = '',
|
||||||
|
@ -91,16 +91,13 @@ class Clicker(object):
|
|||||||
includeUserAgentShadowDOM=True, ignorePointerEventsNone=True)
|
includeUserAgentShadowDOM=True, ignorePointerEventsNone=True)
|
||||||
if r['backendNodeId'] != self._ele._backend_id:
|
if r['backendNodeId'] != self._ele._backend_id:
|
||||||
vx, vy = self._ele.rect.viewport_midpoint
|
vx, vy = self._ele.rect.viewport_midpoint
|
||||||
lx, ly = self._ele.rect._get_page_coord(vx, vy)
|
|
||||||
else:
|
else:
|
||||||
vx, vy = self._ele.rect.viewport_click_point
|
vx, vy = self._ele.rect.viewport_click_point
|
||||||
lx, ly = self._ele.rect._get_page_coord(vx, vy)
|
|
||||||
|
|
||||||
except CDPError:
|
except CDPError:
|
||||||
vx, vy = self._ele.rect.viewport_midpoint
|
vx, vy = self._ele.rect.viewport_midpoint
|
||||||
lx, ly = self._ele.rect._get_page_coord(vx, vy)
|
|
||||||
|
|
||||||
self._click(lx, ly, vx, vy)
|
self._click(vx, vy)
|
||||||
return self._ele
|
return self._ele
|
||||||
|
|
||||||
if by_js is not False:
|
if by_js is not False:
|
||||||
@ -113,7 +110,7 @@ class Clicker(object):
|
|||||||
def right(self):
|
def right(self):
|
||||||
"""右键单击"""
|
"""右键单击"""
|
||||||
self._ele.owner.scroll.to_see(self._ele)
|
self._ele.owner.scroll.to_see(self._ele)
|
||||||
return self._click(*self._ele.rect.click_point, *self._ele.rect.viewport_click_point, button='right')
|
return self._click(*self._ele.rect.viewport_click_point, button='right')
|
||||||
|
|
||||||
def middle(self, get_tab=True):
|
def middle(self, get_tab=True):
|
||||||
"""中键单击,默认返回新出现的tab对象
|
"""中键单击,默认返回新出现的tab对象
|
||||||
@ -122,7 +119,7 @@ class Clicker(object):
|
|||||||
"""
|
"""
|
||||||
self._ele.owner.scroll.to_see(self._ele)
|
self._ele.owner.scroll.to_see(self._ele)
|
||||||
curr_tid = self._ele.tab.browser.tab_ids[0]
|
curr_tid = self._ele.tab.browser.tab_ids[0]
|
||||||
self._click(*self._ele.rect.click_point, *self._ele.rect.viewport_click_point, button='middle')
|
self._click(*self._ele.rect.viewport_click_point, button='middle')
|
||||||
if get_tab:
|
if get_tab:
|
||||||
tid = self._ele.tab.browser.wait.new_tab(curr_tab=curr_tid)
|
tid = self._ele.tab.browser.wait.new_tab(curr_tab=curr_tid)
|
||||||
if not tid:
|
if not tid:
|
||||||
@ -226,17 +223,14 @@ class Clicker(object):
|
|||||||
self.left(by_js=by_js)
|
self.left(by_js=by_js)
|
||||||
return True if self._ele.tab.wait.title_change(text=text, exclude=exclude, timeout=timeout) else False
|
return True if self._ele.tab.wait.title_change(text=text, exclude=exclude, timeout=timeout) else False
|
||||||
|
|
||||||
def _click(self, loc_x, loc_y, view_x, view_y, button='left', count=1):
|
def _click(self, view_x, view_y, button='left', count=1):
|
||||||
"""实施点击
|
"""实施点击
|
||||||
:param loc_x: 绝对x坐标
|
|
||||||
:param loc_y: 绝对y坐标
|
|
||||||
:param view_x: 视口x坐标
|
:param view_x: 视口x坐标
|
||||||
:param view_y: 视口y坐标
|
:param view_y: 视口y坐标
|
||||||
:param button: 'left' 'right' 'middle' 'back' 'forward'
|
:param button: 'left' 'right' 'middle' 'back' 'forward'
|
||||||
:param count: 点击次数
|
:param count: 点击次数
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
self._ele.owner.actions.move_to((loc_x, loc_y), duration=.05)
|
|
||||||
self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mousePressed', x=view_x,
|
self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mousePressed', x=view_x,
|
||||||
y=view_y, button=button, clickCount=count, _ignore=AlertExistsError)
|
y=view_y, button=button, clickCount=count, _ignore=AlertExistsError)
|
||||||
self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mouseReleased', x=view_x,
|
self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mouseReleased', x=view_x,
|
||||||
|
@ -53,8 +53,7 @@ class Clicker(object):
|
|||||||
def for_title_change(self, text: str = None, exclude: bool = False,
|
def for_title_change(self, text: str = None, exclude: bool = False,
|
||||||
by_js: bool = False, timeout: float = None) -> bool: ...
|
by_js: bool = False, timeout: float = None) -> bool: ...
|
||||||
|
|
||||||
def _click(self, loc_x: float,
|
def _click(self,
|
||||||
loc_y: float,
|
|
||||||
view_x: float,
|
view_x: float,
|
||||||
view_y: float,
|
view_y: float,
|
||||||
button: str = 'left',
|
button: str = 'left',
|
||||||
|
@ -428,6 +428,34 @@ class TabSetter(ChromiumBaseSetter):
|
|||||||
|
|
||||||
class ChromiumPageSetter(TabSetter):
|
class ChromiumPageSetter(TabSetter):
|
||||||
|
|
||||||
|
def NoneElement_value(self, value=None, on_off=True):
|
||||||
|
"""设置空元素是否返回设定值
|
||||||
|
:param value: 返回的设定值
|
||||||
|
:param on_off: 是否启用
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
super().NoneElement_value(value, on_off)
|
||||||
|
self._owner.browser._none_ele_return_value = on_off
|
||||||
|
self._owner.browser._none_ele_value = value
|
||||||
|
|
||||||
|
def retry_times(self, times):
|
||||||
|
"""设置连接失败重连次数"""
|
||||||
|
super().retry_times(times)
|
||||||
|
self._owner.browser.retry_times = times
|
||||||
|
|
||||||
|
def retry_interval(self, interval):
|
||||||
|
"""设置连接失败重连间隔"""
|
||||||
|
super().retry_interval(interval)
|
||||||
|
self._owner.browser.retry_interval = interval
|
||||||
|
|
||||||
|
def download_path(self, path):
|
||||||
|
"""设置下载路径
|
||||||
|
:param path: 下载路径
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
super().download_path(path)
|
||||||
|
self._owner.browser._download_path = self._owner._download_path
|
||||||
|
|
||||||
def auto_handle_alert(self, on_off=True, accept=True, all_tabs=False):
|
def auto_handle_alert(self, on_off=True, accept=True, all_tabs=False):
|
||||||
"""设置是否启用自动处理弹窗
|
"""设置是否启用自动处理弹窗
|
||||||
:param on_off: bool表示开或关
|
:param on_off: bool表示开或关
|
||||||
@ -625,18 +653,20 @@ class LoadMode(object):
|
|||||||
if value.lower() not in ('normal', 'eager', 'none'):
|
if value.lower() not in ('normal', 'eager', 'none'):
|
||||||
raise ValueError("只能选择 'normal', 'eager', 'none'。")
|
raise ValueError("只能选择 'normal', 'eager', 'none'。")
|
||||||
self._owner._load_mode = value
|
self._owner._load_mode = value
|
||||||
|
if self._owner._type in ('ChromiumPage', 'MixPage'):
|
||||||
|
self._owner.browser._load_mode = value
|
||||||
|
|
||||||
def normal(self):
|
def normal(self):
|
||||||
"""设置页面加载策略为normal"""
|
"""设置页面加载策略为normal"""
|
||||||
self._owner._load_mode = 'normal'
|
self.__call__('normal')
|
||||||
|
|
||||||
def eager(self):
|
def eager(self):
|
||||||
"""设置页面加载策略为eager"""
|
"""设置页面加载策略为eager"""
|
||||||
self._owner._load_mode = 'eager'
|
self.__call__('eager')
|
||||||
|
|
||||||
def none(self):
|
def none(self):
|
||||||
"""设置页面加载策略为none"""
|
"""设置页面加载策略为none"""
|
||||||
self._owner._load_mode = 'none'
|
self.__call__('none')
|
||||||
|
|
||||||
|
|
||||||
class PageScrollSetter(object):
|
class PageScrollSetter(object):
|
||||||
@ -740,6 +770,7 @@ class WindowSetter(object):
|
|||||||
return self._owner._run_cdp('Browser.getWindowForTarget')
|
return self._owner._run_cdp('Browser.getWindowForTarget')
|
||||||
except:
|
except:
|
||||||
sleep(.1)
|
sleep(.1)
|
||||||
|
raise RuntimeError('获取窗口信息失败。')
|
||||||
|
|
||||||
def _perform(self, bounds):
|
def _perform(self, bounds):
|
||||||
"""执行改变窗口大小操作
|
"""执行改变窗口大小操作
|
||||||
|
@ -35,16 +35,19 @@ class BrowserWaiter(OriginWaiter):
|
|||||||
def new_tab(self, timeout=None, curr_tab=None, raise_err=None):
|
def new_tab(self, timeout=None, curr_tab=None, raise_err=None):
|
||||||
"""等待新标签页出现
|
"""等待新标签页出现
|
||||||
:param timeout: 超时时间(秒),为None则使用页面对象timeout属性
|
:param timeout: 超时时间(秒),为None则使用页面对象timeout属性
|
||||||
:param curr_tab: 指定当前最新的tab id,用于判断新tab出现,为None自动获取
|
:param curr_tab: 指定当前最新的tab对象或tab id,用于判断新tab出现,为None自动获取
|
||||||
:param raise_err: 等待失败时是否报错,为None时根据Settings设置
|
:param raise_err: 等待失败时是否报错,为None时根据Settings设置
|
||||||
:return: 等到新标签页返回其id,否则返回False
|
:return: 等到新标签页返回其id,否则返回False
|
||||||
"""
|
"""
|
||||||
curr_tid = curr_tab if curr_tab else self._owner.tab_ids[0]
|
if not curr_tab:
|
||||||
|
curr_tab = self._owner.tab_ids[0]
|
||||||
|
elif hasattr(curr_tab, '_type'):
|
||||||
|
curr_tab = curr_tab.tab_id
|
||||||
timeout = timeout if timeout is not None else self._owner.timeout
|
timeout = timeout if timeout is not None else self._owner.timeout
|
||||||
end_time = perf_counter() + timeout
|
end_time = perf_counter() + timeout
|
||||||
while perf_counter() < end_time:
|
while perf_counter() < end_time:
|
||||||
latest_tid = self._owner.tab_ids[0]
|
latest_tid = self._owner.tab_ids[0]
|
||||||
if curr_tid != latest_tid:
|
if curr_tab != latest_tid:
|
||||||
return latest_tid
|
return latest_tid
|
||||||
sleep(.01)
|
sleep(.01)
|
||||||
|
|
||||||
@ -130,7 +133,7 @@ class BaseWaiter(OriginWaiter):
|
|||||||
end_time = perf_counter() + timeout
|
end_time = perf_counter() + timeout
|
||||||
ele = self._owner._ele(loc_or_ele, raise_err=False, timeout=timeout)
|
ele = self._owner._ele(loc_or_ele, raise_err=False, timeout=timeout)
|
||||||
timeout = end_time - perf_counter()
|
timeout = end_time - perf_counter()
|
||||||
if not ele:
|
if timeout <= 0 or not ele:
|
||||||
if raise_err is True or Settings.raise_when_wait_failed is True:
|
if raise_err is True or Settings.raise_when_wait_failed is True:
|
||||||
raise WaitTimeoutError(f'等待元素显示失败(等待{timeout}秒)。')
|
raise WaitTimeoutError(f'等待元素显示失败(等待{timeout}秒)。')
|
||||||
else:
|
else:
|
||||||
@ -193,7 +196,7 @@ class BaseWaiter(OriginWaiter):
|
|||||||
by = ('id', 'xpath', 'link text', 'partial link text', 'name', 'tag name', 'class name', 'css selector')
|
by = ('id', 'xpath', 'link text', 'partial link text', 'name', 'tag name', 'class name', 'css selector')
|
||||||
locators = ((get_loc(locators)[1],) if (isinstance(locators, str) or isinstance(locators, tuple)
|
locators = ((get_loc(locators)[1],) if (isinstance(locators, str) or isinstance(locators, tuple)
|
||||||
and locators[0] in by and len(locators) == 2)
|
and locators[0] in by and len(locators) == 2)
|
||||||
else [get_loc(l)[1] for l in locators])
|
else [get_loc(x)[1] for x in locators])
|
||||||
method = any if any_one else all
|
method = any if any_one else all
|
||||||
|
|
||||||
timeout = self._owner.timeout if timeout is None else timeout
|
timeout = self._owner.timeout if timeout is None else timeout
|
||||||
@ -321,7 +324,8 @@ class BaseWaiter(OriginWaiter):
|
|||||||
:param raise_err: 等待失败时是否报错,为None时根据Settings设置
|
:param raise_err: 等待失败时是否报错,为None时根据Settings设置
|
||||||
:return: 是否等待成功
|
:return: 是否等待成功
|
||||||
"""
|
"""
|
||||||
timeout = timeout if timeout is not None else self._owner.timeout
|
if timeout is None:
|
||||||
|
timeout = self._owner.timeout
|
||||||
timeout = .1 if timeout <= 0 else timeout
|
timeout = .1 if timeout <= 0 else timeout
|
||||||
end_time = perf_counter() + timeout
|
end_time = perf_counter() + timeout
|
||||||
while perf_counter() < end_time:
|
while perf_counter() < end_time:
|
||||||
@ -527,7 +531,8 @@ class ElementWaiter(OriginWaiter):
|
|||||||
:param raise_err: 等待失败时是否报错,为None时根据Settings设置
|
:param raise_err: 等待失败时是否报错,为None时根据Settings设置
|
||||||
:return: 成功返回元素对象,失败返回False
|
:return: 成功返回元素对象,失败返回False
|
||||||
"""
|
"""
|
||||||
timeout = timeout if timeout is not None else self._timeout
|
if timeout is None:
|
||||||
|
timeout = self._timeout
|
||||||
t1 = perf_counter()
|
t1 = perf_counter()
|
||||||
r = self._wait_state('is_clickable', True, timeout, raise_err, err_text='等待元素可点击失败(等{}秒)。')
|
r = self._wait_state('is_clickable', True, timeout, raise_err, err_text='等待元素可点击失败(等{}秒)。')
|
||||||
r = self.stop_moving(timeout=timeout - perf_counter() + t1) if wait_moved and r else r
|
r = self.stop_moving(timeout=timeout - perf_counter() + t1) if wait_moved and r else r
|
||||||
|
@ -34,7 +34,10 @@ class BrowserWaiter(OriginWaiter):
|
|||||||
|
|
||||||
def download_begin(self, timeout: float = None, cancel_it: bool = False) -> DownloadMission: ...
|
def download_begin(self, timeout: float = None, cancel_it: bool = False) -> DownloadMission: ...
|
||||||
|
|
||||||
def new_tab(self, timeout: float = None, curr_tab: str = None, raise_err: bool = None) -> Union[str, bool]: ...
|
def new_tab(self,
|
||||||
|
timeout: float = None,
|
||||||
|
curr_tab: Union[str, ChromiumTab] = None,
|
||||||
|
raise_err: bool = None) -> Union[str, bool]: ...
|
||||||
|
|
||||||
def all_downloads_done(self, timeout: float = None, cancel_if_timeout: bool = True) -> bool: ...
|
def all_downloads_done(self, timeout: float = None, cancel_if_timeout: bool = True) -> bool: ...
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user