mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
元素增加css_path和xpath属性;修复selenium导致的DriverElement不能获取直接子元素的问题
This commit is contained in:
parent
16755abad6
commit
45756a64b3
@ -19,7 +19,6 @@ class DrissionElement(object):
|
|||||||
|
|
||||||
def __init__(self, ele: Union[Element, WebElement]):
|
def __init__(self, ele: Union[Element, WebElement]):
|
||||||
self._inner_ele = ele
|
self._inner_ele = ele
|
||||||
self._xpath = None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def inner_ele(self) -> Union[WebElement, Element]:
|
def inner_ele(self) -> Union[WebElement, Element]:
|
||||||
@ -54,26 +53,12 @@ class DrissionElement(object):
|
|||||||
return
|
return
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def xpath(self):
|
def css_path(self):
|
||||||
self._xpath = self._xpath or self._get_xpath()
|
return
|
||||||
return self._xpath
|
|
||||||
|
|
||||||
def _get_xpath(self):
|
@property
|
||||||
"""获取当前元素xpath字符串"""
|
def xpath(self):
|
||||||
xpath_str = ''
|
return
|
||||||
ele = self
|
|
||||||
while ele:
|
|
||||||
ele_id = ele.attr('id')
|
|
||||||
if ele_id:
|
|
||||||
return f'//{ele.tag}[@id="{ele_id}"]{xpath_str}'
|
|
||||||
else:
|
|
||||||
if 'SessionElement' in str(type(self)):
|
|
||||||
brothers = len(ele.eles(f'xpath:./preceding-sibling::{ele.tag}'))
|
|
||||||
else:
|
|
||||||
brothers = len(ele.eles(f'xpath:./preceding-sibling::{ele.tag}', timeout=0.001))
|
|
||||||
xpath_str = f'/{ele.tag}[{brothers + 1}]{xpath_str}' if brothers > 0 else f'/{ele.tag}{xpath_str}'
|
|
||||||
ele = ele.parent
|
|
||||||
return xpath_str
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def ele(self, loc: Union[tuple, str], mode: str = None, show_errmsg: bool = True):
|
def ele(self, loc: Union[tuple, str], mode: str = None, show_errmsg: bool = True):
|
||||||
|
@ -71,6 +71,58 @@ class DriverElement(DrissionElement):
|
|||||||
"""返回元素类型"""
|
"""返回元素类型"""
|
||||||
return self._inner_ele.tag_name
|
return self._inner_ele.tag_name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def css_path(self) -> str:
|
||||||
|
js = '''
|
||||||
|
function e(el) {
|
||||||
|
if (!(el instanceof Element)) return;
|
||||||
|
var path = '';
|
||||||
|
while (el.nodeType === Node.ELEMENT_NODE) {
|
||||||
|
if (el.id) {
|
||||||
|
return '#' + el.id + path;
|
||||||
|
} else {
|
||||||
|
var sib = el, nth = 0;
|
||||||
|
while (sib) {
|
||||||
|
if(sib.nodeType === Node.ELEMENT_NODE){nth += 1;}
|
||||||
|
sib = sib.previousSibling;
|
||||||
|
}
|
||||||
|
path = '>' + ":nth-child(" + nth + ")" + path;
|
||||||
|
}
|
||||||
|
el = el.parentNode;
|
||||||
|
}
|
||||||
|
return path.substr(1);
|
||||||
|
}
|
||||||
|
return e(arguments[0]);
|
||||||
|
'''
|
||||||
|
return self.run_script(js)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def xpath(self) -> str:
|
||||||
|
js = '''
|
||||||
|
function e(el) {
|
||||||
|
if (!(el instanceof Element)) return;
|
||||||
|
var path = '';
|
||||||
|
while (el.nodeType === Node.ELEMENT_NODE) {
|
||||||
|
var tag = el.nodeName.toLowerCase();
|
||||||
|
if (el.id) {
|
||||||
|
return '//' + tag + '[@id="' + el.id + '"]' + path;
|
||||||
|
} else {
|
||||||
|
var sib = el, nth = 0;
|
||||||
|
while (sib) {
|
||||||
|
if(sib.nodeType === Node.ELEMENT_NODE && sib.nodeName.toLowerCase()==tag){nth += 1;}
|
||||||
|
sib = sib.previousSibling;
|
||||||
|
}
|
||||||
|
if(nth>1){path = '/' + tag + '[' + nth + ']' + path;}
|
||||||
|
else{path = '/' + tag + path;}
|
||||||
|
}
|
||||||
|
el = el.parentNode;
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
return e(arguments[0]);
|
||||||
|
'''
|
||||||
|
return self.run_script(js)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def parent(self):
|
def parent(self):
|
||||||
"""返回父级元素"""
|
"""返回父级元素"""
|
||||||
@ -165,7 +217,7 @@ class DriverElement(DrissionElement):
|
|||||||
loc_or_str = loc_or_str[0], loc_str
|
loc_or_str = loc_or_str[0], loc_str
|
||||||
else:
|
else:
|
||||||
if loc_or_str[1].lstrip().startswith('>'):
|
if loc_or_str[1].lstrip().startswith('>'):
|
||||||
raise ValueError('WebElement does not support getting direct child elements.')
|
loc_or_str = loc_or_str[0], f'{self.css_path}{loc_or_str[1]}'
|
||||||
|
|
||||||
timeout = timeout or self.timeout
|
timeout = timeout or self.timeout
|
||||||
return execute_driver_find(self.inner_ele, loc_or_str, mode, show_errmsg, timeout)
|
return execute_driver_find(self.inner_ele, loc_or_str, mode, show_errmsg, timeout)
|
||||||
|
@ -48,6 +48,34 @@ class SessionElement(DrissionElement):
|
|||||||
"""返回元素类型"""
|
"""返回元素类型"""
|
||||||
return self._inner_ele.tag
|
return self._inner_ele.tag
|
||||||
|
|
||||||
|
@property
|
||||||
|
def css_path(self) -> str:
|
||||||
|
"""返回css path路径"""
|
||||||
|
return self._get_ele_path('css')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def xpath(self) -> str:
|
||||||
|
"""返回xpath路径"""
|
||||||
|
return self._get_ele_path('xpath')
|
||||||
|
|
||||||
|
def _get_ele_path(self, mode):
|
||||||
|
"""获取css路径或xpath路径"""
|
||||||
|
path_str = ''
|
||||||
|
ele = self
|
||||||
|
while ele:
|
||||||
|
ele_id = ele.attr('id')
|
||||||
|
if ele_id:
|
||||||
|
return f'#{ele_id}{path_str}' if mode == 'css' else f'//{ele.tag}[@id="{ele_id}"]{path_str}'
|
||||||
|
else:
|
||||||
|
if mode == 'css':
|
||||||
|
brothers = len(ele.eles(f'xpath:./preceding-sibling::*'))
|
||||||
|
path_str = f'>:nth-child({brothers + 1}){path_str}'
|
||||||
|
else:
|
||||||
|
brothers = len(ele.eles(f'xpath:./preceding-sibling::{ele.tag}'))
|
||||||
|
path_str = f'/{ele.tag}[{brothers + 1}]{path_str}' if brothers > 0 else f'/{ele.tag}{path_str}'
|
||||||
|
ele = ele.parent
|
||||||
|
return path_str[1:] if mode == 'css' else path_str
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def parent(self):
|
def parent(self):
|
||||||
"""返回父级元素"""
|
"""返回父级元素"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user