增加对shadow-dom支持,初步完成

This commit is contained in:
g1879 2020-08-30 20:09:48 +08:00
parent 7186620c97
commit ca9d2124d9

View File

@ -1,11 +1,12 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from html import unescape
from re import split as re_SPLIT
from typing import Union, Any
from selenium.webdriver.remote.webelement import WebElement
from .common import DrissionElement, get_loc_from_str
from .common import DrissionElement
from .driver_element import execute_driver_find
@ -16,6 +17,9 @@ class ShadowRootElement(DrissionElement):
self.timeout = timeout
self._driver = inner_ele.parent
def __repr__(self):
return f'<ShadowRootElement in {self.parent_ele} >'
@property
def driver(self):
"""返回控制元素的WebDriver对象"""
@ -41,18 +45,18 @@ class ShadowRootElement(DrissionElement):
loc = 'xpath', f'.{"/.." * (num - 1)}'
return self.parent_ele.ele(loc, timeout=0.01, show_errmsg=False)
# @property
# def next(self):
# """返回后一个兄弟元素"""
# return
#
# def nexts(self, num: int = 1):
# """返回后面第num个兄弟元素 \n
# :param num: 后面第几个兄弟元素
# :return: DriverElement对象
# """
# # loc = 'xpath', f'./following-sibling::*[{num}]'
# return
@property
def next(self):
"""返回后一个兄弟元素"""
return self.nexts()
def nexts(self, num: int = 1):
"""返回后面第num个兄弟元素 \n
:param num: 后面第几个兄弟元素
:return: DriverElement对象
"""
loc = 'css selector', f':nth-child({num})'
return self.parent_ele.ele(loc)
def ele(self,
loc_or_str: Union[tuple, str],
@ -60,33 +64,21 @@ class ShadowRootElement(DrissionElement):
timeout: float = None,
show_errmsg: bool = False):
if isinstance(loc_or_str, str):
loc_or_str = get_loc_from_str(loc_or_str)
loc_or_str = get_css_from_str(loc_or_str)
elif isinstance(loc_or_str, tuple) and len(loc_or_str) == 2:
pass
else:
raise ValueError('Argument loc_or_str can only be tuple or str.')
if loc_or_str[0] == 'xpath':
# 确保查询语句最前面是.
# loc_str = loc_or_str[1] if loc_or_str[1].startswith(('.', '/')) else f'.//{loc_or_str[1]}'
# loc_str = loc_str if loc_str.startswith('.') else f'.{loc_str}'
loc_str = loc_or_str[1]
# print(self.inner_ele)
# print(loc_str)
js = f'''return document.evaluate('{loc_str}', arguments[0]).iterateNext()''' #
print(js)
return self.inner_ele.parent.execute_script(js, self.inner_ele)
# return self.run_script(js)
# else:
# if loc_or_str[1].lstrip().startswith('>'):
# loc_or_str = loc_or_str[0], f'{self.css_path}{loc_or_str[1]}'
raise ValueError('不支持xpath')
timeout = timeout or self.timeout
return execute_driver_find(self.inner_ele, loc_or_str, mode, show_errmsg, timeout)
def eles(self, loc: Union[tuple, str], show_errmsg: bool = True):
pass
def eles(self,
loc_or_str: Union[tuple, str],
timeout: float = None,
show_errmsg: bool = False):
return self.ele(loc_or_str, mode='all', show_errmsg=show_errmsg, timeout=timeout)
def run_script(self, script: str, *args) -> Any:
"""执行js代码传入自己为第一个参数 \n
@ -107,3 +99,47 @@ class ShadowRootElement(DrissionElement):
return True
except:
return False
def get_css_from_str(loc: str) -> tuple:
"""处理元素查找语句 \n
查找方式属性tag name及属性css selector \n
=表示精确匹配:表示模糊匹配无控制字符串时默认搜索该字符串 \n
示例 \n
@class:ele_class - class含有ele_class的元素 \n
@class=ele_class - class等于ele_class的元素 \n
@class - 带class属性的元素 \n
tag:div - div元素 \n
tag:div@class:ele_class - class含有ele_class的div元素 \n
tag:div@class=ele_class - class等于ele_class的div元素 \n
css:div.ele_class \n
"""
if loc.startswith('@'): # 根据属性查找
r = re_SPLIT(r'([:=])', loc[1:], maxsplit=1)
if len(r) == 3:
mode = '=' if r[1] == '=' else '*='
loc_str = f'*[{r[0]}{mode}{r[2]}]'
else:
loc_str = f'*[{loc[1:]}]'
elif loc.startswith(('tag=', 'tag:')): # 根据tag name查找
if '@' not in loc[4:]:
loc_str = f'{loc[4:]}'
else:
at_lst = loc[4:].split('@', maxsplit=1)
r = re_SPLIT(r'([:=])', at_lst[1], maxsplit=1)
if len(r) == 3:
if r[0] == 'text()':
raise ValueError('不支持按文本查找')
mode = '=' if r[1] == '=' else '*='
loc_str = f'{at_lst[0]}[{r[0]}{mode}"{r[2]}"]'
else:
loc_str = f'{at_lst[0]}[{r[0]}]'
elif loc.startswith(('css=', 'css:')): # 用css selector查找
loc_str = loc[4:]
elif loc.startswith(('text=', 'text:')): # 根据文本查找
raise ValueError('不支持按文本查找')
elif loc.startswith(('xpath=', 'xpath:')): # 用xpath查找
raise ValueError('不支持xpath')
else:
raise ValueError('不支持的查询语句')
return 'css selector', loc_str