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
|
@File : common.py
|
||||||
"""
|
"""
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from html import unescape
|
# from html import unescape
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from re import split as re_SPLIT
|
from re import split as re_SPLIT
|
||||||
from shutil import rmtree
|
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
|
||||||
text=search_text - 文本等于search_text的元素 \n
|
text=search_text - 文本等于search_text的元素 \n
|
||||||
xpath://div[@class="ele_class"] - 用xpath查找 \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'
|
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:
|
def _make_search_str(search_str: str) -> str:
|
||||||
"""将"转义,不知何故不能直接用\来转义 \n
|
"""将"转义,不知何故不能直接用 \ 来转义 \n
|
||||||
:param search_str: 查询字符串
|
:param search_str: 查询字符串
|
||||||
:return: 把"转义后的字符串
|
:return: 把"转义后的字符串
|
||||||
"""
|
"""
|
||||||
@ -212,9 +217,20 @@ def _make_search_str(search_str: str) -> str:
|
|||||||
return search_str
|
return search_str
|
||||||
|
|
||||||
|
|
||||||
def format_html(text: str) -> str:
|
def format_html(text: str, replace_space: bool = True) -> str:
|
||||||
"""处理html编码字符"""
|
"""处理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:
|
def translate_loc(loc: tuple) -> tuple:
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
@Contact : g1879@qq.com
|
@Contact : g1879@qq.com
|
||||||
@File : driver_element.py
|
@File : driver_element.py
|
||||||
"""
|
"""
|
||||||
|
import re
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from typing import Union, List, Any, Tuple
|
from typing import Union, List, Any, Tuple
|
||||||
@ -78,7 +79,13 @@ class DriverElement(DrissionElement):
|
|||||||
@property
|
@property
|
||||||
def text(self) -> str:
|
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
|
@property
|
||||||
def link(self) -> str:
|
def link(self) -> str:
|
||||||
@ -178,7 +185,10 @@ class DriverElement(DrissionElement):
|
|||||||
:param attr: 属性名
|
:param attr: 属性名
|
||||||
:return: 属性值文本
|
: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))
|
return format_html(self.inner_ele.get_attribute(attr))
|
||||||
|
|
||||||
def ele(self,
|
def ele(self,
|
||||||
@ -209,6 +219,12 @@ class DriverElement(DrissionElement):
|
|||||||
ele.ele('text=some_text') - 返回第一个文本等于some_text的子元素 \n
|
ele.ele('text=some_text') - 返回第一个文本等于some_text的子元素 \n
|
||||||
ele.ele('xpath://div[@class="ele_class"]') - 返回第一个符合xpath的子元素 \n
|
ele.ele('xpath://div[@class="ele_class"]') - 返回第一个符合xpath的子元素 \n
|
||||||
ele.ele('css:div.ele_class') - 返回第一个符合css selector的子元素 \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 loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串
|
||||||
:param mode: 'single' 或 'all',对应查找一个或全部
|
:param mode: 'single' 或 'all',对应查找一个或全部
|
||||||
:param timeout: 查找元素超时时间
|
:param timeout: 查找元素超时时间
|
||||||
@ -265,6 +281,12 @@ class DriverElement(DrissionElement):
|
|||||||
ele.eles('text=some_text') - 返回所有文本等于some_text的子元素 \n
|
ele.eles('text=some_text') - 返回所有文本等于some_text的子元素 \n
|
||||||
ele.eles('xpath://div[@class="ele_class"]') - 返回所有符合xpath的子元素 \n
|
ele.eles('xpath://div[@class="ele_class"]') - 返回所有符合xpath的子元素 \n
|
||||||
ele.eles('css:div.ele_class') - 返回所有符合css selector的子元素 \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 loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串
|
||||||
:param timeout: 查找元素超时时间
|
:param timeout: 查找元素超时时间
|
||||||
:return: DriverElement对象组成的列表
|
:return: DriverElement对象组成的列表
|
||||||
@ -574,7 +596,7 @@ def execute_driver_find(page_or_ele,
|
|||||||
:return: 返回DriverElement元素或它们组成的列表
|
:return: 返回DriverElement元素或它们组成的列表
|
||||||
"""
|
"""
|
||||||
mode = mode or 'single'
|
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}'.")
|
raise ValueError(f"Argument mode can only be 'single' or 'all', not '{mode}'.")
|
||||||
|
|
||||||
if isinstance(page_or_ele, DrissionElement):
|
if isinstance(page_or_ele, DrissionElement):
|
||||||
|
@ -36,9 +36,8 @@ class SessionElement(DrissionElement):
|
|||||||
@property
|
@property
|
||||||
def html(self) -> str:
|
def html(self) -> str:
|
||||||
"""返回元素outerHTML文本"""
|
"""返回元素outerHTML文本"""
|
||||||
# tostring()会把跟紧元素的文本节点也带上,因此要去掉
|
|
||||||
html = format_html(tostring(self._inner_ele, method="html").decode())
|
html = format_html(tostring(self._inner_ele, method="html").decode())
|
||||||
return format_html(html[:html.rfind('>') + 1])
|
return html[:html.rfind('>') + 1] # tostring()会把跟紧元素的文本节点也带上,因此要去掉
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def inner_html(self) -> str:
|
def inner_html(self) -> str:
|
||||||
@ -50,26 +49,35 @@ class SessionElement(DrissionElement):
|
|||||||
def text(self) -> str:
|
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):
|
def get_node(ele):
|
||||||
str_list = []
|
str_list = []
|
||||||
for el in ele.eles('xpath:./node()'):
|
for el in ele.eles('xpath:./node()'):
|
||||||
if isinstance(el, str):
|
if isinstance(el, str):
|
||||||
if el.replace(' ', '').replace('\n', '') != '':
|
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:
|
elif '\n' in el:
|
||||||
str_list.append('\n')
|
str_list.append('\n')
|
||||||
else:
|
else:
|
||||||
str_list.append(' ')
|
str_list.append(' ')
|
||||||
else:
|
else:
|
||||||
str_list.extend(get_node(el))
|
str_list.extend(get_node(el))
|
||||||
|
if el.tag in ('br', 'p',):
|
||||||
|
str_list.append('\n')
|
||||||
|
|
||||||
return str_list
|
return str_list
|
||||||
|
|
||||||
re_str = ''.join(get_node(self))
|
re_str = ''.join(get_node(self))
|
||||||
re_str = re.sub(r'\n{2,}', '\n', re_str)
|
re_str = re.sub(r'\n{2,}', '\n', re_str)
|
||||||
re_str = re.sub(r' {2,}', ' ', re_str)
|
re_str = re.sub(r' {2,}', ' ', re_str)
|
||||||
|
|
||||||
return format_html(re_str.strip('\n '))
|
return format_html(re_str.strip('\n '))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -176,7 +184,7 @@ class SessionElement(DrissionElement):
|
|||||||
elif attr == 'src':
|
elif attr == 'src':
|
||||||
return self._make_absolute(self.inner_ele.get('src'))
|
return self._make_absolute(self.inner_ele.get('src'))
|
||||||
|
|
||||||
elif attr in ['text', 'innerText']:
|
elif attr in ('text', 'innerText'):
|
||||||
return self.text
|
return self.text
|
||||||
|
|
||||||
elif attr == 'outerHTML':
|
elif attr == 'outerHTML':
|
||||||
@ -213,6 +221,12 @@ class SessionElement(DrissionElement):
|
|||||||
ele.ele('text=some_text') - 返回第一个文本等于some_text的子元素 \n
|
ele.ele('text=some_text') - 返回第一个文本等于some_text的子元素 \n
|
||||||
ele.ele('xpath://div[@class="ele_class"]') - 返回第一个符合xpath的子元素 \n
|
ele.ele('xpath://div[@class="ele_class"]') - 返回第一个符合xpath的子元素 \n
|
||||||
ele.ele('css:div.ele_class') - 返回第一个符合css selector的子元素 \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 loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串
|
||||||
:param mode: 'single' 或 'all‘,对应查找一个或全部
|
:param mode: 'single' 或 'all‘,对应查找一个或全部
|
||||||
:return: SessionElement对象
|
:return: SessionElement对象
|
||||||
@ -267,6 +281,12 @@ class SessionElement(DrissionElement):
|
|||||||
ele.eles('text=some_text') - 返回所有文本等于some_text的子元素 \n
|
ele.eles('text=some_text') - 返回所有文本等于some_text的子元素 \n
|
||||||
ele.eles('xpath://div[@class="ele_class"]') - 返回所有符合xpath的子元素 \n
|
ele.eles('xpath://div[@class="ele_class"]') - 返回所有符合xpath的子元素 \n
|
||||||
ele.eles('css:div.ele_class') - 返回所有符合css selector的子元素 \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 loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串
|
||||||
:return: SessionElement对象组成的列表
|
:return: SessionElement对象组成的列表
|
||||||
"""
|
"""
|
||||||
@ -363,7 +383,7 @@ def execute_session_find(page_or_ele,
|
|||||||
:return: 返回SessionElement元素或列表
|
:return: 返回SessionElement元素或列表
|
||||||
"""
|
"""
|
||||||
mode = mode or 'single'
|
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}'.")
|
raise ValueError(f"Argument mode can only be 'single' or 'all', not '{mode}'.")
|
||||||
|
|
||||||
# 根据传入对象类型获取页面对象和lxml元素对象
|
# 根据传入对象类型获取页面对象和lxml元素对象
|
||||||
@ -372,7 +392,6 @@ def execute_session_find(page_or_ele,
|
|||||||
page_or_ele = page_or_ele.inner_ele
|
page_or_ele = page_or_ele.inner_ele
|
||||||
else: # 传入的是SessionPage对象
|
else: # 传入的是SessionPage对象
|
||||||
page = page_or_ele
|
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)
|
page_or_ele = fromstring(page_or_ele.response.text)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user