From 661604997b645d5789558eb3142d79a9db759f32 Mon Sep 17 00:00:00 2001 From: g1879 Date: Thu, 8 Sep 2022 15:01:48 +0800 Subject: [PATCH] =?UTF-8?q?2.7.3=20=E9=A1=B5=E9=9D=A2=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E5=92=8C=E5=85=83=E7=B4=A0=E5=AF=B9=E8=B1=A1=E7=9A=84screensho?= =?UTF-8?q?t=5Fas=5Fbytes()=E6=96=B9=E6=B3=95=E5=90=88=E5=B9=B6=E5=88=B0sc?= =?UTF-8?q?reenshot()=EF=BC=9Binput()=E6=96=B9=E6=B3=95=E6=8E=A5=E6=94=B6?= =?UTF-8?q?=E9=9D=9E=E6=96=87=E6=9C=AC=E5=8F=82=E6=95=B0=E6=97=B6=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E8=BD=AC=E6=88=90=E6=96=87=E6=9C=AC=E8=BE=93=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DrissionPage/driver_element.py | 36 +++++++++++++++++++--------------- DrissionPage/driver_page.py | 16 +++++++-------- docs/使用方法/元素操作.md | 14 ++++++------- docs/使用方法/查找页面元素.md | 9 +++++++++ docs/使用方法/页面操作.md | 12 +++++------- docs/版本历史.md | 6 ++++++ setup.py | 2 +- 7 files changed, 55 insertions(+), 40 deletions(-) diff --git a/DrissionPage/driver_element.py b/DrissionPage/driver_element.py index 96e99eb..1c98028 100644 --- a/DrissionPage/driver_element.py +++ b/DrissionPage/driver_element.py @@ -537,6 +537,8 @@ class DriverElement(DrissionElement): :return: bool """ if not insure or self.tag != 'input' or self.prop('type') != 'text': # 普通输入 + if not isinstance(vals, (str, tuple)): + vals = str(vals) if clear: self.inner_ele.clear() @@ -545,7 +547,7 @@ class DriverElement(DrissionElement): else: # 确保输入正确 if not isinstance(vals, str): - raise TypeError('insure参数生效时vals只能接收str数据。') + vals = str(vals) enter = '\n' if vals.endswith('\n') else None full_txt = vals if clear else f'{self.attr("value")}{vals}' full_txt = full_txt.rstrip('\n') @@ -623,34 +625,36 @@ class DriverElement(DrissionElement): except Exception: return False - def screenshot(self, path: str, filename: str = None) -> str: - """对元素进行截图 \n + def screenshot(self, path: str = None, filename: str = None, as_bytes: bool = False) -> Union[str, bytes]: + """对元素进行截图 \n :param path: 保存路径 :param filename: 图片文件名,不传入时以元素tag name命名 - :return: 图片完整路径 + :param as_bytes: 是否已字节形式返回图片,为True时上面两个参数失效 + :return: 图片完整路径或字节文本 """ - name = filename or self.tag - path = Path(path).absolute() - path.mkdir(parents=True, exist_ok=True) - if not name.lower().endswith('.png'): - name = f'{name}.png' - # 等待元素加载完成 if self.tag == 'img': js = ('return arguments[0].complete && typeof arguments[0].naturalWidth != "undefined" ' - '&& arguments[0].naturalWidth > 0') - while not self.run_script(js): + '&& arguments[0].naturalWidth > 0 && typeof arguments[0].naturalHeight != "undefined" ' + '&& arguments[0].naturalHeight > 0') + t1 = perf_counter() + while not self.run_script(js) and perf_counter() - t1 < self.page.timeout: pass + if as_bytes: + return self.inner_ele.screenshot_as_png + + name = filename or self.tag + path = Path(path or '.').absolute() + path.mkdir(parents=True, exist_ok=True) + if not name.lower().endswith('.png'): + name = f'{name}.png' + img_path = str(get_usable_path(f'{path}{sep}{name}')) self.inner_ele.screenshot(img_path) return img_path - def screenshot_as_bytes(self) -> bytes: - """以字节方式返回元素截图""" - return self.inner_ele.screenshot_as_png - def prop(self, prop: str) -> str: """获取property属性值 \n :param prop: 属性名 diff --git a/DrissionPage/driver_page.py b/DrissionPage/driver_page.py index e37e913..2f93d13 100644 --- a/DrissionPage/driver_page.py +++ b/DrissionPage/driver_page.py @@ -442,25 +442,25 @@ class DriverPage(BasePage): if cookies: self.run_cdp('Network.clearBrowserCookies') - def screenshot(self, path: str, filename: str = None) -> str: - """截取页面可见范围截图 \n + def screenshot(self, path: str = None, filename: str = None, as_bytes: bool = False) -> Union[str, bytes]: + """截取页面可见范围截图 \n :param path: 保存路径 :param filename: 图片文件名,不传入时以页面title命名 - :return: 图片完整路径 + :param as_bytes: 是否已字节形式返回图片,为True时上面两个参数失效 + :return: 图片完整路径或字节文本 """ + if as_bytes: + return self.driver.get_screenshot_as_png() + name = filename or self.title if not name.lower().endswith('.png'): name = f'{name}.png' - path = Path(path).absolute() + path = Path(path or '.').absolute() path.mkdir(parents=True, exist_ok=True) img_path = str(get_usable_path(f'{path}{sep}{name}')) self.driver.save_screenshot(img_path) return img_path - def screenshot_as_bytes(self) -> bytes: - """以字节方式返回页面截图""" - return self.driver.get_screenshot_as_png() - def scroll_to_see(self, loc_or_ele: Union[str, tuple, WebElement, DriverElement]) -> None: """滚动页面直到元素可见 \n :param loc_or_ele: 元素的定位信息,可以是loc元组,或查询字符串(详见ele函数注释) diff --git a/docs/使用方法/元素操作.md b/docs/使用方法/元素操作.md index 3af4073..a270dc2 100644 --- a/docs/使用方法/元素操作.md +++ b/docs/使用方法/元素操作.md @@ -89,7 +89,7 @@ ele.r_click_at(50, 50) insure 参数为 `True` 时可自动确保输入正确。该功能是为了应对 selenium 原生输入在某些i情况下会失效的问题。但只能用于 input 元素且 `type` 为 `text` 的情况。 接收组合键的时候可接收 selenium 的 `Keys` 对象的值。组合键要放在一个 `tuple` 中传入。 !> **注意:**
`insure` 为 `True` 时不能用于接收组合键。 -?> **Tips:**
有些文本框可以接收回车代替点击按钮,可以直接在文本末尾加上`'\n'`。 +?> **Tips:**
- 有些文本框可以接收回车代替点击按钮,可以直接在文本末尾加上`'\n'`。
- 非传入`tuple`时,会自动把非`str`转换为`str`。 参数: @@ -183,23 +183,21 @@ ele1.wait_ele(ele2).hidden() 此方法用于对元素进行截图。 如果是图片元素,会自动等待加载结束才截图。 此方法能自动获取能够使用的文件名,避免重名覆盖原有文件。并返回保存路径。 -保存格式为 png。 +保存格式为 png,也可以返回图片的二进制文本。 参数: - path:图片保持路径 - filename:图片文件名,不传入时以元素`tag`标签命名 +- as_bytes:是否已字节形式返回图片,为True时上面两个参数失效 -返回:图片的完整路径 +返回:图片完整路径或字节文本 ```python -path = ele.screenshot(r'D:\tmp', 'img_name') +path = ele.screenshot(r'D:\tmp', 'img1') # 保存到路径,文件名为img1.png +bytes = ele.screenshot(as_bytes=True) # 返回截图二进制文本 ``` -## screenshot_as_bytes() - -此方法以字节形式返回元素截图。 - ## set_prop() 此方法用于设置元素`property`属性。 diff --git a/docs/使用方法/查找页面元素.md b/docs/使用方法/查找页面元素.md index 89e0e34..c08ec9a 100644 --- a/docs/使用方法/查找页面元素.md +++ b/docs/使用方法/查找页面元素.md @@ -241,6 +241,9 @@ ele2 = ele1.ele('.:ele_class') 表示某个属性,只匹配一个属性。 `@`关键字只有一个简单功能,就是匹配`@`后面的内容,不再对后面的字符串进行解析。因此即使后面的字符串也存在`@`或`@@`,也作为要匹配的内容对待。 +!> **注意:** +如果属性中包含特殊字符,如包含`@`,用这个方式不能正确匹配到,须使用 css selector 方式查找。且特殊字符要用`\`转义。 + ```python # 查找 name 属性为 ele_name 的元素 ele2 = ele1.ele('@name=ele_name') @@ -256,6 +259,9 @@ ele2 = ele1.ele('@') # 查找 emaile 属性为 abc@def.com 的元素,有多个 @ 也不会重复处理 ele2 = ele1.ele('@email=abc@def.com') + +# 属性中有特殊字符的情形,匹配abc@def属性等于v的元素 +ele2 = ele1.ele('css:div[abc\@def="v"]') ``` ## `@@` @@ -273,6 +279,9 @@ ele2 = ele1.ele('@email=abc@def.com') - 属性名本身以`-`开头 +!> **注意:** +如果属性中包含特殊字符,如包含`@`,用这个方式不能正确匹配到,须使用 css selector 方式查找。且特殊字符要用`\`转义。 + ```python # 查找 name 属性为 name 且 class 属性包含 cls 文本的元素 ele2 = ele1.ele('@@name=name@@class:cls') diff --git a/docs/使用方法/页面操作.md b/docs/使用方法/页面操作.md index e157507..a927a77 100644 --- a/docs/使用方法/页面操作.md +++ b/docs/使用方法/页面操作.md @@ -533,23 +533,21 @@ page.scroll_to_see((By.XPATH, '//div')) 此方法用于生成页面可见范围截图。图片为 png 格式。 此方法能够自动处理文件重命名的情况,给新文件后面增加序号。 +也可以返回图片的二进制文本。 参数: - path:图片保存路径 - filename:图片文件名,可不写后缀,不传入时以页面 title 命名 +- as_bytes:是否已字节形式返回图片,为True时上面两个参数失效 -返回:图片完整路径 +返回:图片完整路径或字节文本 ```python -# 浏览器窗口截图,保存到 D 盘 img 文件夹,文件名为 img1.png -page.screenshot(r'D:\img', 'img1') +path = page.screenshot(r'D:\tmp', 'img1') # 保存到路径,文件名为img1.png +bytes = page.screenshot(as_bytes=True) # 返回截图二进制文本 ``` -## screenshot_as_bytes() - -此方法以字节形式返回页面可见范围截图。 - ## set_window_size() 此方法用于设置浏览器窗口大小。 diff --git a/docs/版本历史.md b/docs/版本历史.md index d054244..ee783fc 100644 --- a/docs/版本历史.md +++ b/docs/版本历史.md @@ -1,3 +1,9 @@ +# 2.7.3 + +- 页面对象和元素对象的`screenshot_as_bytes()`方法合并到`screenshot()` + +- `input()`方法接收非文本参数时自动转成文本输入 + # v2.7.2 - d 模式页面和元素对象增加`screenshot_as_bytes()`方法 diff --git a/setup.py b/setup.py index ffa3d02..70a2478 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ with open("README.md", "r", encoding='utf-8') as fh: setup( name="DrissionPage", - version="2.7.2", + version="2.7.3", author="g1879", author_email="g1879@qq.com", description="A module that integrates selenium and requests session, encapsulates common page operations.",