未完成

This commit is contained in:
g1879 2020-04-27 18:44:40 +08:00
parent 315cf6085a
commit 1daadf25d4
4 changed files with 90 additions and 36 deletions

View File

@ -104,7 +104,13 @@ class DriverPage(object):
"""查找符合条件的所有元素"""
return self.find(loc, mode='all', timeout=timeout, show_errmsg=show_errmsg)
def search(self, value: str, mode: str = None, timeout: float = 10):
def search(self, value: str, mode: str = None, timeout: float = 10) -> Union[WebElement, list, None]:
"""根据内容搜索元素
:param value: 搜索内容
:param mode: 可选'single','all'
:param timeout: 超时时间
:return: 页面元素对象
"""
mode = mode if mode else 'single'
if mode not in ['single', 'all']:
raise ValueError("mode须在'single', 'all'中选择")
@ -118,9 +124,13 @@ class DriverPage(object):
ele = wait.until(EC.presence_of_all_elements_located(loc))
return ele
except:
return ele
if mode == 'single':
return None
elif mode == 'all':
return []
def search_all(self, value: str, timeout: float = 10):
def search_all(self, value: str, timeout: float = 10) -> list:
"""根据内容搜索元素"""
return self.search(value, mode='all', timeout=timeout)
def get_attr(self, loc_or_ele: Union[WebElement, tuple], attr: str) -> str:

View File

