auto_handle_alert()下级会覆盖上级设置,包括Settings的;Page对象删除set.auto_handle_alert()方法的all_tabs参数

This commit is contained in:
g1879 2024-08-22 18:03:06 +08:00
parent 9ae65b6b2e
commit 987f94104b
12 changed files with 61 additions and 70 deletions

View File

@ -69,6 +69,7 @@ class Chromium(object):
self._timeouts = Timeout(**self._chromium_options.timeouts) self._timeouts = Timeout(**self._chromium_options.timeouts)
self._load_mode = self._chromium_options.load_mode self._load_mode = self._chromium_options.load_mode
self._download_path = str(Path(self._chromium_options.download_path).absolute()) self._download_path = str(Path(self._chromium_options.download_path).absolute())
self._auto_handle_alert = None
self.retry_times = self._chromium_options.retry_times self.retry_times = self._chromium_options.retry_times
self.retry_interval = self._chromium_options.retry_interval self.retry_interval = self._chromium_options.retry_interval
self.address = self._chromium_options.address self.address = self._chromium_options.address
@ -86,6 +87,7 @@ class Chromium(object):
self._driver = BrowserDriver(self.id, 'browser', self.address, self) self._driver = BrowserDriver(self.id, 'browser', self.address, self)
ws.close() ws.close()
s.close() s.close()
self._is_exists = False
self._frames = {} self._frames = {}
self._drivers = {} self._drivers = {}
self._all_drivers = {} self._all_drivers = {}

View File

@ -6,7 +6,7 @@
@License : BSD 3-Clause. @License : BSD 3-Clause.
""" """
from threading import Lock from threading import Lock
from typing import List, Optional, Set, Dict, Union, Tuple from typing import List, Optional, Set, Dict, Union, Tuple, Literal
from .driver import BrowserDriver, Driver from .driver import BrowserDriver, Driver
from .._configs.chromium_options import ChromiumOptions from .._configs.chromium_options import ChromiumOptions
@ -44,6 +44,7 @@ class Chromium(object):
_timeouts: Timeout = ... _timeouts: Timeout = ...
_load_mode: str = ... _load_mode: str = ...
_download_path: str = ... _download_path: str = ...
_auto_handle_alert: Optional[bool] = ...
_is_exists: bool = ... _is_exists: bool = ...
_is_headless: bool = ... _is_headless: bool = ...
@ -85,8 +86,8 @@ class Chromium(object):
... ...
@property @property
def load_mode(self) -> str: def load_mode(self) -> Literal['none', 'normal', 'eager']:
"""返回加载模式""" """返回页面加载模式,包括 'none', 'normal', 'eager' 三种"""
... ...
@property @property

View File

@ -58,7 +58,7 @@ class ChromiumBase(BasePage):
self._console = None self._console = None
self._upload_list = None self._upload_list = None
self._doc_got = False # 用于在LoadEventFired和FrameStoppedLoading间标记是否已获取doc self._doc_got = False # 用于在LoadEventFired和FrameStoppedLoading间标记是否已获取doc
self._download_path = None self._auto_handle_alert = None
self._load_end_time = 0 self._load_end_time = 0
self._init_jss = [] self._init_jss = []
self._type = 'ChromiumBase' self._type = 'ChromiumBase'
@ -107,7 +107,7 @@ class ChromiumBase(BasePage):
self._is_loading = True self._is_loading = True
self._driver = self.browser._get_driver(target_id, self) self._driver = self.browser._get_driver(target_id, self)
self._alert = Alert() self._alert = Alert(self._auto_handle_alert)
self._driver.set_callback('Page.javascriptDialogOpening', self._on_alert_open, immediate=True) self._driver.set_callback('Page.javascriptDialogOpening', self._on_alert_open, immediate=True)
self._driver.set_callback('Page.javascriptDialogClosed', self._on_alert_close) self._driver.set_callback('Page.javascriptDialogClosed', self._on_alert_close)
@ -703,6 +703,7 @@ class ChromiumBase(BasePage):
self._has_alert = True self._has_alert = True
if self._alert.auto is not None: if self._alert.auto is not None:
if self._alert.auto != 'close':
self._handle_alert(self._alert.auto) self._handle_alert(self._alert.auto)
elif Settings.auto_handle_alert is not None: elif Settings.auto_handle_alert is not None:
self._handle_alert(Settings.auto_handle_alert) self._handle_alert(Settings.auto_handle_alert)
@ -882,7 +883,7 @@ class Timeout(object):
class Alert(object): class Alert(object):
"""用于保存alert信息的类""" """用于保存alert信息的类"""
def __init__(self): def __init__(self, auto=None):
self.activated = False self.activated = False
self.text = None self.text = None
self.type = None self.type = None
@ -891,7 +892,7 @@ class Alert(object):
self.response_text = None self.response_text = None
self.handle_next = None self.handle_next = None
self.next_text = None self.next_text = None
self.auto = None self.auto = auto
def close_privacy_dialog(page, tid): def close_privacy_dialog(page, tid):

