Chromium增加clear_cache()方法;修复无痕模式new_tab()问题

This commit is contained in:
g1879 2024-08-19 18:11:50 +08:00
parent d1b4a23bed
commit 421ec5b888
4 changed files with 70 additions and 12 deletions

View File

@ -24,6 +24,7 @@ from .._pages.chromium_base import Timeout
from .._pages.tabs import ChromiumTab, MixTab
from .._units.downloader import DownloadManager
from .._units.setter import BrowserSetter
from .._units.states import BrowserStates
from .._units.waiter import BrowserWaiter
from ..errors import BrowserConnectError, CDPError
from ..errors import PageDisconnectedError
@ -64,6 +65,7 @@ class Chromium(object):
self._set = None
self._wait = None
self._states = None
self._timeouts = Timeout(**self._chromium_options.timeouts)
self._load_mode = self._chromium_options.load_mode
self._download_path = str(Path(self._chromium_options.download_path).absolute())
@ -72,8 +74,8 @@ class Chromium(object):
self.address = self._chromium_options.address
self._driver = BrowserDriver(self.id, 'browser', self.address, self)
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):
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.quit(3, True)
connect_browser(self._chromium_options)
s = Session()
@ -137,6 +139,12 @@ class Chromium(object):
self._set = BrowserSetter(self)
return self._set
@property
def states(self):
if self._states is None:
self._states = BrowserStates(self)
return self._states
@property
def wait(self):
if self._wait is None:
@ -183,12 +191,13 @@ class Chromium(object):
if tab:
kwargs['browserContextId'] = tab
try:
tab = self._run_cdp('Target.createTarget', **kwargs)['targetId']
except CDPError:
data = ('a', {'href': url or 'https://#', 'target': '_new' if new_window else '_blank'})
tab = self.get_mix_tab() if isinstance(obj, MixTab) else self.get_tab()
return tab.add_ele(data).click.for_new_tab(by_js=True)
if self.states.is_incognito():
return _new_tab_by_js(self, url, obj, new_window)
else:
try:
tab = self._run_cdp('Target.createTarget', **kwargs)['targetId']
except CDPError:
return _new_tab_by_js(self, url, obj, new_window)
while tab not in self._drivers:
sleep(.1)
@ -198,13 +207,19 @@ class Chromium(object):
return tab
def get_tab(self, id_or_num=None, title=None, url=None, tab_type='page', as_id=False):
return self._get_tab(id_or_num=id_or_num, title=title, url=url, tab_type=tab_type, as_id=as_id)
t = self._get_tab(id_or_num=id_or_num, title=title, url=url, tab_type=tab_type, as_id=as_id)
if t._type == 'MixTab':
raise RuntimeError('该标签页已有MixTab版本如需多对象公用请用Settings设置singleton_tab_obj为False。')
return t
def get_tabs(self, title=None, url=None, tab_type='page', as_id=False):
return self._get_tabs(title=title, url=url, tab_type=tab_type, as_id=as_id)
def get_mix_tab(self, id_or_num=None, title=None, url=None, tab_type='page', as_id=False):
return self._get_tab(id_or_num=id_or_num, title=title, url=url, tab_type=tab_type, mix=True, as_id=as_id)
t = self._get_tab(id_or_num=id_or_num, title=title, url=url, tab_type=tab_type, mix=True, as_id=as_id)
if t._type != 'MixTab':
raise RuntimeError('该标签页已有非MixTab版本如需多对象公用请用Settings设置singleton_tab_obj为False。')
return t
def get_mix_tabs(self, title=None, url=None, tab_type='page', as_id=False):
return self._get_tabs(title=title, url=url, tab_type=tab_type, mix=True, as_id=as_id)
@ -298,6 +313,13 @@ class Chromium(object):
self._driver.set_callback('Target.targetDestroyed', self._onTargetDestroyed)
self._driver.set_callback('Target.targetCreated', self._onTargetCreated)
def clear_cache(self, cache=True, cookies=True):
if cache:
self.latest_tab.run_cdp('Network.clearBrowserCache')
if cookies:
self._run_cdp('Storage.clearCookies')
def quit(self, timeout=5, force=False, del_data=False):
try:
self._run_cdp('Browser.close')
@ -454,3 +476,13 @@ def run_browser(chromium_options):
except:
raise BrowserConnectError('\n浏览器连接失败,请确认浏览器是否启动。')
return is_headless, browser_id, is_exists
def _new_tab_by_js(browser:Chromium, url, obj, new_window):
tab = browser.get_mix_tab() if isinstance(obj, MixTab) else browser.get_tab()
url = f'"{url}"' if url else ''
new = 'target="_new"' if new_window else 'target="_blank"'
tid = browser.latest_tab.tab_id
tab.run_js(f'window.open({url}, {new})')
tid = browser.wait.new_tab(curr_tab=tid)
return browser.get_mix_tab(tid) if isinstance(obj, MixTab) else browser.get_tab(tid)

View File

@ -16,6 +16,7 @@ from .._pages.chromium_base import Timeout
from .._pages.tabs import ChromiumTab, MixTab
from .._units.downloader import DownloadManager
from .._units.setter import BrowserSetter
from .._units.states import BrowserStates
from .._units.waiter import BrowserWaiter
@ -29,6 +30,9 @@ class Chromium(object):
retry_times: int = ...
retry_interval: float = ...
_set: Optional[BrowserSetter] = ...
_wait: Optional[BrowserWaiter] = ...
_states: Optional[BrowserStates] = ...
_chromium_options: ChromiumOptions = ...
_session_options: SessionOptions = ...
_driver: BrowserDriver = ...
@ -37,8 +41,6 @@ class Chromium(object):
_all_drivers: Dict[str, Set[Driver]] = ...
_process_id: Optional[int] = ...
_dl_mgr: DownloadManager = ...
_set: Optional[BrowserSetter] = ...
_wait: Optional[BrowserWaiter] = ...
_timeouts: Timeout = ...
_load_mode: str = ...
_download_path: str = ...
@ -97,6 +99,11 @@ class Chromium(object):
"""返回用于设置的对象"""
...
@property
def states(self) -> BrowserStates:
"""返回用于获取状态的对象"""
...
@property
def wait(self) -> BrowserWaiter:
"""返回用于等待的对象"""
@ -285,6 +292,14 @@ class Chromium(object):
"""断开重连"""
...
def clear_cache(self, cache: bool = True, cookies: bool = True) -> None:
"""清除缓存,可选要清除的项
:param cache: 是否清除cache
:param cookies: 是否清除cookies
:return: None
"""
...
def quit(self, timeout: float = 5, force: bool = False, del_data: bool = False) -> None:
"""关闭浏览器
:param timeout: 等待浏览器关闭超时时间

View File

@ -92,6 +92,7 @@ class ShadowRootStates(object):
class BrowserStates(object):
def __init__(self, browser):
self._browser = browser
self._incognito = None
def is_alive(self):
return self._browser._driver.is_running
@ -102,6 +103,11 @@ class BrowserStates(object):
def is_existed(self):
return self._browser._is_exists
def is_incognito(self):
if self._incognito is None:
self._incognito = str(self._browser._run_cdp('Browser.getHistograms')).count('Incognito') > 1
return self._incognito
class PageStates(object):
"""Page对象、Tab对象使用"""

View File

@ -95,6 +95,7 @@ class ShadowRootStates(object):
class BrowserStates(object):
_browser: Chromium = ...
_incognito: Optional[bool] = ...
def __init__(self, browser: Chromium):
"""
@ -114,6 +115,10 @@ class BrowserStates(object):
"""返回浏览器是否接管的"""
...
def is_incognito(self):
"""返回浏览器是否无痕模式"""
...
class PageStates(object):
_owner: ChromiumBase = ...