一些修改(+)

增加Settings.browser_connect_timeout属性;
优化关闭标签页逻辑;
修复下载路径设置问题;
点击产生的新标签页下载任务可用原标签页等待;
remove_attr()返回元素自身;
select各种方法返回元素本身,找不到项时报错;
This commit is contained in:
g1879 2024-10-21 07:10:10 +08:00
parent 8d37aa079e
commit 4407a0daa1
19 changed files with 130 additions and 114 deletions

View File

@ -65,7 +65,6 @@ class Chromium(object):
self._drivers = {} self._drivers = {}
self._all_drivers = {} self._all_drivers = {}
self._newest_tab_id = None self._newest_tab_id = None
self._tab_to_close = set()
self._set = None self._set = None
self._wait = None self._wait = None
@ -204,18 +203,19 @@ class Chromium(object):
all_tabs = set(self.tab_ids) all_tabs = set(self.tab_ids)
if others: if others:
tabs = all_tabs - tabs tabs = all_tabs - tabs
if len(all_tabs - tabs) <= 0:
self.quit()
return
for tab in tabs:
self._close_tab(tab_id=tab)
def _close_tab(self, tab_id): if len(all_tabs - tabs) > 0:
# self._onTargetDestroyed(targetId=tab) for tab in tabs:
self._tab_to_close.add(tab_id) self._close_tab(tab=tab)
self._driver.run('Target.closeTarget', targetId=tab_id) else:
while tab_id in self._tab_to_close: self.quit()
sleep(.2)
def _close_tab(self, tab):
if isinstance(tab, str):
tab = self.get_tab(tab)
tab._run_cdp('Target.closeTarget', targetId=tab.tab_id)
while tab.driver.is_running and tab.tab_id in self._all_drivers:
sleep(.01)
def activate_tab(self, id_ind_tab): def activate_tab(self, id_ind_tab):
if isinstance(id_ind_tab, int): if isinstance(id_ind_tab, int):
@ -396,16 +396,14 @@ class Chromium(object):
pass pass
def _onTargetDestroyed(self, **kwargs): def _onTargetDestroyed(self, **kwargs):
with self._lock: tab_id = kwargs['targetId']
tab_id = kwargs['targetId'] self._dl_mgr.clear_tab_info(tab_id)
self._dl_mgr.clear_tab_info(tab_id) for key in [k for k, i in self._frames.items() if i == tab_id]:
for key in [k for k, i in self._frames.items() if i == tab_id]: self._frames.pop(key, None)
self._frames.pop(key, None) for d in self._all_drivers.get(tab_id, tuple()):
for d in self._all_drivers.get(tab_id, tuple()): d.stop()
d.stop() self._drivers.pop(tab_id, None)
self._drivers.pop(tab_id, None) self._all_drivers.pop(tab_id, None)
self._all_drivers.pop(tab_id, None)
self._tab_to_close.discard(tab_id)
def _on_disconnect(self): def _on_disconnect(self):
if not self._disconnect_flag: if not self._disconnect_flag:

View File