View File

@ -8,6 +8,8 @@
from pathlib import Path from pathlib import Path
from typing import Union, Tuple, List, Any, Optional, Literal from typing import Union, Tuple, List, Any, Optional, Literal
from .chromium_page import ChromiumPage
from .mix_page import MixPage
from .tabs import ChromiumTab, MixTab from .tabs import ChromiumTab, MixTab
from .._base.base import BasePage from .._base.base import BasePage
from .._base.browser import Chromium from .._base.browser import Chromium
@ -53,6 +55,7 @@ class ChromiumBase(BasePage):
_states: Optional[PageStates] = ... _states: Optional[PageStates] = ...
_alert: Alert = ... _alert: Alert = ...
_has_alert: bool = ... _has_alert: bool = ...
_auto_handle_alert: Optional[bool] = ...
_doc_got: bool = ... _doc_got: bool = ...
_load_end_time: float = ... _load_end_time: float = ...
_init_jss: list = ... _init_jss: list = ...
@ -60,12 +63,13 @@ class ChromiumBase(BasePage):
_rect: Optional[TabRect] = ... _rect: Optional[TabRect] = ...
_console: Optional[Console] = ... _console: Optional[Console] = ...
_type: str = ... _type: str = ...
def __init__(self, def __init__(self,
browser: Chromium, browser: Chromium,
tab_id: str = None): tab_id: str = None):
""" """
:param browser: Chromium :param browser: Chromium
:param target_id: 要控制的target id不指定默认为激活的标签页 :param tab_id: 要控制的tab id不指定默认为激活的标签页
""" """
... ...
@ -652,3 +656,5 @@ class Alert(object):
handle_next: Optional[bool] = ... handle_next: Optional[bool] = ...
next_text: Optional[str] = ... next_text: Optional[str] = ...
auto: Optional[bool] = ... auto: Optional[bool] = ...
def __init__(self, auto: bool = None): ...

View File

@ -83,6 +83,7 @@ class ChromiumFrame(ChromiumBase):
self.retry_times = self._target_page.retry_times self.retry_times = self._target_page.retry_times
self.retry_interval = self._target_page.retry_interval self.retry_interval = self._target_page.retry_interval
self._download_path = self._target_page.download_path self._download_path = self._target_page.download_path
self._auto_handle_alert = self._target_page._auto_handle_alert
self._load_mode = self._target_page._load_mode if not self._is_diff_domain else 'normal' self._load_mode = self._target_page._load_mode if not self._is_diff_domain else 'normal'
def _driver_init(self, target_id, is_init=True): def _driver_init(self, target_id, is_init=True):

View File

@ -49,6 +49,7 @@ class ChromiumPage(ChromiumBase):
self._download_path = self.browser.download_path self._download_path = self.browser.download_path
self.retry_times = self.browser.retry_times self.retry_times = self.browser.retry_times
self.retry_interval = self.browser.retry_interval self.retry_interval = self.browser.retry_interval
self._auto_handle_alert = self.browser._auto_handle_alert
@property @property
def set(self): def set(self):

View File

@ -52,7 +52,7 @@ class MixPage(SessionPage, ChromiumPage, BasePage):
@property @property
def latest_tab(self): def latest_tab(self):
return self.browser.get_mix_tab(self.tab_ids[0], as_id=not Settings.singleton_tab_obj) return self.browser._get_tab(id_or_num=self.tab_ids[0], mix=True, as_id=not Settings.singleton_tab_obj)
@property @property
def set(self): def set(self):

View File

@ -48,6 +48,7 @@ class ChromiumTab(ChromiumBase):
self.retry_interval = self.browser.retry_interval self.retry_interval = self.browser.retry_interval
self._load_mode = self.browser._load_mode self._load_mode = self.browser._load_mode
self._download_path = self.browser.download_path self._download_path = self.browser.download_path
self._auto_handle_alert = self.browser._auto_handle_alert
def close(self, others=False): def close(self, others=False):
self.browser.close_tabs(self.tab_id, others=others) self.browser.close_tabs(self.tab_id, others=others)

