diff --git a/DrissionPage/chromium_base.py b/DrissionPage/chromium_base.py index ffbfb8b..6e08aba 100644 --- a/DrissionPage/chromium_base.py +++ b/DrissionPage/chromium_base.py @@ -111,6 +111,7 @@ class ChromiumBase(BasePage): self._tab_obj.set_listener('DOM.documentUpdated', self._onDocumentUpdated) self._tab_obj.set_listener('Page.loadEventFired', self._onLoadEventFired) self._tab_obj.set_listener('Page.frameNavigated', self._onFrameNavigated) + self._tab_obj.set_listener('Page.downloadWillBegin', self._onDownloadWillBegin) def _get_document(self): """刷新cdp使用的document数据""" @@ -242,6 +243,9 @@ class ChromiumBase(BasePage): self.run_cdp('Page.setInterceptFileChooserDialog', enabled=False) self._upload_list = None + def _onDownloadWillBegin(self, **kwargs): + self._page._dl_mgr.add_mission(kwargs['guid'], self.download_path, kwargs['suggestedFilename']) + def __call__(self, loc_or_str, timeout=None): """在内部查找元素 例:ele = page('@id=ele_id') @@ -251,6 +255,10 @@ class ChromiumBase(BasePage): """ return self.ele(loc_or_str, timeout) + @property + def page(self): + return self._page + @property def driver(self): """返回用于控制浏览器的ChromiumDriver对象""" diff --git a/DrissionPage/chromium_base.pyi b/DrissionPage/chromium_base.pyi index 810ab1a..94463f1 100644 --- a/DrissionPage/chromium_base.pyi +++ b/DrissionPage/chromium_base.pyi @@ -13,6 +13,7 @@ from .base import BasePage from .chromium_driver import ChromiumDriver from .chromium_element import ChromiumElement, ChromiumScroll from .chromium_frame import ChromiumFrame +from .chromium_page import ChromiumPage from .commons.constants import NoneElement from .network_listener import NetworkListener from .session_element import SessionElement @@ -25,6 +26,7 @@ class ChromiumBase(BasePage): address: Union[str, int], tab_id: str = None, timeout: float = None): + self._page: ChromiumPage = ... self._control_session: Session = ... self.address: str = ... self._tab_obj: ChromiumDriver = ... @@ -66,6 +68,8 @@ class ChromiumBase(BasePage): def _onFileChooserOpened(self, **kwargs): ... + def _onDownloadWillBegin(self, **kwargs): ... + def _set_start_options(self, address, none) -> None: ... def _set_runtime_settings(self) -> None: ... diff --git a/DrissionPage/chromium_frame.py b/DrissionPage/chromium_frame.py index a5fbebe..001d49f 100644 --- a/DrissionPage/chromium_frame.py +++ b/DrissionPage/chromium_frame.py @@ -23,9 +23,9 @@ class ChromiumFrame(ChromiumBase): """ page_type = str(type(page)) if 'ChromiumPage' in page_type or 'WebPage' in page: - self.page = self._target_page = self.tab = page + self._page = self._target_page = self.tab = page else: # Tab、Frame - self.page = page.page + self._page = page.page self._target_page = page self.tab = page.tab if 'ChromiumFrame' in page_type else page @@ -189,6 +189,10 @@ class ChromiumFrame(ChromiumBase): print('页面停止加载 FrameStoppedLoading') self._get_new_document() + @property + def page(self): + return self._page + @property def ids(self): return self._ids @@ -348,6 +352,10 @@ class ChromiumFrame(ChromiumBase): """返回frame所在tab的id""" return self._tab_id + @property + def download_path(self): + return self.tab.download_path + def refresh(self): """刷新frame页面""" self._check_ok() diff --git a/DrissionPage/chromium_frame.pyi b/DrissionPage/chromium_frame.pyi index f4cb6ba..1a798f6 100644 --- a/DrissionPage/chromium_frame.pyi +++ b/DrissionPage/chromium_frame.pyi @@ -6,6 +6,8 @@ from pathlib import Path from typing import Union, Tuple, List, Any +from DrissionPage import ChromiumPage, WebPage +from .chromium_tab import ChromiumTab from .chromium_base import ChromiumBase, ChromiumPageScroll from .chromium_element import ChromiumElement, Locations, ChromiumElementStates from .setter import ChromiumFrameSetter @@ -15,9 +17,9 @@ from .waiter import FrameWaiter class ChromiumFrame(ChromiumBase): def __init__(self, page: ChromiumBase, ele: ChromiumElement): - self.page: ChromiumBase = ... - self._target_page = ... - self.tab = ... + self._page: ChromiumPage = ... + self._target_page: ChromiumBase = ... + self.tab: ChromiumTab = ... self._tab_id: str = ... self.frame_id: str = ... self._frame_ele: ChromiumElement = ... @@ -51,6 +53,9 @@ class ChromiumFrame(ChromiumBase): def _onFrameDetached(self, **kwargs): ... + @property + def page(self) -> Union[ChromiumPage, WebPage]: ... + @property def ids(self) -> ChromiumFrameIds: ... @@ -120,6 +125,9 @@ class ChromiumFrame(ChromiumBase): @property def tab_id(self) -> str: ... + @property + def download_path(self) -> str: ... + def refresh(self) -> None: ... def attr(self, attr: str) -> Union[str, None]: ... diff --git a/DrissionPage/chromium_page.py b/DrissionPage/chromium_page.py index 6678cb7..8d7e52b 100644 --- a/DrissionPage/chromium_page.py +++ b/DrissionPage/chromium_page.py @@ -3,6 +3,7 @@ @Author : g1879 @Contact : g1879@qq.com """ +from shutil import move from time import perf_counter, sleep from .chromium_base import ChromiumBase, Timeout @@ -25,6 +26,8 @@ class ChromiumPage(ChromiumBase): :param timeout: 超时时间 """ super().__init__(addr_driver_opts, tab_id, timeout) + self._page = self + self._dl_mgr = BrowserDownloadManager(self) def _set_start_options(self, addr_driver_opts, none): """设置浏览器启动属性 @@ -439,9 +442,25 @@ class ChromiumTabRect(object): class BrowserDownloadManager(object): def __init__(self, page): - self.page = page - self.frames = {} - self.pause = False + self._page = page + page.set.download_path(page.download_path) + self._page.browser_driver.set_listener('Browser.downloadProgress', self._onDownloadProgress) + self._missions = {} + + def add_mission(self, guid, path, name): + print(name) + self._missions[guid] = {'path': path, 'name': name} + + def _onDownloadProgress(self, **kwargs): + # todo: 处理同名文件、处理后缀 + if kwargs['state'] == 'completed' and kwargs['guid'] in self._missions: + guid = kwargs['guid'] + path = self._missions[guid]['path'] + name = self._missions[guid]['name'] + form_path = f'{self._page.download_path}\\{guid}' + to_path = f'{path}\\{name}' + move(form_path, to_path) + self._missions.pop(guid) # class BaseDownloadSetter(DownloadSetter): diff --git a/DrissionPage/chromium_page.pyi b/DrissionPage/chromium_page.pyi index 916d85c..1f5f1c3 100644 --- a/DrissionPage/chromium_page.pyi +++ b/DrissionPage/chromium_page.pyi @@ -5,11 +5,11 @@ """ from typing import Union, Tuple, List -from .setter import ChromiumPageSetter from .chromium_base import ChromiumBase from .chromium_driver import ChromiumDriver from .chromium_tab import ChromiumTab from .configs.chromium_options import ChromiumOptions +from .setter import ChromiumPageSetter from .waiter import ChromiumPageWaiter @@ -21,7 +21,7 @@ class ChromiumPage(ChromiumBase): timeout: float = None): self._driver_options: ChromiumOptions = ... self._process_id: str = ... - # self._window_setter: WindowSetter = ... + self._dl_mgr: BrowserDownloadManager = ... self._main_tab: str = ... self._alert: Alert = ... self._browser_driver: ChromiumDriver = ... @@ -125,6 +125,17 @@ class ChromiumTabRect(object): def _get_browser_rect(self) -> dict: ... +class BrowserDownloadManager(object): + _page: ChromiumPage = ... + _missions: dict = ... + + def __init__(self, page: ChromiumPage): ... + + def add_mission(self, guid: str, path: str, name: str) -> None: ... + + def _onDownloadProgress(self, **kwargs) -> None: ... + + # class BaseDownloadSetter(DownloadSetter): # def __init__(self, page: ChromiumPage): # self._page: ChromiumPage = ... diff --git a/DrissionPage/chromium_tab.py b/DrissionPage/chromium_tab.py index 6fdfa38..9f68d5f 100644 --- a/DrissionPage/chromium_tab.py +++ b/DrissionPage/chromium_tab.py @@ -20,7 +20,7 @@ class ChromiumTab(ChromiumBase): :param page: ChromiumPage对象 :param tab_id: 要控制的标签页id,不指定默认为激活的 """ - self.page = page + self._page = page super().__init__(page.address, tab_id, page.timeout) def _set_runtime_settings(self): @@ -35,6 +35,11 @@ class ChromiumTab(ChromiumBase): """关闭当前标签页""" self.page.close_tabs(self.tab_id) + @property + def page(self): + """返回总体page对象""" + return self._page + @property def rect(self): """返回获取窗口坐标和大小的对象""" diff --git a/DrissionPage/chromium_tab.pyi b/DrissionPage/chromium_tab.pyi index fecc3fb..850c1f3 100644 --- a/DrissionPage/chromium_tab.pyi +++ b/DrissionPage/chromium_tab.pyi @@ -21,12 +21,15 @@ from .web_page import WebPage class ChromiumTab(ChromiumBase): def __init__(self, page: ChromiumPage, tab_id: str = None): - self.page: ChromiumPage = ... + self._page: ChromiumPage = ... def _set_runtime_settings(self) -> None: ... def close(self) -> None: ... + @property + def page(self) -> ChromiumPage: ... + @property def rect(self) -> ChromiumTabRect: ... @@ -36,7 +39,7 @@ class ChromiumTab(ChromiumBase): class WebPageTab(SessionPage, ChromiumTab): def __init__(self, page: WebPage, tab_id: str): - self.page: WebPage = ... + self._page: WebPage = ... self._mode: str = ... self._has_driver = ... self._has_session = ... @@ -45,6 +48,9 @@ class WebPageTab(SessionPage, ChromiumTab): loc_or_str: Union[Tuple[str, str], str, ChromiumElement, SessionElement], timeout: float = None) -> Union[ChromiumElement, SessionElement]: ... + @property + def page(self) -> WebPage: ... + @property def url(self) -> Union[str, None]: ... diff --git a/DrissionPage/setter.py b/DrissionPage/setter.py index 8343cc2..b46cf9d 100644 --- a/DrissionPage/setter.py +++ b/DrissionPage/setter.py @@ -158,6 +158,15 @@ class ChromiumPageSetter(ChromiumBaseSetter, DownloadSetter): tab_or_id = tab_or_id.tab_id self._page._control_session.get(f'http://{self._page.address}/json/activate/{tab_or_id}') + def download_path(self, path): + """设置下载路径 + :param path: 下载路径 + :return: None + """ + super().download_path(path) + self._page.browser_driver.call_method('Browser.setDownloadBehavior', downloadPath=self._page.download_path, + behavior='allowAndName', eventsEnabled=True) + class SessionPageSetter(DownloadSetter): def __init__(self, page): diff --git a/DrissionPage/setter.pyi b/DrissionPage/setter.pyi index dfddd59..bbf6cec 100644 --- a/DrissionPage/setter.pyi +++ b/DrissionPage/setter.pyi @@ -69,6 +69,8 @@ class ChromiumPageSetter(ChromiumBaseSetter, DownloadSetter): def tab_to_front(self, tab_or_id: Union[str, ChromiumTab] = None) -> None: ... + def download_path(self, path: Union[str, Path]) -> None: ... + class SessionPageSetter(DownloadSetter): def __init__(self, page: SessionPage):