@ -12,7 +12,7 @@ from .driver import BrowserDriver, 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 .._functions.cookies import CookiesList from .._functions.cookies import CookiesList
from .._pages.chromium_base import Timeout from .._pages.chromium_base import Timeout, ChromiumBase
from .._pages.chromium_tab import ChromiumTab from .._pages.chromium_tab import ChromiumTab
from .._pages.mix_tab import MixTab from .._pages.mix_tab import MixTab
from .._units.downloader import DownloadManager from .._units.downloader import DownloadManager
@ -52,7 +52,6 @@ class Chromium(object):
_none_ele_return_value: bool = ... _none_ele_return_value: bool = ...
_none_ele_value: Any = ... _none_ele_value: Any = ...
_newest_tab_id: Optional[str] = ... _newest_tab_id: Optional[str] = ...
_tab_to_close: set = ...
def __new__(cls, def __new__(cls,
addr_or_opts: Union[str, int, ChromiumOptions] = None, addr_or_opts: Union[str, int, ChromiumOptions] = None,
@ -194,9 +193,9 @@ class Chromium(object):
""" """
... ...
def _close_tab(self, tab_id: str): def _close_tab(self, tab: Union[ChromiumBase, str]):
"""关闭一个标签页 """关闭一个标签页
:param tab_id: 标签页id :param tab: 标签页对象或id
:return: None :return: None
""" """

View File

@ -336,7 +336,7 @@ class ChromiumOptions(object):
return self return self
def set_address(self, address): def set_address(self, address):
address = address.replace('localhost', '127.0.0.1').lstrip('http://').lstrip('https://') address = address.replace('localhost', '127.0.0.1').lstrip('htps:/')
self._address = address self._address = address
return self return self

View File

@ -204,6 +204,8 @@ 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()
return self
def parent(self, level_or_loc=1, index=1, timeout=0): def parent(self, level_or_loc=1, index=1, timeout=0):
return super().parent(level_or_loc, index, timeout=timeout) return super().parent(level_or_loc, index, timeout=timeout)
@ -399,6 +401,7 @@ class ChromiumElement(DrissionElement):
def remove_attr(self, name): def remove_attr(self, name):
self._run_js(f'this.removeAttribute("{name}");') self._run_js(f'this.removeAttribute("{name}");')
return self
def property(self, name): def property(self, name):
try: try:
@ -555,7 +558,7 @@ class ChromiumElement(DrissionElement):
vals = ''.join([str(i) for i in vals]) vals = ''.join([str(i) for i in vals])
self.set.property('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 self
self.wait.clickable(wait_moved=False, timeout=.5) self.wait.clickable(wait_moved=False, timeout=.5)
if clear and vals not in ('\n', '\ue007'): if clear and vals not in ('\n', '\ue007'):
@ -575,7 +578,7 @@ class ChromiumElement(DrissionElement):
if by_js: if by_js:
self._run_js("this.value='';") self._run_js("this.value='';")
self._run_js('this.dispatchEvent(new Event("change", {bubbles: true}));') self._run_js('this.dispatchEvent(new Event("change", {bubbles: true}));')
return return self
self._input_focus() self._input_focus()
self.input(('\ue009', 'a', '\ue017'), clear=False) self.input(('\ue009', 'a', '\ue017'), clear=False)

View File

@ -377,7 +377,7 @@ class ChromiumElement(DrissionElement):
""" """
... ...
def remove_attr(self, name: str) -> None: def remove_attr(self, name: str) -> ChromiumElement:
"""删除元素一个attribute属性 """删除元素一个attribute属性
:param name: 属性名 :param name: 属性名
:return: None :return: None

View File

@ -15,6 +15,7 @@ from time import perf_counter, sleep
from requests import Session from requests import Session
from .settings import Settings
from .tools import port_is_using from .tools import port_is_using
from .._configs.options_manage import OptionsManager from .._configs.options_manage import OptionsManager
from ..errors import BrowserConnectError from ..errors import BrowserConnectError
@ -168,8 +169,8 @@ def set_flags(opt):
dump(states_dict, f) dump(states_dict, f)
def test_connect(ip, port, timeout=30): def test_connect(ip, port):
end_time = perf_counter() + timeout end_time = perf_counter() + Settings.browser_connect_timeout
s = Session() s = Session()
s.trust_env = False s.trust_env = False
s.keep_alive = False s.keep_alive = False

View File

@ -14,6 +14,7 @@ class Settings(object):
raise_when_wait_failed = False raise_when_wait_failed = False
singleton_tab_obj = True singleton_tab_obj = True
cdp_timeout = 30 cdp_timeout = 30
browser_connect_timeout = 30
auto_handle_alert = None auto_handle_alert = None
_suffixes_list = str(Path(__file__).parent.absolute() / 'suffixes.dat').replace('\\', '/') _suffixes_list = str(Path(__file__).parent.absolute() / 'suffixes.dat').replace('\\', '/')

View File

@ -15,6 +15,7 @@ class Settings(object):
raise_when_wait_failed: bool = ... raise_when_wait_failed: bool = ...
singleton_tab_obj: bool = ... singleton_tab_obj: bool = ...
cdp_timeout: float = ... cdp_timeout: float = ...
browser_connect_timeout: float = ...
auto_handle_alert: Optional[bool] = ... auto_handle_alert: Optional[bool] = ...
_suffixes_list: str = ... _suffixes_list: str = ...

View File

@ -118,7 +118,7 @@ class ChromiumPage(ChromiumBase):
self.browser.activate_tab(id_ind_tab) self.browser.activate_tab(id_ind_tab)
def close(self): def close(self):
self.browser._close_tab(self.tab_id) self.browser._close_tab(self)
def close_tabs(self, tabs_or_ids, others=False): def close_tabs(self, tabs_or_ids, others=False):
self.browser.close_tabs(tabs_or_ids=tabs_or_ids, others=others) self.browser.close_tabs(tabs_or_ids=tabs_or_ids, others=others)

View File

@ -54,7 +54,7 @@ class ChromiumTab(ChromiumBase):
if others: if others:
self.browser.close_tabs(self.tab_id, others=True) self.browser.close_tabs(self.tab_id, others=True)
else: else:
self.browser._close_tab(self.tab_id) self.browser._close_tab(self)
@property @property
def set(self): def set(self):

View File

@ -182,7 +182,7 @@ class MixTab(SessionPage, ChromiumTab, BasePage):
if others: if others:
self.browser.close_tabs(self.tab_id, others=True) self.browser.close_tabs(self.tab_id, others=True)
else: else:
self.browser._close_tab(self.tab_id) self.browser._close_tab(self)
if session and self._session: if session and self._session:
self._session.close() self._session.close()
if self._response is not None: if self._response is not None:

View File

@ -232,7 +232,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
def close(self): def close(self):
if self._has_driver: if self._has_driver:
self.browser._close_tab(self.tab_id) self.browser._close_tab(self)
if self._session: if self._session:
self._session.close() self._session.close()
if self._response is not None: if self._response is not None:

View File

@ -125,7 +125,18 @@ class Clicker(object):
if not self._ele.tab._browser._dl_mgr._running: if not self._ele.tab._browser._dl_mgr._running:
self._ele.tab._browser.set.download_path('.') self._ele.tab._browser.set.download_path('.')
if new_tab or self._ele.tab._type.endswith('Page'): if self._ele.tab._type.endswith('Page'):
obj = browser = self._ele.tab._browser
tid = 'browser'
# t_settings = TabDownloadSettings(self._ele.owner.tab_id)
# b_settings = TabDownloadSettings('browser')
# b_settings.rename = t_settings.rename
# b_settings.suffix = t_settings.suffix
# t_settings.rename = None
# t_settings.suffix = None
tmp_save_path = str(Path(save_path).absolute()) if save_path else self._ele.owner._tab.download_path
elif new_tab:
obj = browser = self._ele.tab._browser obj = browser = self._ele.tab._browser
tid = 'browser' tid = 'browser'
t_settings = TabDownloadSettings(self._ele.owner.tab_id) t_settings = TabDownloadSettings(self._ele.owner.tab_id)
@ -150,11 +161,15 @@ class Clicker(object):
browser._dl_mgr.set_flag(tid, True) browser._dl_mgr.set_flag(tid, True)
self.left(by_js=by_js) self.left(by_js=by_js)
r = wait_mission(browser, tid, timeout) m = wait_mission(browser, tid, timeout)
if tmp_save_path: if m:
r.path = tmp_save_path if tmp_save_path:
return r m.path = tmp_save_path
if new_tab:
self._ele.owner.browser._dl_mgr._tab_missions.setdefault(self._ele.owner.tab_id, []).append(m)
m.from_tab = self._ele.owner
return m
def to_upload(self, file_paths, by_js=False): def to_upload(self, file_paths, by_js=False):
self._ele.owner.set.upload_files(file_paths) self._ele.owner.set.upload_files(file_paths)

View File

@ -25,7 +25,7 @@ class DownloadManager(object):
t.when_file_exists = 'rename' t.when_file_exists = 'rename'
self._missions = {} # {guid: DownloadMission} self._missions = {} # {guid: DownloadMission}
self._tab_missions = {} # {tab_id: DownloadMission} self._tab_missions = {} # {tab_id: [DownloadMission, ...]}
self._flags = {} # {tab_id: [bool, DownloadMission]} self._flags = {} # {tab_id: [bool, DownloadMission]}
self._running = False self._running = False
@ -67,8 +67,11 @@ class DownloadManager(object):
if mission.state not in ('canceled', 'skipped'): if mission.state not in ('canceled', 'skipped'):
mission.state = state mission.state = state
mission.final_path = final_path mission.final_path = final_path
if mission.tab_id in self._tab_missions and mission.id in self._tab_missions[mission.tab_id]: if mission.tab_id in self._tab_missions and mission in self._tab_missions[mission.tab_id]:
self._tab_missions[mission.tab_id].remove(mission.id) self._tab_missions[mission.tab_id].remove(mission)
if (mission.from_tab and mission.from_tab in self._tab_missions
and mission in self._tab_missions[mission.from_tab]):
self._tab_missions[mission.from_tab].remove(mission)
self._missions.pop(mission.id, None) self._missions.pop(mission.id, None)
mission._is_done = True mission._is_done = True
@ -96,8 +99,9 @@ class DownloadManager(object):
def _onDownloadWillBegin(self, **kwargs): def _onDownloadWillBegin(self, **kwargs):
guid = kwargs['guid'] guid = kwargs['guid']
tab_id = self._browser._frames.get(kwargs['frameId'], 'browser') tab_id = self._browser._frames.get(kwargs['frameId'], 'browser')
tab = tab_id if tab_id in TabDownloadSettings.TABS else 'browser'
settings = TabDownloadSettings(tab_id if tab_id in TabDownloadSettings.TABS else 'browser') settings = TabDownloadSettings(tab)
if settings.rename: if settings.rename:
if settings.suffix is not None: if settings.suffix is not None:
name = f'{settings.rename}.{settings.suffix}' if settings.suffix else settings.rename name = f'{settings.rename}.{settings.suffix}' if settings.suffix else settings.rename
@ -132,15 +136,15 @@ class DownloadManager(object):
m = DownloadMission(self, tab_id, guid, settings.path, name, kwargs['url'], self._browser.download_path) m = DownloadMission(self, tab_id, guid, settings.path, name, kwargs['url'], self._browser.download_path)
self._missions[guid] = m self._missions[guid] = m
if self.get_flag(tab_id) is False: # 取消该任务 if self.get_flag(tab) is False: # 取消该任务
self.cancel(m) self.cancel(m)
elif skip: elif skip:
self.skip(m) self.skip(m)
else: else:
self._tab_missions.setdefault(tab_id, []).append(m) self._tab_missions.setdefault(tab_id, []).append(m)
if self.get_flag(tab_id) is not None: if self.get_flag(tab) is not None:
self._flags[tab_id] = m self._flags[tab] = m
def _onDownloadProgress(self, **kwargs): def _onDownloadProgress(self, **kwargs):
if kwargs['guid'] in self._missions: if kwargs['guid'] in self._missions:
@ -204,6 +208,7 @@ class DownloadMission(object):
self._mgr = mgr self._mgr = mgr
self.url = url self.url = url
self.tab_id = tab_id self.tab_id = tab_id
self.from_tab = None
self.id = _id self.id = _id
self.path = path self.path = path
self.name = name self.name = name

View File

@ -141,6 +141,7 @@ class TabDownloadSettings(object):
class DownloadMission(object): class DownloadMission(object):
tab_id: str = ... tab_id: str = ...
from_tab: Optional[str] = ...
_mgr: DownloadManager = ... _mgr: DownloadManager = ...
url: str = ... url: str = ...
id: str = ... id: str = ...

View File

@ -32,8 +32,7 @@ class SelectElement(object):
@property @property
def selected_option(self): def selected_option(self):
ele = self._ele._run_js('return this.options[this.selectedIndex];') return self._ele._run_js('return this.options[this.selectedIndex];')
return ele
@property @property
def selected_options(self): def selected_options(self):
@ -54,6 +53,7 @@ class SelectElement(object):
i._run_js(f'this.selected={mode};') i._run_js(f'this.selected={mode};')
if change: if change:
self._dispatch_change() self._dispatch_change()
return self._ele
def clear(self): def clear(self):
if not self.is_multi: if not self.is_multi:
@ -73,7 +73,7 @@ class SelectElement(object):
return self._by_loc(locator, timeout) return self._by_loc(locator, timeout)
def by_option(self, option): def by_option(self, option):
self._select_options(option, 'true') return self._select_options(option, 'true')
def cancel_by_text(self, text, timeout=None): def cancel_by_text(self, text, timeout=None):
return self._select(text, 'text', True, timeout) return self._select(text, 'text', True, timeout)
@ -88,19 +88,17 @@ class SelectElement(object):
return self._by_loc(locator, timeout, True) return self._by_loc(locator, timeout, True)
def cancel_by_option(self, option): def cancel_by_option(self, option):
self._select_options(option, 'false') return self._select_options(option, 'false')
def _by_loc(self, loc, timeout=None, cancel=False): def _by_loc(self, loc, timeout=None, cancel=False):
eles = self._ele.eles(loc, timeout) eles = self._ele.eles(loc, timeout)
if not eles: if not eles:
return False raise RuntimeError('没有找到指定选项。')
mode = 'false' if cancel else 'true' mode = 'false' if cancel else 'true'
if self.is_multi: if not self.is_multi:
self._select_options(eles, mode) eles = eles[0]
else: return self._select_options(eles, mode)
self._select_options(eles[0], mode)
return True
def _select(self, condition, para_type='text', cancel=False, timeout=None): def _select(self, condition, para_type='text', cancel=False, timeout=None):
if not self.is_multi and isinstance(condition, (list, tuple)): if not self.is_multi and isinstance(condition, (list, tuple)):
@ -117,7 +115,6 @@ class SelectElement(object):
return self._index(condition, mode, timeout) return self._index(condition, mode, timeout)
def _text_value(self, condition, para_type, mode, timeout): def _text_value(self, condition, para_type, mode, timeout):
ok = False
text_len = len(condition) text_len = len(condition)
eles = [] eles = []
end_time = perf_counter() + timeout end_time = perf_counter() + timeout
@ -128,34 +125,22 @@ class SelectElement(object):
eles = [i for i in self.options if i.attr('value') in condition] eles = [i for i in self.options if i.attr('value') in condition]
if len(eles) >= text_len: if len(eles) >= text_len:
ok = True return self._select_options(eles, mode)
break
sleep(.01) sleep(.01)
if ok: raise RuntimeError('没有找到指定选项。')
self._select_options(eles, mode)
return True
return False
def _index(self, condition, mode, timeout): def _index(self, condition, mode, timeout):
ok = False
condition = [int(i) for i in condition] condition = [int(i) for i in condition]
text_len = abs(max(condition, key=abs)) text_len = abs(max(condition, key=abs))
end_time = perf_counter() + timeout end_time = perf_counter() + timeout
while perf_counter() < end_time: while perf_counter() < end_time:
if len(self.options) >= text_len: if len(self.options) >= text_len:
ok = True eles = self.options
break eles = [eles[i - 1] if i > 0 else eles[i] for i in condition]
return self._select_options(eles, mode)
sleep(.01) sleep(.01)
raise RuntimeError('没有找到指定选项。')
if ok:
eles = self.options
eles = [eles[i - 1] if i > 0 else eles[i] for i in condition]
self._select_options(eles, mode)
return True
return False
def _select_options(self, option, mode): def _select_options(self, option, mode):
if isinstance(option, (list, tuple, set)): if isinstance(option, (list, tuple, set)):
@ -167,6 +152,7 @@ class SelectElement(object):
else: else:
option._run_js(f'this.selected={mode};') option._run_js(f'this.selected={mode};')
self._dispatch_change() self._dispatch_change()
return self._ele
def _dispatch_change(self): def _dispatch_change(self):
self._ele._run_js('this.dispatchEvent(new CustomEvent("change", {bubbles: true}));') self._ele._run_js('this.dispatchEvent(new CustomEvent("change", {bubbles: true}));')

View File

@ -20,11 +20,11 @@ class SelectElement(object):
def __call__(self, def __call__(self,
text_or_index: Union[str, int, list, tuple], text_or_index: Union[str, int, list, tuple],
timeout: float = None) -> bool: timeout: float = None) -> ChromiumElement:
"""选定下拉列表中子元素 """选定下拉列表中子元素
:param text_or_index: 根据文本值选或序号择选项若允许多选传入list或tuple可多选 :param text_or_index: 根据文本值选或序号择选项若允许多选传入list或tuple可多选
:param timeout: 超时时间不输入默认实用页面超时时间 :param timeout: 超时时间不输入默认实用页面超时时间
:return: None :return: <select>元素对象
""" """
... ...
@ -48,122 +48,124 @@ class SelectElement(object):
"""返回所有被选中的<option>元素列表""" """返回所有被选中的<option>元素列表"""
... ...
def all(self) -> None: def all(self) -> ChromiumElement:
"""全选""" """全选"""
... ...
def invert(self) -> None: def invert(self) -> ChromiumElement:
"""反选""" """反选"""
... ...
def clear(self) -> None: def clear(self) -> ChromiumElement:
"""清除所有已选项""" """清除所有已选项"""
... ...
def by_text(self, def by_text(self,
text: Union[str, list, tuple], text: Union[str, list, tuple],
timeout: float = None) -> bool: timeout: float = None) -> ChromiumElement:
"""此方法用于根据text值选择项。当元素是多选列表时可以接收list或tuple """此方法用于根据text值选择项。当元素是多选列表时可以接收list或tuple
:param text: text属性值传入list或tuple可选择多项 :param text: text属性值传入list或tuple可选择多项
:param timeout: 超时时间为None默认使用页面超时时间 :param timeout: 超时时间为None默认使用页面超时时间
:return: 是否选择成功 :return: <select>元素对象
""" """
... ...
def by_value(self, def by_value(self,
value: Union[str, list, tuple], value: Union[str, list, tuple],
timeout: float = None) -> bool: timeout: float = None) -> ChromiumElement:
"""此方法用于根据value值选择项。当元素是多选列表时可以接收list或tuple """此方法用于根据value值选择项。当元素是多选列表时可以接收list或tuple
:param value: value属性值传入list或tuple可选择多项 :param value: value属性值传入list或tuple可选择多项
:param timeout: 超时时间为None默认使用页面超时时间 :param timeout: 超时时间为None默认使用页面超时时间
:return: 是否选择成功 :return: <select>元素对象
""" """
... ...
def by_index(self, def by_index(self,
index: Union[int, list, tuple], index: Union[int, list, tuple],
timeout: float = None) -> bool: timeout: float = None) -> ChromiumElement:
"""此方法用于根据index值选择项。当元素是多选列表时可以接收list或tuple """此方法用于根据index值选择项。当元素是多选列表时可以接收list或tuple
:param index: 序号从1开始可传入负数获取倒数第几个传入list或tuple可选择多项 :param index: 序号从1开始可传入负数获取倒数第几个传入list或tuple可选择多项
:param timeout: 超时时间为None默认使用页面超时时间 :param timeout: 超时时间为None默认使用页面超时时间
:return: 是否选择成功 :return: <select>元素对象
""" """
... ...
def by_locator(self, def by_locator(self,
locator: Union[Tuple[str, str], str], locator: Union[Tuple[str, str], str],
timeout: float = None) -> bool: timeout: float = None) -> ChromiumElement:
"""用定位符选择指定的项 """用定位符选择指定的项
:param locator: 定位符 :param locator: 定位符
:param timeout: 超时时间 :param timeout: 超时时间
:return: 是否选择成功 :return: <select>元素对象
""" """
... ...
def by_option(self, option: Union[ChromiumElement, List[ChromiumElement], Tuple[ChromiumElement]]) -> None: def by_option(self,
option: Union[ChromiumElement, List[ChromiumElement], Tuple[ChromiumElement]]) -> ChromiumElement:
"""选中单个或多个<option>元素 """选中单个或多个<option>元素
:param option: <option>元素或它们组成的列表 :param option: <option>元素或它们组成的列表
:return: None :return: <select>元素对象
""" """
... ...
def cancel_by_text(self, def cancel_by_text(self,
text: Union[str, list, tuple], text: Union[str, list, tuple],
timeout: float = None) -> bool: timeout: float = None) -> ChromiumElement:
"""此方法用于根据text值取消选择项。当元素是多选列表时可以接收list或tuple """此方法用于根据text值取消选择项。当元素是多选列表时可以接收list或tuple
:param text: 文本传入list或tuple可取消多项 :param text: 文本传入list或tuple可取消多项
:param timeout: 超时时间不输入默认实用页面超时时间 :param timeout: 超时时间不输入默认实用页面超时时间
:return: 是否取消成功 :return: <select>元素对象
""" """
... ...
def cancel_by_value(self, def cancel_by_value(self,
value: Union[str, list, tuple], value: Union[str, list, tuple],
timeout: float = None) -> bool: timeout: float = None) -> ChromiumElement:
"""此方法用于根据value值取消选择项。当元素是多选列表时可以接收list或tuple """此方法用于根据value值取消选择项。当元素是多选列表时可以接收list或tuple
:param value: value属性值传入list或tuple可取消多项 :param value: value属性值传入list或tuple可取消多项
:param timeout: 超时时间不输入默认实用页面超时时间 :param timeout: 超时时间不输入默认实用页面超时时间
:return: 是否取消成功 :return: <select>元素对象
""" """
... ...
def cancel_by_index(self, def cancel_by_index(self,
index: Union[int, list, tuple], index: Union[int, list, tuple],
timeout: float = None) -> bool: timeout: float = None) -> ChromiumElement:
"""此方法用于根据index值取消选择项。当元素是多选列表时可以接收list或tuple """此方法用于根据index值取消选择项。当元素是多选列表时可以接收list或tuple
:param index: 序号从1开始可传入负数获取倒数第几个传入list或tuple可取消多项 :param index: 序号从1开始可传入负数获取倒数第几个传入list或tuple可取消多项
:param timeout: 超时时间不输入默认实用页面超时时间 :param timeout: 超时时间不输入默认实用页面超时时间
:return: 是否取消成功 :return: <select>元素对象
""" """
... ...
def cancel_by_locator(self, def cancel_by_locator(self,
locator: Union[Tuple[str, str], str], locator: Union[Tuple[str, str], str],
timeout: float = None) -> bool: timeout: float = None) -> ChromiumElement:
"""用定位符取消选择指定的项 """用定位符取消选择指定的项
:param locator: 定位符 :param locator: 定位符
:param timeout: 超时时间 :param timeout: 超时时间
:return: 是否选择成功 :return: <select>元素对象
""" """
... ...
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]]) -> ChromiumElement:
"""取消选中单个或多个<option>元素 """取消选中单个或多个<option>元素
:param option: <option>元素或它们组成的列表 :param option: <option>元素或它们组成的列表
:return: None :return: <select>元素对象
""" """
... ...
def _by_loc(self, def _by_loc(self,
loc: Union[str, Tuple[str, str]], loc: Union[str, Tuple[str, str]],
timeout: float = None, timeout: float = None,
cancel: bool = False) -> bool: cancel: bool = False) -> ChromiumElement:
"""用定位符取消选择指定的项 """用定位符取消选择指定的项
:param loc: 定位符 :param loc: 定位符
:param timeout: 超时时间 :param timeout: 超时时间
:param cancel: 是否取消选择 :param cancel: 是否取消选择
:return: 是否选择成功 :return: <select>元素对象
""" """
... ...
@ -171,12 +173,12 @@ class SelectElement(object):
condition: Union[str, int, list, tuple] = None, condition: Union[str, int, list, tuple] = None,
para_type: str = 'text', para_type: str = 'text',
cancel: bool = False, cancel: bool = False,
timeout: float = None) -> bool: timeout: float = None) -> ChromiumElement:
"""选定或取消选定下拉列表中子元素 """选定或取消选定下拉列表中子元素
:param condition: 根据文本值选或序号择选项若允许多选传入list或tuple可多选 :param condition: 根据文本值选或序号择选项若允许多选传入list或tuple可多选
:param para_type: 参数类型可选 'text''value''index' :param para_type: 参数类型可选 'text''value''index'
:param cancel: 是否取消选择 :param cancel: 是否取消选择
:return: 是否选择成功 :return: <select>元素对象
""" """
... ...
@ -184,31 +186,32 @@ class SelectElement(object):
condition: Union[list, set], condition: Union[list, set],
para_type: str, para_type: str,
mode: str, mode: str,
timeout: float) -> bool: timeout: float) -> ChromiumElement:
"""执行text和value搜索 """执行text和value搜索
:param condition: 条件set :param condition: 条件set
:param para_type: 参数类型可选 'text''value' :param para_type: 参数类型可选 'text''value'
:param mode: 'true' 'false' :param mode: 'true' 'false'
:param timeout: 超时时间 :param timeout: 超时时间
:return: 是否选择成功 :return: <select>元素对象
""" """
... ...
def _index(self, condition: set, mode: str, timeout: float) -> bool: def _index(self, condition: set, mode: str, timeout: float) -> ChromiumElement:
"""执行index搜索 """执行index搜索
:param condition: 条件set :param condition: 条件set
:param mode: 'true' 'false' :param mode: 'true' 'false'
:param timeout: 超时时间 :param timeout: 超时时间
:return: 是否选择成功 :return: <select>元素对象
""" """
... ...
def _select_options(self, option: Union[ChromiumElement, List[ChromiumElement], Tuple[ChromiumElement]], def _select_options(self,
mode: str) -> None: option: Union[ChromiumElement, List[ChromiumElement], Tuple[ChromiumElement]],
mode: str) -> ChromiumElement:
"""选中或取消某个选项 """选中或取消某个选项
:param option: options元素对象 :param option: options元素对象
:param mode: 选中还是取消 :param mode: 选中还是取消
:return: None :return: <select>元素对象
""" """
... ...