View File

@ -11,7 +11,6 @@ from time import sleep
from requests.structures import CaseInsensitiveDict from requests.structures import CaseInsensitiveDict
from .cookies_setter import SessionCookiesSetter, CookiesSetter, MixPageCookiesSetter, BrowserCookiesSetter from .cookies_setter import SessionCookiesSetter, CookiesSetter, MixPageCookiesSetter, BrowserCookiesSetter
from .._functions.settings import Settings
from .._functions.tools import show_or_hide_browser from .._functions.tools import show_or_hide_browser
from .._functions.web import format_headers from .._functions.web import format_headers
from ..errors import ElementLostError, JavaScriptError from ..errors import ElementLostError, JavaScriptError
@ -39,9 +38,6 @@ class BaseSetter(object):
class SessionPageSetter(BaseSetter): class SessionPageSetter(BaseSetter):
def __init__(self, owner): def __init__(self, owner):
"""
:param owner: SessionPage对象
"""
super().__init__(owner) super().__init__(owner)
self._cookies_setter = None self._cookies_setter = None
@ -106,12 +102,7 @@ class SessionPageSetter(BaseSetter):
class BrowserBaseSetter(BaseSetter): class BrowserBaseSetter(BaseSetter):
"""Browser和ChromiumBase设置"""
def __init__(self, owner): def __init__(self, owner):
"""
:param owner: ChromiumBase对象
"""
super().__init__(owner) super().__init__(owner)
self._cookies_setter = None self._cookies_setter = None
@ -139,7 +130,7 @@ class BrowserSetter(BrowserBaseSetter):
return self._cookies_setter return self._cookies_setter
def auto_handle_alert(self, on_off=True, accept=True): def auto_handle_alert(self, on_off=True, accept=True):
Settings.auto_handle_alert = accept if on_off else None self._owner._auto_handle_alert = None if on_off is None else accept if on_off else 'close'
def download_path(self, path): def download_path(self, path):
super().download_path(path) super().download_path(path)
@ -213,7 +204,7 @@ class ChromiumBaseSetter(BrowserBaseSetter):
self._owner._upload_list = [str(Path(i).absolute()) for i in files] self._owner._upload_list = [str(Path(i).absolute()) for i in files]
def auto_handle_alert(self, on_off=True, accept=True): def auto_handle_alert(self, on_off=True, accept=True):
self._owner._alert.auto = accept if on_off else None self._owner._alert.auto = None if on_off is None else accept if on_off else 'close'
def blocked_urls(self, urls): def blocked_urls(self, urls):
if not urls: if not urls:
@ -258,39 +249,22 @@ class TabSetter(ChromiumBaseSetter):
class ChromiumPageSetter(TabSetter): class ChromiumPageSetter(TabSetter):
def NoneElement_value(self, value=None, on_off=True): def NoneElement_value(self, value=None, on_off=True):
"""设置空元素是否返回设定值
:param value: 返回的设定值
:param on_off: 是否启用
:return: None
"""
super().NoneElement_value(value, on_off) super().NoneElement_value(value, on_off)
self._owner.browser._none_ele_return_value = on_off self._owner.browser._none_ele_return_value = on_off
self._owner.browser._none_ele_value = value self._owner.browser._none_ele_value = value
def retry_times(self, times): def retry_times(self, times):
"""设置连接失败重连次数"""
super().retry_times(times) super().retry_times(times)
self._owner.browser.retry_times = times self._owner.browser.retry_times = times
def retry_interval(self, interval): def retry_interval(self, interval):
"""设置连接失败重连间隔"""
super().retry_interval(interval) super().retry_interval(interval)
self._owner.browser.retry_interval = interval self._owner.browser.retry_interval = interval
def download_path(self, path): def download_path(self, path):
"""设置下载路径
:param path: 下载路径
:return: None
"""
super().download_path(path) super().download_path(path)
self._owner.browser._download_path = self._owner._download_path self._owner.browser._download_path = self._owner._download_path
def auto_handle_alert(self, on_off=True, accept=True, all_tabs=False):
if all_tabs:
Settings.auto_handle_alert = on_off
else:
self._owner._alert.auto = accept if on_off else None
class MixPageSetter(ChromiumPageSetter): class MixPageSetter(ChromiumPageSetter):
def __init__(self, owner): def __init__(self, owner):
@ -300,7 +274,6 @@ class MixPageSetter(ChromiumPageSetter):
@property @property
def cookies(self): def cookies(self):
"""返回用于设置cookies的对象"""
if self._cookies_setter is None: if self._cookies_setter is None:
self._cookies_setter = MixPageCookiesSetter(self._owner) self._cookies_setter = MixPageCookiesSetter(self._owner)
return self._cookies_setter return self._cookies_setter
@ -390,8 +363,6 @@ class ChromiumFrameSetter(ChromiumBaseSetter):
class LoadMode(object): class LoadMode(object):
"""用于设置页面加载策略的类"""
def __init__(self, owner): def __init__(self, owner):
self._owner = owner self._owner = owner
@ -430,8 +401,6 @@ class PageScrollSetter(object):
class WindowSetter(object): class WindowSetter(object):
"""用于设置窗口大小的类"""
def __init__(self, owner): def __init__(self, owner):
self._owner = owner self._owner = owner
self._window_id = self._get_info()['windowId'] self._window_id = self._get_info()['windowId']

