diff --git a/DrissionPage/driver_element.py b/DrissionPage/driver_element.py index 032d9b2..c5bd469 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: + """输入文本或组合键,也可用于输入文件路径到input元素(文件间用\n间隔) \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参数生效时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') + + 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 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