From 5e5ca4fa26075a04315e8939f9b052e7b9ca1402 Mon Sep 17 00:00:00 2001 From: g1879 Date: Mon, 29 Nov 2021 16:50:35 +0800 Subject: [PATCH 1/3] =?UTF-8?q?input=5Ftxt()=E5=8A=9F=E8=83=BD=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E5=88=B0input()=E9=87=8C=EF=BC=9B=E4=BF=AE=E6=94=B9te?= =?UTF-8?q?xt=E5=B1=9E=E6=80=A7=E8=8E=B7=E5=8F=96=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=EF=BC=88=E5=BE=85=E6=B5=8B=E8=AF=95=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DrissionPage/driver_element.py | 56 ++++++++++++++++------------------ 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/DrissionPage/driver_element.py b/DrissionPage/driver_element.py index d4df95a..1940598 100644 --- a/DrissionPage/driver_element.py +++ b/DrissionPage/driver_element.py @@ -6,8 +6,7 @@ """ from os import sep from pathlib import Path -from re import sub -from time import time +from time import time, perf_counter from typing import Union, List, Any, Tuple from selenium.common.exceptions import TimeoutException, JavascriptException, InvalidElementStateException @@ -81,10 +80,10 @@ class DriverElement(DrissionElement): @property def text(self) -> str: """返回元素内所有文本""" - # return format_html(self.inner_ele.get_attribute('innerText'), False) - re_str = self.inner_ele.get_attribute('innerText') - re_str = sub(r'\n{2,}', '\n', re_str) - re_str = sub(r' {2,}', ' ', re_str) + re_str = self.inner_ele.text + # re_str = self.inner_ele.get_attribute('innerText') + # re_str = sub(r'\n{2,}', '\n', re_str) + # re_str = sub(r' {2,}', ' ', re_str) return format_html(re_str.strip('\n '), False) @@ -282,7 +281,6 @@ class DriverElement(DrissionElement): """ if not by_js: timeout = timeout if timeout is not None else self.page.timeout - from time import perf_counter t1 = perf_counter() while perf_counter() - t1 <= timeout: try: @@ -340,37 +338,35 @@ class DriverElement(DrissionElement): from selenium.webdriver import ActionChains ActionChains(self.page.driver).move_to_element_with_offset(self.inner_ele, x, y).context_click().perform() - def input(self, vals: Union[str, tuple], clear: bool = True) -> None: - """输入文本或组合键,可用于所有场合 \n + def input(self, vals: Union[str, tuple], clear: bool = True, insure_input: bool = True) -> None: + """输入文本或组合键,可用于所有场合 \n :param vals: 文本值或按键组合 :param clear: 输入前是否清空文本框 + :param insure_input: 确保输入正确,解决文本框有时输入失效的问题,不能用于输入组合键 :return: None """ - if clear: - self.clear() - - self.inner_ele.send_keys(*vals) - - def input_txt(self, txt: Union[str, tuple], clear: bool = True) -> None: - """专门用于输入文本框,解决文本框有时输入失效的问题 \n - :param txt: 文本值 - :param clear: 输入前是否清空文本框 - :return: None - """ - enter = '\n' if txt.endswith('\n') else None - full_txt = txt if clear else f'{self.attr("value")}{txt}' - full_txt = full_txt.rstrip('\n') - from time import perf_counter - - t1 = perf_counter() - while self.attr('value') != full_txt and perf_counter() - t1 > self.page.timeout: + if not insure_input: # 普通输入 if clear: self.clear() - self.inner_ele.send_keys(txt) + self.inner_ele.send_keys(*vals) - if enter: - self.inner_ele.send_keys(enter) + else: # 确保输入正确 + if not isinstance(vals, str): + raise TypeError('insure_input参数生效时只能接收str数据。') + 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') + + t1 = perf_counter() + while self.is_valid() and self.attr('value') != full_txt and perf_counter() - t1 <= self.page.timeout: + if clear: + self.clear() + + self.inner_ele.send_keys(vals) + + if enter: + self.inner_ele.send_keys(enter) def run_script(self, script: str, *args) -> Any: """执行js代码,传入自己为第一个参数 \n From ca494ec6e868a71c7174b7ac7747c4ccb8b77ffb Mon Sep 17 00:00:00 2001 From: g1879 Date: Mon, 29 Nov 2021 17:00:32 +0800 Subject: [PATCH 2/3] =?UTF-8?q?input=5Ftxt()=E5=8A=9F=E8=83=BD=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E5=88=B0input()=E9=87=8C=EF=BC=9B=E4=BF=AE=E6=94=B9te?= =?UTF-8?q?xt=E5=B1=9E=E6=80=A7=E8=8E=B7=E5=8F=96=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=EF=BC=88=E5=BE=85=E6=B5=8B=E8=AF=95=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DrissionPage/driver_element.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DrissionPage/driver_element.py b/DrissionPage/driver_element.py index 1940598..c5bd469 100644 --- a/DrissionPage/driver_element.py +++ b/DrissionPage/driver_element.py @@ -339,7 +339,7 @@ class DriverElement(DrissionElement): ActionChains(self.page.driver).move_to_element_with_offset(self.inner_ele, x, y).context_click().perform() def input(self, vals: Union[str, tuple], clear: bool = True, insure_input: bool = True) -> None: - """输入文本或组合键,可用于所有场合 \n + """输入文本或组合键,也可用于输入文件路径到input元素(文件间用\n间隔) \n :param vals: 文本值或按键组合 :param clear: 输入前是否清空文本框 :param insure_input: 确保输入正确,解决文本框有时输入失效的问题,不能用于输入组合键 @@ -353,7 +353,7 @@ class DriverElement(DrissionElement): else: # 确保输入正确 if not isinstance(vals, str): - raise TypeError('insure_input参数生效时只能接收str数据。') + raise TypeError('insure_input参数生效时vals只能接收str数据。') 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') From 6e761b74a243d66530f68c0cb1ff38cda15760fa Mon Sep 17 00:00:00 2001 From: g1879 Date: Mon, 29 Nov 2021 17:30:18 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9SessionElement=E7=9A=84te?= =?UTF-8?q?xt=E5=B1=9E=E6=80=A7=EF=BC=8C=E6=9C=AA=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DrissionPage/session_element.py | 54 ++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/DrissionPage/session_element.py b/DrissionPage/session_element.py index d2fb4a1..acfcfc1 100644 --- a/DrissionPage/session_element.py +++ b/DrissionPage/session_element.py @@ -60,41 +60,45 @@ class SessionElement(DrissionElement): """返回元素内所有文本""" # 为尽量保证与浏览器结果一致,弄得比较复杂 - def get_node(ele, pre: bool = False): + nowrap_list = ('a', 'font', 'b', 'span', 'style', 's', 'i', 'del', 'br') # 前面无须换行的元素 + noText_list = ('script',) # 不获取文本的元素 + + def get_node_txt(ele, pre: bool = False): str_list = [] - if ele.tag == 'pre': + tag = ele.tag.lower() + if tag in noText_list: # script标签内的文本不返回 + return str_list + elif tag == 'br': + return ['\n'] + + if tag == 'pre': pre = True - current_tag = None - for el in ele.eles('xpath:./text() | *'): - if current_tag in ('br', 'p') and str_list and str_list[-1] != '\n': - str_list.append('\n') + nodes = ele.eles('xpath:./text() | *') + for k, el in enumerate(nodes): + if isinstance(el, str): # 字符节点 + if pre: + str_list.append(el) - if isinstance(el, str): - if sub('[ \n]', '', el) != '': # 字符除了回车和空格还有其它内容 - if pre: - str_list.append(el) - else: - str_list.append(el.replace('\n', ' ').strip(' \t')) + else: + if sub('[ \n]', '', el) != '': # 字符除了回车和空格还有其它内容 + txt = el + if not pre: + txt = txt.replace('\n', ' ').strip(' \t') + txt = sub(r' {2,}', ' ', txt) + str_list.append(txt) - elif '\n' in el and str_list and str_list[-1] != '\n': # 元素间换行的情况 + else: # 元素节点 + if el.tag.lower() not in nowrap_list and str_list and str_list[-1] != '\n': # 元素间换行的情况 str_list.append('\n') - else: # 整个字符由回车和空格组成 - str_list.append(' ') - current_tag = None + str_list.extend(get_node_txt(el, pre)) - elif el.tag.lower() == 'script': - current_tag = None - - else: - str_list.extend(get_node(el, pre)) - current_tag = el.tag + if tag in ('p', 'div'): + str_list.append('\n') return str_list - re_str = ''.join(get_node(self)) - re_str = sub(r' {2,}', ' ', re_str) - re_str = sub(r'\n{2,}', '\n', re_str) + re_str = ''.join(get_node_txt(self)) return format_html(re_str, False).strip('\n') @property