diff --git a/DrissionPage/chromium_base.py b/DrissionPage/chromium_base.py index 3afcd5a..387a4ab 100644 --- a/DrissionPage/chromium_base.py +++ b/DrissionPage/chromium_base.py @@ -620,10 +620,12 @@ class ChromiumBase(BasePage): js = f'localStorage.getItem("{item}");' if item else 'localStorage;' return self.run_js_loaded(js, as_expr=True) - def get_screenshot(self, path=None, as_bytes=None, full_page=False, left_top=None, right_bottom=None): + def get_screenshot(self, path=None, as_bytes=None, as_base64=None, + full_page=False, left_top=None, right_bottom=None): """对页面进行截图,可对整个网页、可见网页、指定范围截图。对可视范围外截图需要90以上版本浏览器支持 :param path: 完整路径,后缀可选 'jpg','jpeg','png','webp' - :param as_bytes: 是否已字节形式返回图片,可选 'jpg','jpeg','png','webp',生效时path参数无效 + :param as_bytes: 是否以字节形式返回图片,可选 'jpg','jpeg','png','webp',生效时path参数和as_base64参数无效 + :param as_base64: 是否以base64字符串形式返回图片,可选 'jpg','jpeg','png','webp',生效时path参数无效 :param full_page: 是否整页截图,为True截取整个网页,为False截取可视窗口 :param left_top: 截取范围左上角坐标 :param right_bottom: 截取范围右下角角坐标 @@ -637,6 +639,14 @@ class ChromiumBase(BasePage): raise ValueError("只能接收 'jpg', 'jpeg', 'png', 'webp' 四种格式。") pic_type = 'jpeg' if as_bytes == 'jpg' else as_bytes + elif as_base64: + if as_base64 is True: + pic_type = 'png' + else: + if as_base64 not in ('jpg', 'jpeg', 'png', 'webp'): + raise ValueError("只能接收 'jpg', 'jpeg', 'png', 'webp' 四种格式。") + pic_type = 'jpeg' if as_base64 == 'jpg' else as_base64 + else: if not path: path = f'{self.title}.jpg' @@ -662,6 +672,9 @@ class ChromiumBase(BasePage): else: png = self.run_cdp_loaded('Page.captureScreenshot', format=pic_type)['data'] + if as_base64: + return png + from base64 import b64decode png = b64decode(png) diff --git a/DrissionPage/chromium_base.pyi b/DrissionPage/chromium_base.pyi index bdc7699..e941162 100644 --- a/DrissionPage/chromium_base.pyi +++ b/DrissionPage/chromium_base.pyi @@ -178,7 +178,7 @@ class ChromiumBase(BasePage): def get_local_storage(self, item: str = None) -> Union[str, dict, None]: ... def get_screenshot(self, path: [str, Path] = None, - as_bytes: [bool, str] = None, + as_bytes: [bool, str] = None, as_base64: [bool, str] = None, full_page: bool = False, left_top: Tuple[int, int] = None, right_bottom: Tuple[int, int] = None) -> Union[str, bytes]: ... diff --git a/DrissionPage/chromium_element.py b/DrissionPage/chromium_element.py index 54b8161..e2c3842 100644 --- a/DrissionPage/chromium_element.py +++ b/DrissionPage/chromium_element.py @@ -119,7 +119,7 @@ class ChromiumElement(DrissionElement): def size(self): """返回元素宽和高组成的元组""" model = self.page.run_cdp('DOM.getBoxModel', backendNodeId=self._backend_id)['model'] - return model['height'], model['width'] + return model['width'], model['height'] @property def set(self): @@ -462,10 +462,11 @@ class ChromiumElement(DrissionElement): with open(f'{path}{sep}{rename}', write_type) as f: f.write(data) - def get_screenshot(self, path=None, as_bytes=None): + def get_screenshot(self, path=None, as_bytes=None, as_base64=None): """对当前元素截图,可保存到文件,或以字节方式返回 :param path: 完整路径,后缀可选 'jpg','jpeg','png','webp' - :param as_bytes: 是否已字节形式返回图片,可选 'jpg','jpeg','png','webp',生效时path参数无效 + :param as_bytes: 是否以字节形式返回图片,可选 'jpg','jpeg','png','webp',生效时path参数和as_base64参数无效 + :param as_base64: 是否以base64字符串形式返回图片,可选 'jpg','jpeg','png','webp',生效时path参数无效 :return: 图片完整路径或字节文本 """ if self.tag == 'img': # 等待图片加载完成 @@ -479,12 +480,12 @@ class ChromiumElement(DrissionElement): self.page.scroll.to_see(self) sleep(1) left, top = self.location - height, width = self.size + width, height = self.size left_top = (left, top) right_bottom = (left + width, top + height) if not path: path = f'{self.tag}.jpg' - return self.page.get_screenshot(path, as_bytes=as_bytes, full_page=False, + return self.page.get_screenshot(path, as_bytes=as_bytes, as_base64=as_base64, full_page=False, left_top=left_top, right_bottom=right_bottom) def input(self, vals, clear=True): diff --git a/DrissionPage/chromium_element.pyi b/DrissionPage/chromium_element.pyi index d43b1aa..c244539 100644 --- a/DrissionPage/chromium_element.pyi +++ b/DrissionPage/chromium_element.pyi @@ -171,7 +171,8 @@ class ChromiumElement(DrissionElement): def save(self, path: [str, bool] = None, rename: str = None, timeout: float = None) -> None: ... - def get_screenshot(self, path: [str, Path] = None, as_bytes: [bool, str] = None) -> Union[str, bytes]: ... + def get_screenshot(self, path: [str, Path] = None, as_bytes: [bool, str] = None, + as_base64: [bool, str] = None) -> Union[str, bytes]: ... def input(self, vals: Any, clear: bool = True) -> None: ... diff --git a/DrissionPage/chromium_frame.py b/DrissionPage/chromium_frame.py index 8b9bb1d..b68b605 100644 --- a/DrissionPage/chromium_frame.py +++ b/DrissionPage/chromium_frame.py @@ -402,10 +402,12 @@ class ChromiumFrame(ChromiumBase): self._check_ok() return self.frame_ele.afters(filter_loc, timeout) - def get_screenshot(self, path=None, as_bytes=None, full_page=False, left_top=None, right_bottom=None): + def get_screenshot(self, path=None, as_bytes=None, as_base64=None, + full_page=False, left_top=None, right_bottom=None): """对页面进行截图,可对整个网页、可见网页、指定范围截图。对可视范围外截图需要90以上版本浏览器支持 :param path: 完整路径,后缀可选 'jpg','jpeg','png','webp' - :param as_bytes: 是否已字节形式返回图片,可选 'jpg','jpeg','png','webp',生效时path参数无效 + :param as_bytes: 是否以字节形式返回图片,可选 'jpg','jpeg','png','webp',生效时path参数和as_base64参数无效 + :param as_base64: 是否以base64字符串形式返回图片,可选 'jpg','jpeg','png','webp',生效时path参数无效 :param full_page: 是否整页截图,为True截取整个网页,为False截取可视窗口 :param left_top: 截取范围左上角坐标 :param right_bottom: 截取范围右下角角坐标 @@ -414,7 +416,7 @@ class ChromiumFrame(ChromiumBase): if full_page: raise RuntimeError('暂未实现对iframe全页截图功能。') if left_top is None and right_bottom is None: - return self.frame_ele.get_screenshot(path=path, as_bytes=as_bytes) + return self.frame_ele.get_screenshot(path=path, as_bytes=as_bytes, as_base64=as_base64) else: raise RuntimeError('暂未实现对异域iframe内元素截图功能。') diff --git a/DrissionPage/chromium_frame.pyi b/DrissionPage/chromium_frame.pyi index 7d8037d..f1d9440 100644 --- a/DrissionPage/chromium_frame.pyi +++ b/DrissionPage/chromium_frame.pyi @@ -3,6 +3,7 @@ @Author : g1879 @Contact : g1879@qq.com """ +from pathlib import Path from typing import Union, Tuple, List, Any from .chromium_base import ChromiumBase, ChromiumPageScroll, ChromiumBaseSetter @@ -150,8 +151,14 @@ class ChromiumFrame(ChromiumBase): filter_loc: Union[tuple, str] = ..., timeout: float = ...) -> List[Union[ChromiumElement, ChromiumFrame, str]]: ... + def get_screenshot(self, path: [str, Path] = None, + as_bytes: [bool, str] = None, as_base64: [bool, str] = None, + full_page: bool = False, + left_top: Tuple[int, int] = None, + right_bottom: Tuple[int, int] = None) -> Union[str, bytes]: ... + def _find_elements(self, loc_or_ele: Union[Tuple[str, str], str, ChromiumElement, ChromiumFrame], - timeout: float = None, single: bool = True, relative: bool = False, raise_err: bool=None) \ + timeout: float = None, single: bool = True, relative: bool = False, raise_err: bool = None) \ -> Union[ChromiumElement, ChromiumFrame, None, List[Union[ChromiumElement, ChromiumFrame]]]: ... def _d_connect(self,