View File

@ -271,7 +271,7 @@ class ChromiumPageSetter(TabSetter):
self._owner._DownloadKit.set.save_path(path) self._owner._DownloadKit.set.save_path(path)
def download_file_name(self, name=None, suffix=None): def download_file_name(self, name=None, suffix=None):
super().download_file_name(name=name, suffix=suffix) # super().download_file_name(name=name, suffix=suffix)
self._owner.browser.set.download_file_name(name, suffix) self._owner.browser.set.download_file_name(name, suffix)

View File

@ -270,6 +270,9 @@ class ChromiumPageWaiter(TabWaiter):
def new_tab(self, timeout=None, raise_err=None): def new_tab(self, timeout=None, raise_err=None):
return self._owner.browser.wait.new_tab(timeout=timeout, raise_err=raise_err) return self._owner.browser.wait.new_tab(timeout=timeout, raise_err=raise_err)
def download_begin(self, timeout=None, cancel_it=False):
return self._owner.browser.wait.download_begin(timeout=timeout, cancel_it=cancel_it)
def all_downloads_done(self, timeout=None, cancel_if_timeout=True): def all_downloads_done(self, timeout=None, cancel_if_timeout=True):
return self._owner.browser.wait.downloads_done(timeout=timeout, cancel_if_timeout=cancel_if_timeout) return self._owner.browser.wait.downloads_done(timeout=timeout, cancel_if_timeout=cancel_if_timeout)