View File

@ -53,7 +53,7 @@ class BaseSetter(object):
... ...
def retry_interval(self, interval: float) -> None: def retry_interval(self, interval: float) -> None:
"""设置连接失败重连间隔 """设置连接失败重连间隔(秒)
:param interval: 重试间隔 :param interval: 重试间隔
:return: None :return: None
""" """
@ -71,7 +71,11 @@ class SessionPageSetter(BaseSetter):
_owner: SessionPage = ... _owner: SessionPage = ...
_cookies_setter: Optional[SessionCookiesSetter] = ... _cookies_setter: Optional[SessionCookiesSetter] = ...
def __init__(self, owner: SessionPage): ... def __init__(self, owner: SessionPage):
"""
:param owner: SessionPage对象
"""
...
@property @property
def cookies(self) -> SessionCookiesSetter: def cookies(self) -> SessionCookiesSetter:
@ -196,11 +200,18 @@ class SessionPageSetter(BaseSetter):
class BrowserBaseSetter(BaseSetter): class BrowserBaseSetter(BaseSetter):
"""Browser和ChromiumBase设置"""
_cookies_setter: Optional[CookiesSetter] = ... _cookies_setter: Optional[CookiesSetter] = ...
def __init__(self, owner: ChromiumBase):
"""
:param owner: ChromiumBase对象
"""
...
@property @property
def load_mode(self) -> LoadMode: def load_mode(self) -> LoadMode:
"""返回用于设置页面加载策略的对象""" """返回用于设置页面加载模式的对象"""
... ...
def timeouts(self, def timeouts(self,
@ -220,6 +231,12 @@ class BrowserSetter(BrowserBaseSetter):
_owner: Chromium = ... _owner: Chromium = ...
_cookies_setter: BrowserCookiesSetter = ... _cookies_setter: BrowserCookiesSetter = ...
def __init__(self, owner: Chromium):
"""
:param owner: Chromium对象
"""
...
@property @property
def cookies(self) -> BrowserCookiesSetter: def cookies(self) -> BrowserCookiesSetter:
"""返回用于设置cookies的对象""" """返回用于设置cookies的对象"""
@ -227,15 +244,15 @@ class BrowserSetter(BrowserBaseSetter):
def auto_handle_alert(self, def auto_handle_alert(self,
on_off: bool = True, on_off: bool = True,
accept: bool = True): accept: bool = True) -> None:
"""设置是否启用自动处理弹窗 """设置本浏览器是否启用自动处理弹窗
:param on_off: bool表示开或关 :param on_off: bool表示开或关传入None表示使用Settings设置
:param accept: bool表示确定还是取消 :param accept: bool表示确定还是取消
:return: None :return: None
""" """
... ...
def download_path(self, path: Union[Path, str, None]): def download_path(self, path: Union[Path, str, None]) -> None:
"""设置下载路径 """设置下载路径
:param path: 下载路径 :param path: 下载路径
:return: None :return: None
@ -244,7 +261,7 @@ class BrowserSetter(BrowserBaseSetter):
def download_file_name(self, def download_file_name(self,
name: str = None, name: str = None,
suffix: str = None): suffix: str = None) -> None:
"""设置下一个被下载文件的名称 """设置下一个被下载文件的名称
:param name: 文件名可不含后缀会自动使用远程文件后缀 :param name: 文件名可不含后缀会自动使用远程文件后缀
:param suffix: 后缀名显式设置后缀名不使用远程文件后缀 :param suffix: 后缀名显式设置后缀名不使用远程文件后缀
@ -252,7 +269,7 @@ class BrowserSetter(BrowserBaseSetter):
""" """
... ...
def when_download_file_exists(self, mode: FILE_EXISTS): def when_download_file_exists(self, mode: FILE_EXISTS) -> None:
"""设置当存在同名文件时的处理方式 """设置当存在同名文件时的处理方式
:param mode: 可在 'rename', 'overwrite', 'skip', 'r', 'o', 's'中选择 :param mode: 可在 'rename', 'overwrite', 'skip', 'r', 'o', 's'中选择
:return: None :return: None
@ -335,7 +352,7 @@ class ChromiumBaseSetter(BrowserBaseSetter):
class TabSetter(ChromiumBaseSetter): class TabSetter(ChromiumBaseSetter):
_owner: ChromiumTab = ... _owner: ChromiumTab = ...
def __init__(self, owner: Union[ChromiumTab, MixTab, MixPage, ChromiumPage]): def __init__(self, owner: ChromiumTab):
""" """
:param owner: 标签页对象 :param owner: 标签页对象
""" """
@ -384,18 +401,6 @@ class ChromiumPageSetter(TabSetter):
""" """
... ...
def auto_handle_alert(self,
on_off: bool = True,
accept: bool = True,
all_tabs: bool = False) -> None:
"""设置是否启用自动处理弹窗
:param on_off: bool表示开或关
:param accept: bool表示确定还是取消
:param all_tabs: 是否为全局设置
:return: None
"""
...
class MixPageSetter(ChromiumPageSetter): class MixPageSetter(ChromiumPageSetter):
_owner: MixPage = ... _owner: MixPage = ...
@ -409,7 +414,9 @@ class MixPageSetter(ChromiumPageSetter):
... ...
@property @property
def cookies(self) -> MixPageCookiesSetter: ... def cookies(self) -> MixPageCookiesSetter:
"""返回用于设置cookies的对象"""
...
class MixTabSetter(TabSetter): class MixTabSetter(TabSetter):
@ -518,6 +525,7 @@ class ChromiumFrameSetter(ChromiumBaseSetter):
class LoadMode(object): class LoadMode(object):
"""用于设置页面加载策略的类"""
_owner: Union[Chromium, ChromiumBase] = ... _owner: Union[Chromium, ChromiumBase] = ...
def __init__(self, owner: Union[Chromium, ChromiumBase]): def __init__(self, owner: Union[Chromium, ChromiumBase]):
@ -571,6 +579,7 @@ class PageScrollSetter(object):
class WindowSetter(object): class WindowSetter(object):
"""用于设置窗口大小的类"""
_owner: ChromiumBase = ... _owner: ChromiumBase = ...
_window_id: str = ... _window_id: str = ...

View File

@ -115,7 +115,7 @@ class BrowserStates(object):
"""返回浏览器是否接管的""" """返回浏览器是否接管的"""
... ...
def is_incognito(self): def is_incognito(self) -> bool:
"""返回浏览器是否无痕模式""" """返回浏览器是否无痕模式"""
... ...

View File

@ -50,17 +50,17 @@ class BrowserWaiter(OriginWaiter):
def new_tab(self, def new_tab(self,
timeout: float = None, timeout: float = None,
curr_tab: Union[str, ChromiumTab] = None, curr_tab: Union[str, ChromiumTab, MixTab] = None,
raise_err: bool = None) -> Union[str, bool]: raise_err: bool = None) -> Union[str, bool]:
"""等待新标签页出现 """等待新标签页出现
:param timeout: 超时时间为None则使用页面对象timeout属性 :param timeout: 超时时间为None则使用对象timeout属性
:param curr_tab: 指定当前最新的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
""" """
... ...
def download_begin(self, timeout: float = None, cancel_it: bool = False) -> DownloadMission: def download_begin(self, timeout: float = None, cancel_it: bool = False) -> Union[DownloadMission, False]:
"""等待浏览器下载开始,可将其拦截 """等待浏览器下载开始,可将其拦截
:param timeout: 超时时间None使用页面对象超时时间 :param timeout: 超时时间None使用页面对象超时时间
:param cancel_it: 是否取消该任务 :param cancel_it: 是否取消该任务