尝试支持shadow-dom,未完成

This commit is contained in:
g1879 2020-08-28 19:44:19 +08:00
parent 7729e16c4a
commit 7186620c97
3 changed files with 87 additions and 32 deletions

View File

@ -28,9 +28,9 @@ class DrissionElement(object):
def is_valid(self):
return True
@property
def text(self):
return
# @property
# def text(self):
# return
@property
def html(self):
@ -52,13 +52,13 @@ class DrissionElement(object):
def prev(self):
return
@property
def css_path(self):
return
@property
def xpath(self):
return
# @property
# def css_path(self):
# return
#
# @property
# def xpath(self):
# return
@abstractmethod
def ele(self, loc: Union[tuple, str], mode: str = None, show_errmsg: bool = True):
@ -68,9 +68,9 @@ class DrissionElement(object):
def eles(self, loc: Union[tuple, str], show_errmsg: bool = True):
pass
@abstractmethod
def attr(self, attr: str):
pass
# @abstractmethod
# def attr(self, attr: str):
# pass
def get_loc_from_str(loc: str) -> tuple:

View File

@ -127,7 +127,7 @@ class DriverElement(DrissionElement):
def shadow_root(self):
e = self.run_script('return arguments[0].shadowRoot')
if e:
from shadow_root_element import ShadowRootElement
from .shadow_root_element import ShadowRootElement
return ShadowRootElement(e, self)
else:
return None

View File

@ -5,26 +5,89 @@ from typing import Union, Any
from selenium.webdriver.remote.webelement import WebElement
from common import DrissionElement
# from driver_element import DriverElement
from .common import DrissionElement, get_loc_from_str
from .driver_element import execute_driver_find
class ShadowRootElement(DrissionElement):
def __init__(self, inner_ele: WebElement, parent_ele):
def __init__(self, inner_ele: WebElement, parent_ele, timeout: float = 10):
super().__init__(inner_ele)
self.parent_ele = parent_ele
self.timeout = timeout
self._driver = inner_ele.parent
def ele(self, loc: Union[tuple, str], mode: str = None, show_errmsg: bool = True):
pass
@property
def driver(self):
"""返回控制元素的WebDriver对象"""
return self._driver
@property
def tag(self):
return 'shadow-root'
@property
def html(self):
return unescape(self.inner_ele.get_attribute('innerHTML')).replace('\xa0', ' ')
@property
def parent(self):
return self.parent_ele
def parents(self, num: int = 1):
"""返回上面第num级父元素 \n
:param num: 第几级父元素
:return: DriverElement对象
"""
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
def ele(self,
loc_or_str: Union[tuple, str],
mode: str = None,
timeout: float = None,
show_errmsg: bool = False):
if isinstance(loc_or_str, str):
loc_or_str = get_loc_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]}'
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 attr(self, attr: str):
return self.html if attr == 'innerHTML' else None
def run_script(self, script: str, *args) -> Any:
"""执行js代码传入自己为第一个参数 \n
:param script: js文本
@ -33,14 +96,6 @@ class ShadowRootElement(DrissionElement):
"""
return self.inner_ele.parent.execute_script(script, self.inner_ele, *args)
@property
def html(self):
return unescape(self.attr('innerHTML')).replace('\xa0', ' ')
@property
def parent(self):
return self.parent_ele
def is_enabled(self) -> bool:
"""是否可用"""
return self.inner_ele.is_enabled()