mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
继续研究text属性的格式,未完成
This commit is contained in:
parent
c0bfdfa1e9
commit
89769f3caa
@ -5,7 +5,7 @@
|
||||
@File : common.py
|
||||
"""
|
||||
from abc import abstractmethod
|
||||
from html import unescape
|
||||
# from html import unescape
|
||||
from pathlib import Path
|
||||
from re import split as re_SPLIT
|
||||
from shutil import rmtree
|
||||
@ -96,7 +96,12 @@ def str_to_loc(loc: str) -> tuple:
|
||||
text:search_text - 文本含有search_text的元素 \n
|
||||
text=search_text - 文本等于search_text的元素 \n
|
||||
xpath://div[@class="ele_class"] - 用xpath查找 \n
|
||||
css:div.ele_class - 用css selector查找
|
||||
css:div.ele_class - 用css selector查找 \n
|
||||
xpath://div[@class="ele_class"] - 等同于 x://div[@class="ele_class"] \n
|
||||
css:div.ele_class - 等同于 c:div.ele_class \n
|
||||
tag:div - 等同于 t:div \n
|
||||
text:search_text - 等同于 tx:search_text \n
|
||||
text=search_text - 等同于 tx=search_text \n
|
||||
"""
|
||||
loc_by = 'xpath'
|
||||
|
||||
@ -195,7 +200,7 @@ def _make_xpath_str(tag: str, arg: str, val: str, mode: str = 'fuzzy') -> str:
|
||||
|
||||
|
||||
def _make_search_str(search_str: str) -> str:
|
||||
"""将"转义,不知何故不能直接用\来转义 \n
|
||||
"""将"转义,不知何故不能直接用 \ 来转义 \n
|
||||
:param search_str: 查询字符串
|
||||
:return: 把"转义后的字符串
|
||||
"""
|
||||
@ -212,9 +217,20 @@ def _make_search_str(search_str: str) -> str:
|
||||
return search_str
|
||||
|
||||
|
||||
def format_html(text: str) -> str:
|
||||
def format_html(text: str, replace_space: bool = True) -> str:
|
||||
"""处理html编码字符"""
|
||||
return unescape(text) if text else text
|
||||
if not text:
|
||||
return text
|
||||
|
||||
# text = unescape(text)
|
||||
|
||||
# if '&' in text:
|
||||
# html = unescape(text)
|
||||
|
||||
if replace_space:
|
||||
text = text.replace('\xa0', ' ')
|
||||
|
||||
return text
|
||||
|
||||
|
||||
def translate_loc(loc: tuple) -> tuple:
|
||||
|
@ -4,6 +4,7 @@
|
||||
@Contact : g1879@qq.com
|
||||
@File : driver_element.py
|
||||
"""
|
||||
import re
|
||||
from pathlib import Path
|
||||
from time import sleep
|
||||
from typing import Union, List, Any, Tuple
|
||||
@ -78,7 +79,13 @@ class DriverElement(DrissionElement):
|
||||
@property
|
||||
def text(self) -> str:
|
||||
"""返回元素内所有文本"""
|
||||
return self.attr('innerText')
|
||||
# return self.inner_ele.get_attribute('innerText')
|
||||
re_str = self.inner_ele.get_attribute('innerText')
|
||||
re_str = re.sub(r'\n{2,}', '\n', re_str)
|
||||
re_str = re.sub(r' {2,}', ' ', re_str)
|
||||
|
||||
return format_html(re_str.strip('\n '))
|
||||
# return re_str.strip('\n ')
|
||||
|
||||
@property
|
||||
def link(self) -> str:
|
||||
@ -178,7 +185,10 @@ class DriverElement(DrissionElement):
|
||||
:param attr: 属性名
|
||||
:return: 属性值文本
|
||||
"""
|
||||
attr = 'innerText' if attr == 'text' else attr
|
||||
# attr = 'innerText' if attr == 'text' else attr
|
||||
if attr in ('text', 'innerText'):
|
||||
return self.text
|
||||
|
||||
return format_html(self.inner_ele.get_attribute(attr))
|
||||
|
||||
def ele(self,
|
||||
@ -188,7 +198,7 @@ class DriverElement(DrissionElement):
|
||||
"""返回当前元素下级符合条件的子元素、属性或节点文本,默认返回第一个 \n
|
||||
示例: \n
|
||||
- 用loc元组查找: \n
|
||||
ele.ele((By.CLASS_NAME, 'ele_class')) - 返回第一个class为ele_class的子元素 \n
|
||||
ele.ele((By.CLASS_NAME, 'ele_class')) - 返回第一个class为ele_class的子元素 \n
|
||||
- 用查询字符串查找: \n
|
||||
查找方式:属性、tag name和属性、文本、xpath、css selector、id、class \n
|
||||
@表示属性,.表示class,#表示id,=表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串 \n
|
||||
@ -209,6 +219,12 @@ class DriverElement(DrissionElement):
|
||||
ele.ele('text=some_text') - 返回第一个文本等于some_text的子元素 \n
|
||||
ele.ele('xpath://div[@class="ele_class"]') - 返回第一个符合xpath的子元素 \n
|
||||
ele.ele('css:div.ele_class') - 返回第一个符合css selector的子元素 \n
|
||||
- 查询字符串还有最精简模式,用x代替xpath、c代替css、t代替tag、tx代替text: \n
|
||||
ele.ele('xpath://div[@class="ele_class"]') - 等同于 ele.ele('x://div[@class="ele_class"]') \n
|
||||
ele.ele('css:div.ele_class') - 等同于 ele.ele('c:div.ele_class') \n
|
||||
ele.ele('tag:div') - 等同于 ele.ele('t:div') \n
|
||||
ele.ele('text:some_text') - 等同于 ele.ele('tx:some_text') \n
|
||||
ele.ele('text=some_text') - 等同于 ele.ele('tx=some_text')
|
||||
:param loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串
|
||||
:param mode: 'single' 或 'all',对应查找一个或全部
|
||||
:param timeout: 查找元素超时时间
|
||||
@ -244,7 +260,7 @@ class DriverElement(DrissionElement):
|
||||
"""返回当前元素下级所有符合条件的子元素、属性或节点文本 \n
|
||||
示例: \n
|
||||
- 用loc元组查找: \n
|
||||
ele.eles((By.CLASS_NAME, 'ele_class')) - 返回所有class为ele_class的子元素 \n
|
||||
ele.eles((By.CLASS_NAME, 'ele_class')) - 返回所有class为ele_class的子元素 \n
|
||||
- 用查询字符串查找: \n
|
||||
查找方式:属性、tag name和属性、文本、xpath、css selector、id、class \n
|
||||
@表示属性,.表示class,#表示id,=表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串 \n
|
||||
@ -265,6 +281,12 @@ class DriverElement(DrissionElement):
|
||||
ele.eles('text=some_text') - 返回所有文本等于some_text的子元素 \n
|
||||
ele.eles('xpath://div[@class="ele_class"]') - 返回所有符合xpath的子元素 \n
|
||||
ele.eles('css:div.ele_class') - 返回所有符合css selector的子元素 \n
|
||||
- 查询字符串还有最精简模式,用x代替xpath、c代替css、t代替tag、tx代替text: \n
|
||||
ele.eles('xpath://div[@class="ele_class"]') - 等同于 ele.eles('x://div[@class="ele_class"]') \n
|
||||
ele.eles('css:div.ele_class') - 等同于 ele.eles('c:div.ele_class') \n
|
||||
ele.eles('tag:div') - 等同于 ele.eles('t:div') \n
|
||||
ele.eles('text:some_text') - 等同于 ele.eles('tx:some_text') \n
|
||||
ele.eles('text=some_text') - 等同于 ele.eles('tx=some_text')
|
||||
:param loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串
|
||||
:param timeout: 查找元素超时时间
|
||||
:return: DriverElement对象组成的列表
|
||||
@ -574,7 +596,7 @@ def execute_driver_find(page_or_ele,
|
||||
:return: 返回DriverElement元素或它们组成的列表
|
||||
"""
|
||||
mode = mode or 'single'
|
||||
if mode not in ['single', 'all']:
|
||||
if mode not in ('single', 'all'):
|
||||
raise ValueError(f"Argument mode can only be 'single' or 'all', not '{mode}'.")
|
||||
|
||||
if isinstance(page_or_ele, DrissionElement):
|
||||
@ -674,7 +696,7 @@ class ElementsByXpath(object):
|
||||
else:
|
||||
driver, the_node = ele_or_driver.parent, ele_or_driver
|
||||
|
||||
# 把lxml元素对象包装成DriverElement对象并按需要返回第一个或全部
|
||||
# 把lxml元素对象包装成DriverElement对象并按需要返回第一个或全部
|
||||
if self.mode == 'single':
|
||||
try:
|
||||
e = get_nodes(the_node, xpath_txt=self.xpath, type_txt='9')
|
||||
|
@ -36,9 +36,8 @@ class SessionElement(DrissionElement):
|
||||
@property
|
||||
def html(self) -> str:
|
||||
"""返回元素outerHTML文本"""
|
||||
# tostring()会把跟紧元素的文本节点也带上,因此要去掉
|
||||
html = format_html(tostring(self._inner_ele, method="html").decode())
|
||||
return format_html(html[:html.rfind('>') + 1])
|
||||
return html[:html.rfind('>') + 1] # tostring()会把跟紧元素的文本节点也带上,因此要去掉
|
||||
|
||||
@property
|
||||
def inner_html(self) -> str:
|
||||
@ -50,26 +49,35 @@ class SessionElement(DrissionElement):
|
||||
def text(self) -> str:
|
||||
"""返回元素内所有文本"""
|
||||
|
||||
# re_str = str(self._inner_ele.text_content())
|
||||
# # re_str = re.sub(r'<br */?>', '\n', re_str)
|
||||
# re_str = re.sub(r'\n{2,}', '\n', re_str)
|
||||
# re_str = re.sub(r' {2,}', ' ', re_str)
|
||||
# return format_html(re_str.strip('\n '))
|
||||
# # return format_html(re_str)
|
||||
|
||||
# 为尽量保证与浏览器结果一致,弄得比较复杂
|
||||
def get_node(ele):
|
||||
str_list = []
|
||||
for el in ele.eles('xpath:./node()'):
|
||||
if isinstance(el, str):
|
||||
if el.replace(' ', '').replace('\n', '') != '':
|
||||
str_list.append(el.replace('\xa0', ' ').replace('\n', ' ').strip())
|
||||
# str_list.append(el.replace('\xa0', ' ').replace('\n', ' ').strip())
|
||||
str_list.append(el.replace('\n', ' ').strip(' '))
|
||||
elif '\n' in el:
|
||||
str_list.append('\n')
|
||||
else:
|
||||
str_list.append(' ')
|
||||
else:
|
||||
str_list.extend(get_node(el))
|
||||
if el.tag in ('br', 'p',):
|
||||
str_list.append('\n')
|
||||
|
||||
return str_list
|
||||
|
||||
re_str = ''.join(get_node(self))
|
||||
re_str = re.sub(r'\n{2,}', '\n', re_str)
|
||||
re_str = re.sub(r' {2,}', ' ', re_str)
|
||||
|
||||
return format_html(re_str.strip('\n '))
|
||||
|
||||
@property
|
||||
@ -176,7 +184,7 @@ class SessionElement(DrissionElement):
|
||||
elif attr == 'src':
|
||||
return self._make_absolute(self.inner_ele.get('src'))
|
||||
|
||||
elif attr in ['text', 'innerText']:
|
||||
elif attr in ('text', 'innerText'):
|
||||
return self.text
|
||||
|
||||
elif attr == 'outerHTML':
|
||||
@ -189,10 +197,10 @@ class SessionElement(DrissionElement):
|
||||
return self.inner_ele.get(attr)
|
||||
|
||||
def ele(self, loc_or_str: Union[Tuple[str, str], str], mode: str = None):
|
||||
"""返回当前元素下级符合条件的子元素、属性或节点文本,默认返回第一个 \n
|
||||
"""返回当前元素下级符合条件的子元素、属性或节点文本,默认返回第一个 \n
|
||||
示例: \n
|
||||
- 用loc元组查找: \n
|
||||
ele.ele((By.CLASS_NAME, 'ele_class')) - 返回第一个class为ele_class的子元素 \n
|
||||
ele.ele((By.CLASS_NAME, 'ele_class')) - 返回第一个class为ele_class的子元素 \n
|
||||
- 用查询字符串查找: \n
|
||||
查找方式:属性、tag name和属性、文本、xpath、css selector、id、class \n
|
||||
@表示属性,.表示class,#表示id,=表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串 \n
|
||||
@ -213,6 +221,12 @@ class SessionElement(DrissionElement):
|
||||
ele.ele('text=some_text') - 返回第一个文本等于some_text的子元素 \n
|
||||
ele.ele('xpath://div[@class="ele_class"]') - 返回第一个符合xpath的子元素 \n
|
||||
ele.ele('css:div.ele_class') - 返回第一个符合css selector的子元素 \n
|
||||
- 查询字符串还有最精简模式,用x代替xpath、c代替css、t代替tag、tx代替text: \n
|
||||
ele.ele('xpath://div[@class="ele_class"]') - 等同于 ele.ele('x://div[@class="ele_class"]') \n
|
||||
ele.ele('css:div.ele_class') - 等同于 ele.ele('c:div.ele_class') \n
|
||||
ele.ele('tag:div') - 等同于 ele.ele('t:div') \n
|
||||
ele.ele('text:some_text') - 等同于 ele.ele('tx:some_text') \n
|
||||
ele.ele('text=some_text') - 等同于 ele.ele('tx=some_text')
|
||||
:param loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串
|
||||
:param mode: 'single' 或 'all‘,对应查找一个或全部
|
||||
:return: SessionElement对象
|
||||
@ -246,7 +260,7 @@ class SessionElement(DrissionElement):
|
||||
"""返回当前元素下级所有符合条件的子元素、属性或节点文本 \n
|
||||
示例: \n
|
||||
- 用loc元组查找: \n
|
||||
ele.eles((By.CLASS_NAME, 'ele_class')) - 返回所有class为ele_class的子元素 \n
|
||||
ele.eles((By.CLASS_NAME, 'ele_class')) - 返回所有class为ele_class的子元素 \n
|
||||
- 用查询字符串查找: \n
|
||||
查找方式:属性、tag name和属性、文本、xpath、css selector、id、class \n
|
||||
@表示属性,.表示class,#表示id,=表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串 \n
|
||||
@ -267,6 +281,12 @@ class SessionElement(DrissionElement):
|
||||
ele.eles('text=some_text') - 返回所有文本等于some_text的子元素 \n
|
||||
ele.eles('xpath://div[@class="ele_class"]') - 返回所有符合xpath的子元素 \n
|
||||
ele.eles('css:div.ele_class') - 返回所有符合css selector的子元素 \n
|
||||
- 查询字符串还有最精简模式,用x代替xpath、c代替css、t代替tag、tx代替text: \n
|
||||
ele.eles('xpath://div[@class="ele_class"]') - 等同于 ele.eles('x://div[@class="ele_class"]') \n
|
||||
ele.eles('css:div.ele_class') - 等同于 ele.eles('c:div.ele_class') \n
|
||||
ele.eles('tag:div') - 等同于 ele.eles('t:div') \n
|
||||
ele.eles('text:some_text') - 等同于 ele.eles('tx:some_text') \n
|
||||
ele.eles('text=some_text') - 等同于 ele.eles('tx=some_text')
|
||||
:param loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串
|
||||
:return: SessionElement对象组成的列表
|
||||
"""
|
||||
@ -363,7 +383,7 @@ def execute_session_find(page_or_ele,
|
||||
:return: 返回SessionElement元素或列表
|
||||
"""
|
||||
mode = mode or 'single'
|
||||
if mode not in ['single', 'all']:
|
||||
if mode not in ('single', 'all'):
|
||||
raise ValueError(f"Argument mode can only be 'single' or 'all', not '{mode}'.")
|
||||
|
||||
# 根据传入对象类型获取页面对象和lxml元素对象
|
||||
@ -372,7 +392,6 @@ def execute_session_find(page_or_ele,
|
||||
page_or_ele = page_or_ele.inner_ele
|
||||
else: # 传入的是SessionPage对象
|
||||
page = page_or_ele
|
||||
# page_or_ele = fromstring(format_html(page_or_ele.response.text, False))
|
||||
page_or_ele = fromstring(page_or_ele.response.text)
|
||||
|
||||
try:
|
||||
|
Loading…
x
Reference in New Issue
Block a user