From 33ab90fe528e31cf68f8b5232fc1c98b389ad44c Mon Sep 17 00:00:00 2001 From: g1879 Date: Fri, 20 Jan 2023 23:11:07 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6=E6=97=B6?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=BC=A0=E5=85=A5=E7=9B=B8=E5=AF=B9=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=EF=BC=9BChromiumPage=E4=B9=9F=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=94=A8DownloadKit=E4=B8=8B=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DrissionPage/chromium_element.py | 3 +- DrissionPage/chromium_page.py | 57 +++++++++++++++++++++++++++++++- DrissionPage/chromium_page.pyi | 21 +++++++++++- DrissionPage/functions/web.py | 21 ++++++++++++ DrissionPage/functions/web.pyi | 4 +++ DrissionPage/session_page.py | 22 ++++-------- DrissionPage/session_page.pyi | 2 +- DrissionPage/web_page.py | 16 +++------ 8 files changed, 115 insertions(+), 31 deletions(-) diff --git a/DrissionPage/chromium_element.py b/DrissionPage/chromium_element.py index fa62151..2fe1626 100644 --- a/DrissionPage/chromium_element.py +++ b/DrissionPage/chromium_element.py @@ -571,12 +571,13 @@ class ChromiumElement(DrissionElement): self.page.driver.Input.insertText(text=vals) def _set_file_input(self, files): - """设置上传控件值 + """往上传控件写入路径 :param files: 文件路径列表或字符串,字符串时多个文件用回车分隔 :return: None """ if isinstance(files, str): files = files.split('\n') + files = [str(Path(i).absolute()) for i in files] self.page.run_cdp('DOM.setFileInputFiles', files=files, nodeId=self._node_id, not_change=True) def clear(self, by_js=False): diff --git a/DrissionPage/chromium_page.py b/DrissionPage/chromium_page.py index 8bc9e77..b929004 100644 --- a/DrissionPage/chromium_page.py +++ b/DrissionPage/chromium_page.py @@ -7,12 +7,16 @@ from pathlib import Path from platform import system from time import perf_counter, sleep +from DownloadKit import DownloadKit +from requests import Session + from .chromium_base import ChromiumBase, Timeout from .chromium_driver import ChromiumDriver from .chromium_tab import ChromiumTab from .configs.chromium_options import ChromiumOptions from .configs.driver_options import DriverOptions from .functions.browser import connect_browser +from .functions.web import set_session_cookies from .session_page import DownloadSetter @@ -26,6 +30,9 @@ class ChromiumPage(ChromiumBase): :param timeout: 超时时间 """ super().__init__(addr_driver_opts, tab_id, timeout) + self._session = None + self._download_set = None + self._download_kit = None def _connect_browser(self, addr_driver_opts=None, tab_id=None): """连接浏览器,在第一次时运行 @@ -137,7 +144,17 @@ class ChromiumPage(ChromiumBase): @property def download_set(self): """返回用于设置下载参数的对象""" - return ChromiumDownloadSetter(self) + if self._download_set is None: + self._download_set = ChromiumDownloadSetter(self) + return self._download_set + + @property + def download(self): + """返回下载器对象""" + self.cookies_to_session() + if self._download_kit is None: + self._download_kit = DownloadKit(session=self._session, goal_path=self.download_path) + return self._download_kit def get_tab(self, tab_id=None): """获取一个标签页对象 @@ -344,6 +361,15 @@ class ChromiumPage(ChromiumBase): """显示浏览器窗口,只在Windows系统可用""" show_or_hide_browser(self, hide=False) + def cookies_to_session(self): + """把driver对象的cookies复制到session对象""" + if self._session is None: + self._session = Session() + selenium_user_agent = self._tab_obj.Runtime.evaluate(expression='navigator.userAgent;')['result']['value'] + self._session.headers.update({"User-Agent": selenium_user_agent}) + + set_session_cookies(self._session, self.get_cookies(as_dict=True)) + def quit(self): """关闭浏览器""" self._tab_obj.Browser.close() @@ -373,6 +399,10 @@ class ChromiumPage(ChromiumBase): class ChromiumDownloadSetter(DownloadSetter): """用于设置下载参数的类""" + def __init__(self, page): + super().__init__(page) + self._behavior = 'allow' + def save_path(self, path): """设置下载路径 :param path: 下载路径 @@ -388,6 +418,31 @@ class ChromiumDownloadSetter(DownloadSetter): except: self._page.run_cdp('Page.setDownloadBehavior', behavior='allow', downloadPath=path, not_change=True) + if self._page._download_kit is not None: + self._page._download_kit.goal_path = path + + def use_browser(self): + """设置使用浏览器下载文件""" + self._page.driver.Page.downloadWillBegin = None + self._page.driver.Browser.downloadWillBegin = None + self._page.driver.Browser.setDownloadBehavior(behavior='allow', downloadPath=self._page.download_path) + self._behavior = 'allow' + + def use_DownloadKit(self): + """设置使用DownloadKit下载文件""" + self._page.driver.Page.downloadWillBegin = self._download_by_DownloadKit + self._page.driver.Browser.downloadWillBegin = self._download_by_DownloadKit + self._page.driver.Browser.setDownloadBehavior(behavior='deny') + self._behavior = 'deny' + + def _download_by_DownloadKit(self, **kwargs): + gid = kwargs['guid'] + self._page.run_cdp('Browser.cancelDownload', guid=gid, not_change=True) + url = kwargs['url'] + name = kwargs['suggestedFilename'] + print(f'下载:{url}') + self._page.download.add(url, goal_path=self._page.download_path, rename=name) + class Alert(object): """用于保存alert信息的类""" diff --git a/DrissionPage/chromium_page.pyi b/DrissionPage/chromium_page.pyi index f28e21d..8712593 100644 --- a/DrissionPage/chromium_page.pyi +++ b/DrissionPage/chromium_page.pyi @@ -7,6 +7,10 @@ from os import popen from pathlib import Path from typing import Union, Tuple, List +from DownloadKit import DownloadKit +from requests import Session + +from .configs.chromium_options import ChromiumOptions from .chromium_base import ChromiumBase from .chromium_driver import ChromiumDriver from .chromium_tab import ChromiumTab @@ -25,6 +29,9 @@ class ChromiumPage(ChromiumBase): self._main_tab: str = ... self._alert: Alert = ... self._download_path: str = ... + self._session: Session = ... + self._download_set: ChromiumDownloadSetter = ... + self._download_kit: DownloadKit = ... def _connect_browser(self, addr_driver_opts: Union[str, ChromiumDriver, DriverOptions] = None, @@ -54,6 +61,9 @@ class ChromiumPage(ChromiumBase): @property def download_set(self) -> ChromiumDownloadSetter: ... + @property + def download(self) -> DownloadKit: ... + @property def download_path(self) -> str: ... @@ -85,6 +95,8 @@ class ChromiumPage(ChromiumBase): def show_browser(self) -> None: ... + def cookies_to_session(self) -> None: ... + def quit(self) -> None: ... def _on_alert_close(self, **kwargs): ... @@ -95,8 +107,15 @@ class ChromiumPage(ChromiumBase): class ChromiumDownloadSetter(object): def __init__(self, page: ChromiumPage): self._page: ChromiumPage = ... + self._behavior: str = ... - def save_path(self, path: Union[str, Path]): ... + def save_path(self, path) -> None: ... + + def use_browser(self) -> None: ... + + def use_DownloadKit(self) -> None: ... + + def _download_by_DownloadKit(self, **kwargs) -> None: ... class Alert(object): diff --git a/DrissionPage/functions/web.py b/DrissionPage/functions/web.py index 09b12f1..8a9ac22 100644 --- a/DrissionPage/functions/web.py +++ b/DrissionPage/functions/web.py @@ -216,3 +216,24 @@ def cookies_to_tuple(cookies): raise TypeError('cookies参数必须为RequestsCookieJar、list、tuple、str或dict类型。') return cookies + + +def set_session_cookies(session, cookies): + """设置Session对象的cookies + :param session: Session对象 + :param cookies: cookies信息 + :return: None + """ + cookies = cookies_to_tuple(cookies) + for cookie in cookies: + if cookie['value'] is None: + cookie['value'] = '' + + kwargs = {x: cookie[x] for x in cookie + if x.lower() in ('version', 'port', 'domain', 'path', 'secure', + 'expires', 'discard', 'comment', 'comment_url', 'rest')} + + if 'expiry' in cookie: + kwargs['expires'] = cookie['expiry'] + + session.cookies.set(cookie['name'], cookie['value'], **kwargs) diff --git a/DrissionPage/functions/web.pyi b/DrissionPage/functions/web.pyi index 7c49332..0930552 100644 --- a/DrissionPage/functions/web.pyi +++ b/DrissionPage/functions/web.pyi @@ -6,6 +6,7 @@ from http.cookiejar import Cookie from typing import Union +from requests import Session from requests.cookies import RequestsCookieJar from DrissionPage.base import DrissionElement, BasePage @@ -34,3 +35,6 @@ def cookie_to_dict(cookie: Union[Cookie, str, dict]) -> dict: ... def cookies_to_tuple(cookies: Union[RequestsCookieJar, list, tuple, str, dict]) -> tuple: ... + + +def set_session_cookies(session: Session, cookies: Union[RequestsCookieJar, list, tuple, str, dict]) -> None: ... diff --git a/DrissionPage/session_page.py b/DrissionPage/session_page.py index 67dd129..d11c89e 100644 --- a/DrissionPage/session_page.py +++ b/DrissionPage/session_page.py @@ -14,7 +14,7 @@ from tldextract import extract from .base import BasePage from .configs.session_options import SessionOptions -from .functions.web import cookies_to_tuple, cookie_to_dict +from .functions.web import cookie_to_dict, set_session_cookies from .session_element import SessionElement, make_session_ele @@ -71,23 +71,15 @@ class SessionPage(BasePage): def _set_options(self): """设置WebPage中与d模式共用的配置,便于WebPage覆盖掉""" - self._timeouts = self._session_options.timeout + self._timeout = self._session_options.timeout self._download_path = self._session_options.download_path def set_cookies(self, cookies): - cookies = cookies_to_tuple(cookies) - for cookie in cookies: - if cookie['value'] is None: - cookie['value'] = '' - - kwargs = {x: cookie[x] for x in cookie - if x.lower() in ('version', 'port', 'domain', 'path', 'secure', - 'expires', 'discard', 'comment', 'comment_url', 'rest')} - - if 'expiry' in cookie: - kwargs['expires'] = cookie['expiry'] - - self.session.cookies.set(cookie['name'], cookie['value'], **kwargs) + """为Session对象设置cookies + :param cookies: cookies信息 + :return: None + """ + set_session_cookies(self.session, cookies) def set_headers(self, headers): """设置通用的headers,设置的headers值回逐个覆盖原有的,不会清理原来的 diff --git a/DrissionPage/session_page.pyi b/DrissionPage/session_page.pyi index 110bd29..9015690 100644 --- a/DrissionPage/session_page.pyi +++ b/DrissionPage/session_page.pyi @@ -154,7 +154,7 @@ class SessionPage(BasePage): class DownloadSetter(object): - def __init__(self, page: SessionPage): + def __init__(self, page: BasePage): self._page: SessionPage = ... def save_path(self, path: Union[str, Path]): ... diff --git a/DrissionPage/web_page.py b/DrissionPage/web_page.py index 81a8c15..369fb55 100644 --- a/DrissionPage/web_page.py +++ b/DrissionPage/web_page.py @@ -487,10 +487,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage): class WebPageDownloadSetter(ChromiumDownloadSetter): """用于设置下载参数的类""" - def __init__(self, page): - super().__init__(page) - self._behavior = 'allow' - def save_path(self, path): """设置下载路径 :param path: 下载路径 @@ -501,6 +497,10 @@ class WebPageDownloadSetter(ChromiumDownloadSetter): path.mkdir(parents=True, exist_ok=True) path = str(path) self._page._download_path = path + + if self._page._download_kit is not None: + self._page._download_kit.goal_path = path + if self._page._has_driver: try: self._page.run_cdp('Browser.setDownloadBehavior', behavior=self._behavior, downloadPath=path, @@ -525,11 +525,3 @@ class WebPageDownloadSetter(ChromiumDownloadSetter): self._page.driver.Browser.downloadWillBegin = self._download_by_DownloadKit self._page.driver.Browser.setDownloadBehavior(behavior='deny') self._behavior = 'deny' - - def _download_by_DownloadKit(self, **kwargs): - gid = kwargs['guid'] - self._page.run_cdp('Browser.cancelDownload', guid=gid, not_change=True) - url = kwargs['url'] - name = kwargs['suggestedFilename'] - print(f'下载:{url}') - self._page.download.add(url, goal_path=self._page.download_path, rename=name)