@ -1,5 +1,9 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@Author : g1879
@Contact : g1879@qq.com
@File : mix_page.py
"""
import re
from html import unescape
from time import sleep
@ -8,6 +12,7 @@ from typing import Union
from requests_html import Element
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.wait import WebDriverWait
from .config import global_tmp_path
@ -19,18 +24,21 @@ class MixElement(object):
self._ele = ele
@property
def ele(self):
def ele(self) -> Union[WebElement, Element]:
"""返回元素对象"""
return self._ele
@property
def text(self):
def text(self) -> str:
"""元素内文本"""
if isinstance(self._ele, Element):
return unescape(self._ele.text).replace('\xa0', ' ')
else:
return unescape(self.attr('innerText')).replace('\xa0', ' ')
@property
def html(self):
def html(self) -> str:
"""元素innerHTML"""
if isinstance(self._ele, Element):
html = unescape(self._ele.html).replace('\xa0', ' ')
r = re.match(r'<.*?>(.*)</.*?>', html, flags=re.DOTALL)
@ -39,7 +47,8 @@ class MixElement(object):
return unescape(self.attr('innerHTML')).replace('\xa0', ' ')
@property
def tag_name(self):
def tag_name(self) -> str:
"""获取标签名"""
if isinstance(self._ele, Element):
html = unescape(self._ele.html).replace('\xa0', ' ')
r = re.match(r'^<(.*?)\s+', html, flags=re.DOTALL)
@ -47,7 +56,8 @@ class MixElement(object):
else:
return self._ele.tag_name
def attr(self, attr):
def attr(self, attr) -> str:
"""获取属性值"""
if isinstance(self._ele, Element):
try:
if attr == 'href':
@ -67,26 +77,28 @@ class MixElement(object):
else:
return self._ele.get_attribute(attr)
def find(self, loc: tuple, mode: str = None, show_errmsg: bool = True):
def find(self, loc: tuple, mode: str = None, show_errmsg: bool = True) -> Union[WebElement, Element, list, None]:
"""根据loc获取元素"""
if isinstance(self._ele, Element):
mode = mode if mode else 'single'
if mode not in ['single', 'all']:
raise ValueError("mode须在'single', 'all'中选择")
loc_by, loc_str = _translate_loc(loc)
msg = first = None
msg = ele = None
try:
if mode == 'single':
msg = '未找到元素'
first = True
if loc_by == 'xpath':
ele = MixElement(self.ele.xpath(loc_str, first=True, _encoding='utf-8'))
else:
ele = MixElement(self.ele.find(loc_str, first=True, _encoding='utf-8'))
elif mode == 'all':
msg = '未找到元素s'
first = False
if loc_by == 'xpath':
ele = self.ele.xpath(loc_str, first=first, _encoding='utf-8')
else:
ele = self.ele.find(loc_str, first=first, _encoding='utf-8')
return MixElement(ele)
if loc_by == 'xpath':
ele = self.ele.xpath(loc_str, first=False, _encoding='utf-8')
else:
ele = self.ele.find(loc_str, first=False, _encoding='utf-8')
return ele
except:
if show_errmsg:
print(msg, loc)
@ -103,16 +115,18 @@ class MixElement(object):
ele = wait.until(EC.presence_of_element_located(loc))
elif mode == 'all':
msg = '未找到元素s'
ele = wait.until(EC.presence_of_all_elements_located(loc))
ele = MixElement(wait.until(EC.presence_of_all_elements_located(loc)))
elif mode == 'visible':
msg = '元素不可见或不存在'
ele = wait.until(EC.visibility_of_element_located(loc))
return MixElement(ele)
return ele
except:
if show_errmsg:
print(msg, loc)
raise
def find_all(self, loc: tuple, show_errmsg: bool = True):
def find_all(self, loc: tuple, show_errmsg: bool = True) -> list:
"""根据loc获取子元素列表"""
return self.find(loc, mode='all', show_errmsg=show_errmsg)
def search(self, value: str, mode: str = None):
@ -143,11 +157,12 @@ class MixElement(object):
except:
return None
def search_all(self, value: str):
def search_all(self, value: str) -> list:
"""根据内容获取元素列表"""
return self.search(value, mode='all')
# -----------------以下为d模式独占-------------------
def click(self):
def click(self) -> bool:
"""点击"""
for _ in range(10):
try:
@ -164,7 +179,8 @@ class MixElement(object):
except:
raise
def input(self, value, clear: bool = True):
def input(self, value, clear: bool = True) -> bool:
"""输入文本"""
try:
if clear:
self.run_script("arguments[0].value=''")
@ -174,32 +190,41 @@ class MixElement(object):
raise
def run_script(self, script: str):
"""运行js"""
self.ele.parent.execute_script(script, self.ele)
def submit(self):
"""提交表单"""
self.ele.submit()
def clear(self):
"""清空元素"""
self.ele.clear()
def is_selected(self):
def is_selected(self) -> bool:
"""是否选中"""
return self.ele.is_selected()
def is_enabled(self):
def is_enabled(self) -> bool:
"""是否可用"""
return self.ele.is_enabled()
def is_displayed(self):
def is_displayed(self) -> bool:
"""是否可见"""
return self.ele.is_displayed()
@property
def size(self):
"""元素大小"""
return self.ele.size
@property
def location(self):
"""元素坐标"""
return self.ele.location
def screenshot(self, path: str = None, filename: str = None):
def screenshot(self, path: str = None, filename: str = None) -> str:
"""元素截图"""
path = path if path else global_tmp_path
name = filename if filename else self.tag_name
# 等待元素加载完成
@ -212,10 +237,16 @@ class MixElement(object):
self.ele.screenshot(img_path)
return img_path
def select(self, value: str):
pass
def select(self, text: str):
"""选择下拉列表"""
ele = Select(self.ele)
try:
ele.select_by_visible_text(text)
return True
except:
return False
def set_attr(self, attr, value):
def set_attr(self, attr, value) -> bool:
"""设置元素属性"""
try:
self.run_script(f"arguments[0].{attr} = '{value}';")

View File

@ -183,13 +183,20 @@ class MixPage(Null, SessionPage, DriverPage):
elif self._mode == 'd':
return super(SessionPage, self).find_all(loc, timeout=timeout, show_errmsg=show_errmsg)
def search(self, value: str, mode: str = None, timeout: float = 10):
def search(self, value: str, mode: str = None, timeout: float = 10) -> Union[WebElement, Element, None]:
"""根据内容搜索元素
:param value: 搜索内容
:param mode: 可选'single','all'
:param timeout: 超时时间
:return: 页面元素对象s模式下返回Elementd模式下返回WebElement
"""
if self._mode == 's':
return super().search(value, mode=mode)
elif self._mode == 'd':
return super(SessionPage, self).search(value, mode=mode, timeout=timeout)
def search_all(self, value: str, timeout: float = 10):
def search_all(self, value: str, timeout: float = 10) -> list:
"""根据内容搜索元素"""
if self._mode == 's':
return super().search_all(value)
elif self._mode == 'd':

View File

@ -115,7 +115,12 @@ class SessionPage(object):
"""查找符合条件的所有元素"""
return self.find(loc, mode='all', show_errmsg=True)
def search(self, value: str, mode: str = None):
def search(self, value: str, mode: str = None) -> Union[Element, list, None]:
"""根据内容搜索元素
:param value: 搜索内容
:param mode: 可选'single','all'
:return: 页面元素对象
"""
mode = mode if mode else 'single'
if mode not in ['single', 'all']:
raise ValueError("mode须在'single', 'all'中选择")
@ -127,9 +132,10 @@ class SessionPage(object):
eles = self.response.html.xpath(f'.//*[contains(text(),"{value}")]')
return eles
except:
return None
return
def search_all(self, value: str):
def search_all(self, value: str) -> list:
"""根据内容搜索元素"""
return self.search(value, mode='all')
def _get_ele(self, loc_or_ele: Union[Element, tuple]) -> Element: