mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
DriverElement添加page属性,指向所属页面对象,并取消driver属性
This commit is contained in:
parent
c9eae68acb
commit
1d9489b6ef
@ -22,20 +22,14 @@ from .common import DrissionElement, get_loc_from_str, get_available_file_name,
|
|||||||
class DriverElement(DrissionElement):
|
class DriverElement(DrissionElement):
|
||||||
"""driver模式的元素对象,包装了一个WebElement对象,并封装了常用功能"""
|
"""driver模式的元素对象,包装了一个WebElement对象,并封装了常用功能"""
|
||||||
|
|
||||||
def __init__(self, ele: WebElement, timeout: float = 10):
|
def __init__(self, ele: WebElement, page, timeout: float = 10):
|
||||||
super().__init__(ele)
|
super().__init__(ele, page)
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
self._driver = ele.parent
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
attrs = [f"{attr}='{self.attrs[attr]}'" for attr in self.attrs]
|
attrs = [f"{attr}='{self.attrs[attr]}'" for attr in self.attrs]
|
||||||
return f'<DriverElement {self.tag} {" ".join(attrs)}>'
|
return f'<DriverElement {self.tag} {" ".join(attrs)}>'
|
||||||
|
|
||||||
@property
|
|
||||||
def driver(self) -> WebDriver:
|
|
||||||
"""返回控制元素的WebDriver对象"""
|
|
||||||
return self._driver
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def attrs(self) -> dict:
|
def attrs(self) -> dict:
|
||||||
"""返回元素所有属性及值"""
|
"""返回元素所有属性及值"""
|
||||||
@ -261,16 +255,18 @@ class DriverElement(DrissionElement):
|
|||||||
# 处理语句最前面的(
|
# 处理语句最前面的(
|
||||||
brackets = len(re.match(r'\(*', loc_or_str[1]).group(0))
|
brackets = len(re.match(r'\(*', loc_or_str[1]).group(0))
|
||||||
bracket, loc_str = '(' * brackets, loc_or_str[1][brackets:]
|
bracket, loc_str = '(' * brackets, loc_or_str[1][brackets:]
|
||||||
|
|
||||||
# 确保查询语句最前面是.
|
# 确保查询语句最前面是.
|
||||||
loc_str = loc_str if loc_str.startswith(('.', '/')) else f'.//{loc_str}'
|
loc_str = loc_str if loc_str.startswith(('.', '/')) else f'.//{loc_str}'
|
||||||
loc_str = loc_str if loc_str.startswith('.') else f'.{loc_str}'
|
loc_str = loc_str if loc_str.startswith('.') else f'.{loc_str}'
|
||||||
loc_or_str = loc_or_str[0], f'{bracket}{loc_str}'
|
loc_or_str = loc_or_str[0], f'{bracket}{loc_str}'
|
||||||
|
|
||||||
elif loc_or_str[0] == 'css selector':
|
elif loc_or_str[0] == 'css selector':
|
||||||
if loc_or_str[1].lstrip().startswith('>'):
|
if loc_or_str[1].lstrip().startswith('>'):
|
||||||
loc_or_str = loc_or_str[0], f'{self.css_path}{loc_or_str[1]}'
|
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, loc_or_str, mode, show_errmsg, timeout)
|
||||||
|
|
||||||
def eles(self,
|
def eles(self,
|
||||||
loc_or_str: Union[Tuple[str, str], str],
|
loc_or_str: Union[Tuple[str, str], str],
|
||||||
@ -473,7 +469,7 @@ class DriverElement(DrissionElement):
|
|||||||
|
|
||||||
from selenium.webdriver import ActionChains
|
from selenium.webdriver import ActionChains
|
||||||
from random import randint
|
from random import randint
|
||||||
actions = ActionChains(self.driver)
|
actions = ActionChains(self.page.driver)
|
||||||
actions.click_and_hold(self.inner_ele)
|
actions.click_and_hold(self.inner_ele)
|
||||||
loc1 = self.location
|
loc1 = self.location
|
||||||
for x, y in points: # 逐个访问要经过的点
|
for x, y in points: # 逐个访问要经过的点
|
||||||
@ -489,17 +485,17 @@ class DriverElement(DrissionElement):
|
|||||||
def hover(self) -> None:
|
def hover(self) -> None:
|
||||||
"""鼠标悬停"""
|
"""鼠标悬停"""
|
||||||
from selenium.webdriver import ActionChains
|
from selenium.webdriver import ActionChains
|
||||||
ActionChains(self._driver).move_to_element(self.inner_ele).perform()
|
ActionChains(self.page.driver).move_to_element(self.inner_ele).perform()
|
||||||
|
|
||||||
|
|
||||||
def execute_driver_find(ele_or_driver: Union[WebElement, WebDriver],
|
def execute_driver_find(page_or_ele,
|
||||||
loc: Tuple[str, str],
|
loc: Tuple[str, str],
|
||||||
mode: str = 'single',
|
mode: str = 'single',
|
||||||
show_errmsg: bool = False,
|
show_errmsg: bool = False,
|
||||||
timeout: float = 10) -> Union[DriverElement, List[DriverElement or str]]:
|
timeout: float = 10) -> Union[DriverElement, List[DriverElement or str]]:
|
||||||
"""执行driver模式元素的查找 \n
|
"""执行driver模式元素的查找 \n
|
||||||
页面查找元素及元素查找下级元素皆使用此方法 \n
|
页面查找元素及元素查找下级元素皆使用此方法 \n
|
||||||
:param ele_or_driver: WebDriver对象或WebElement元素对象
|
:param page_or_ele: DriverPage对象或DriverElement对象
|
||||||
:param loc: 元素定位元组
|
:param loc: 元素定位元组
|
||||||
:param mode: 'single' 或 'all',对应获取第一个或全部
|
:param mode: 'single' 或 'all',对应获取第一个或全部
|
||||||
:param show_errmsg: 出现异常时是否显示错误信息
|
:param show_errmsg: 出现异常时是否显示错误信息
|
||||||
@ -510,16 +506,23 @@ def execute_driver_find(ele_or_driver: Union[WebElement, WebDriver],
|
|||||||
if mode not in ['single', 'all']:
|
if mode not in ['single', 'all']:
|
||||||
raise ValueError("Argument mode can only be 'single' or 'all'.")
|
raise ValueError("Argument mode can only be 'single' or 'all'.")
|
||||||
|
|
||||||
|
if isinstance(page_or_ele, DriverElement):
|
||||||
|
page = page_or_ele.page
|
||||||
|
driver = page_or_ele.inner_ele
|
||||||
|
else: # 传入的是DriverPage对象
|
||||||
|
page = page_or_ele
|
||||||
|
driver = page_or_ele.driver
|
||||||
|
|
||||||
try:
|
try:
|
||||||
wait = WebDriverWait(ele_or_driver, timeout=timeout)
|
wait = WebDriverWait(driver, timeout=timeout)
|
||||||
if loc[0] == 'xpath':
|
if loc[0] == 'xpath':
|
||||||
return wait.until(ElementsByXpath(ele_or_driver, loc[1], mode, timeout))
|
return wait.until(ElementsByXpath(page, loc[1], mode, timeout))
|
||||||
else:
|
else:
|
||||||
if mode == 'single':
|
if mode == 'single':
|
||||||
return DriverElement(wait.until(ec.presence_of_element_located(loc)), timeout)
|
return DriverElement(wait.until(ec.presence_of_element_located(loc)), page, timeout)
|
||||||
elif mode == 'all':
|
elif mode == 'all':
|
||||||
eles = wait.until(ec.presence_of_all_elements_located(loc))
|
eles = wait.until(ec.presence_of_all_elements_located(loc))
|
||||||
return [DriverElement(ele, timeout) for ele in eles]
|
return [DriverElement(ele, page, timeout) for ele in eles]
|
||||||
|
|
||||||
except InvalidElementStateException:
|
except InvalidElementStateException:
|
||||||
raise ValueError('Query statement error.', loc)
|
raise ValueError('Query statement error.', loc)
|
||||||
@ -534,19 +537,20 @@ def execute_driver_find(ele_or_driver: Union[WebElement, WebDriver],
|
|||||||
class ElementsByXpath(object):
|
class ElementsByXpath(object):
|
||||||
"""用js通过xpath获取元素、节点或属性,与WebDriverWait配合使用"""
|
"""用js通过xpath获取元素、节点或属性,与WebDriverWait配合使用"""
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self, page, xpath: str = None, mode: str = 'all', timeout: float = 10):
|
||||||
ele_or_driver: Union[WebDriver, WebElement],
|
"""
|
||||||
xpath: str = None,
|
:param page: DrissionPage对象
|
||||||
mode: str = 'all',
|
:param xpath: xpath文本
|
||||||
timeout: float = 10):
|
:param mode: 'all' 或 'single'
|
||||||
self.ele_or_driver = ele_or_driver
|
:param timeout: 超时时间
|
||||||
|
"""
|
||||||
|
self.page = page
|
||||||
self.xpath = xpath
|
self.xpath = xpath
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
|
|
||||||
def __call__(self,
|
def __call__(self, ele_or_driver: Union[WebDriver, WebElement]) \
|
||||||
ele_or_driver: Union[WebDriver, WebElement],
|
-> Union[str, DriverElement, None, List[str or DriverElement]]:
|
||||||
) -> Union[str, DriverElement, None, List[str or DriverElement]]:
|
|
||||||
driver, the_node = (ele_or_driver, 'document') if isinstance(ele_or_driver, WebDriver) \
|
driver, the_node = (ele_or_driver, 'document') if isinstance(ele_or_driver, WebDriver) \
|
||||||
else (ele_or_driver.parent, ele_or_driver)
|
else (ele_or_driver.parent, ele_or_driver)
|
||||||
|
|
||||||
@ -559,17 +563,17 @@ class ElementsByXpath(object):
|
|||||||
"""
|
"""
|
||||||
node_txt = 'document' if not node or node == 'document' else 'arguments[0]'
|
node_txt = 'document' if not node or node == 'document' else 'arguments[0]'
|
||||||
for_txt = ''
|
for_txt = ''
|
||||||
if type_txt == '9': # 获取第一个元素、节点或属性
|
|
||||||
|
# 获取第一个元素、节点或属性
|
||||||
|
if type_txt == '9':
|
||||||
return_txt = '''
|
return_txt = '''
|
||||||
if(e.singleNodeValue.constructor.name=="Text"){return e.singleNodeValue.data;}
|
if(e.singleNodeValue.constructor.name=="Text"){return e.singleNodeValue.data;}
|
||||||
else if(e.singleNodeValue.constructor.name=="Attr"){return e.singleNodeValue.nodeValue;}
|
else if(e.singleNodeValue.constructor.name=="Attr"){return e.singleNodeValue.nodeValue;}
|
||||||
else{return e.singleNodeValue;}
|
else{return e.singleNodeValue;}
|
||||||
'''
|
'''
|
||||||
elif type_txt == '2':
|
|
||||||
return_txt = 'return e.stringValue;'
|
# 按顺序获取所有元素、节点或属性
|
||||||
elif type_txt == '1':
|
elif type_txt == '7':
|
||||||
return_txt = 'return e.numberValue;'
|
|
||||||
elif type_txt == '7': # 按顺序获取所有元素、节点或属性
|
|
||||||
for_txt = """
|
for_txt = """
|
||||||
var a=new Array();
|
var a=new Array();
|
||||||
for(var i = 0; i <e.snapshotLength ; i++){
|
for(var i = 0; i <e.snapshotLength ; i++){
|
||||||
@ -579,6 +583,10 @@ class ElementsByXpath(object):
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
return_txt = 'return a;'
|
return_txt = 'return a;'
|
||||||
|
elif type_txt == '2':
|
||||||
|
return_txt = 'return e.stringValue;'
|
||||||
|
elif type_txt == '1':
|
||||||
|
return_txt = 'return e.numberValue;'
|
||||||
else:
|
else:
|
||||||
return_txt = 'return e.singleNodeValue;'
|
return_txt = 'return e.singleNodeValue;'
|
||||||
js = """
|
js = """
|
||||||
@ -591,12 +599,20 @@ class ElementsByXpath(object):
|
|||||||
if self.mode == 'single':
|
if self.mode == 'single':
|
||||||
try:
|
try:
|
||||||
e = get_nodes(the_node, xpath_txt=self.xpath, type_txt='9')
|
e = get_nodes(the_node, xpath_txt=self.xpath, type_txt='9')
|
||||||
return DriverElement(e, self.timeout) if isinstance(e, WebElement) else unescape(e).replace('\xa0', ' ')
|
return DriverElement(e, self.page, self.timeout) \
|
||||||
except JavascriptException: # 找不到目标时
|
if isinstance(e, WebElement) else unescape(e).replace('\xa0', ' ')
|
||||||
|
|
||||||
|
# 找不到目标时
|
||||||
|
except JavascriptException:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
elif self.mode == 'all':
|
elif self.mode == 'all':
|
||||||
e = get_nodes(the_node, xpath_txt=self.xpath)
|
e = get_nodes(the_node, xpath_txt=self.xpath)
|
||||||
e = filter(lambda x: x != '\n', e) # 去除元素间换行符
|
|
||||||
e = map(lambda x: unescape(x).replace('\xa0', ' ') if isinstance(x, str) else x, e) # 替换空格
|
# 去除元素间换行符
|
||||||
return list(map(lambda x: DriverElement(x, self.timeout) if isinstance(x, WebElement) else x, e))
|
e = filter(lambda x: x != '\n', e)
|
||||||
|
|
||||||
|
# 替换空格
|
||||||
|
e = map(lambda x: unescape(x).replace('\xa0', ' ') if isinstance(x, str) else x, e)
|
||||||
|
|
||||||
|
return list(map(lambda x: DriverElement(x, self.page, self.timeout) if isinstance(x, WebElement) else x, e))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user