mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
自动等待填写上传路径;增加remove_ele()方法;新加载的iframe自动等待完成;wait增加input_upload_paths()
This commit is contained in:
parent
76920e05d8
commit
0a73226c4f
@ -16,7 +16,7 @@ from .chromium_element import ChromiumWaiter, ChromiumScroll, ChromiumElement, r
|
|||||||
ChromiumElementWaiter
|
ChromiumElementWaiter
|
||||||
from .common.constants import HANDLE_ALERT_METHOD, ERROR, NoneElement
|
from .common.constants import HANDLE_ALERT_METHOD, ERROR, NoneElement
|
||||||
from .common.errors import ContextLossError, ElementLossError, AlertExistsError, CallMethodError, TabClosedError, \
|
from .common.errors import ContextLossError, ElementLossError, AlertExistsError, CallMethodError, TabClosedError, \
|
||||||
NoRectError
|
NoRectError, ElementNotFoundError
|
||||||
from .common.locator import get_loc
|
from .common.locator import get_loc
|
||||||
from .common.tools import get_usable_path
|
from .common.tools import get_usable_path
|
||||||
from .common.web import offset_scroll, cookies_to_tuple
|
from .common.web import offset_scroll, cookies_to_tuple
|
||||||
@ -212,7 +212,10 @@ class ChromiumBase(BasePage):
|
|||||||
if self._upload_list:
|
if self._upload_list:
|
||||||
files = self._upload_list if kwargs['mode'] == 'selectMultiple' else self._upload_list[:1]
|
files = self._upload_list if kwargs['mode'] == 'selectMultiple' else self._upload_list[:1]
|
||||||
self.run_cdp('DOM.setFileInputFiles', files=files, backendNodeId=kwargs['backendNodeId'])
|
self.run_cdp('DOM.setFileInputFiles', files=files, backendNodeId=kwargs['backendNodeId'])
|
||||||
self._upload_list = []
|
|
||||||
|
self.driver.Page.fileChooserOpened = None
|
||||||
|
self.run_cdp('Page.setInterceptFileChooserDialog', enabled=False)
|
||||||
|
self._upload_list = None
|
||||||
|
|
||||||
def __call__(self, loc_or_str, timeout=None):
|
def __call__(self, loc_or_str, timeout=None):
|
||||||
"""在内部查找元素
|
"""在内部查找元素
|
||||||
@ -233,8 +236,7 @@ class ChromiumBase(BasePage):
|
|||||||
@property
|
@property
|
||||||
def _wait_driver(self):
|
def _wait_driver(self):
|
||||||
"""返回用于控制浏览器的ChromiumDriver对象,会先等待页面加载完毕"""
|
"""返回用于控制浏览器的ChromiumDriver对象,会先等待页面加载完毕"""
|
||||||
while self._is_loading:
|
self.wait.load_complete()
|
||||||
sleep(.1)
|
|
||||||
return self.driver
|
return self.driver
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -461,6 +463,8 @@ class ChromiumBase(BasePage):
|
|||||||
loc = get_loc(loc_or_ele)[1]
|
loc = get_loc(loc_or_ele)[1]
|
||||||
elif isinstance(loc_or_ele, ChromiumElement) or str(type(loc_or_ele)).endswith(".ChromiumFrame'>"):
|
elif isinstance(loc_or_ele, ChromiumElement) or str(type(loc_or_ele)).endswith(".ChromiumFrame'>"):
|
||||||
return loc_or_ele
|
return loc_or_ele
|
||||||
|
elif not loc_or_ele:
|
||||||
|
raise ElementNotFoundError
|
||||||
else:
|
else:
|
||||||
raise ValueError('loc_or_str参数只能是tuple、str、ChromiumElement类型。')
|
raise ValueError('loc_or_str参数只能是tuple、str、ChromiumElement类型。')
|
||||||
|
|
||||||
@ -557,6 +561,17 @@ class ChromiumBase(BasePage):
|
|||||||
while self.ready_state != 'complete':
|
while self.ready_state != 'complete':
|
||||||
sleep(.1)
|
sleep(.1)
|
||||||
|
|
||||||
|
def remove_ele(self, loc_or_ele):
|
||||||
|
"""从页面上删除一个元素
|
||||||
|
:param loc_or_ele: 元素对象或定位符
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
if not loc_or_ele:
|
||||||
|
return
|
||||||
|
ele = self._ele(loc_or_ele)
|
||||||
|
if ele:
|
||||||
|
self.run_cdp('DOM.removeNode', nodeId=ele.ids.node_id)
|
||||||
|
|
||||||
def get_session_storage(self, item=None):
|
def get_session_storage(self, item=None):
|
||||||
"""获取sessionStorage信息,不设置item则获取全部
|
"""获取sessionStorage信息,不设置item则获取全部
|
||||||
:param item: 要获取的项,不设置则返回全部
|
:param item: 要获取的项,不设置则返回全部
|
||||||
@ -850,7 +865,7 @@ class ChromiumBaseSetter(object):
|
|||||||
:param files: 文件路径列表或字符串,字符串时多个文件用回车分隔
|
:param files: 文件路径列表或字符串,字符串时多个文件用回车分隔
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
if self._page._upload_list is None:
|
if not self._page._upload_list:
|
||||||
self._page.driver.Page.fileChooserOpened = self._page._onFileChooserOpened
|
self._page.driver.Page.fileChooserOpened = self._page._onFileChooserOpened
|
||||||
self._page.run_cdp('Page.setInterceptFileChooserDialog', enabled=True)
|
self._page.run_cdp('Page.setInterceptFileChooserDialog', enabled=True)
|
||||||
|
|
||||||
@ -885,7 +900,7 @@ class ChromiumPageWaiter(ChromiumWaiter):
|
|||||||
while perf_counter() < end_time:
|
while perf_counter() < end_time:
|
||||||
if self._driver.is_loading == start:
|
if self._driver.is_loading == start:
|
||||||
return True
|
return True
|
||||||
sleep(.005)
|
sleep(.01)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def load_start(self, timeout=None):
|
def load_start(self, timeout=None):
|
||||||
@ -902,6 +917,11 @@ class ChromiumPageWaiter(ChromiumWaiter):
|
|||||||
"""
|
"""
|
||||||
return self._loading(timeout=timeout, start=False)
|
return self._loading(timeout=timeout, start=False)
|
||||||
|
|
||||||
|
def input_upload_paths(self):
|
||||||
|
"""等待自动填写上传文件路径"""
|
||||||
|
while self._driver._upload_list:
|
||||||
|
sleep(.01)
|
||||||
|
|
||||||
|
|
||||||
class ChromiumPageScroll(ChromiumScroll):
|
class ChromiumPageScroll(ChromiumScroll):
|
||||||
def __init__(self, page):
|
def __init__(self, page):
|
||||||
|
@ -13,7 +13,7 @@ from requests.cookies import RequestsCookieJar
|
|||||||
from .common.constants import NoneElement
|
from .common.constants import NoneElement
|
||||||
from .base import BasePage
|
from .base import BasePage
|
||||||
from .chromium_driver import ChromiumDriver
|
from .chromium_driver import ChromiumDriver
|
||||||
from .chromium_element import ChromiumElement, ChromiumScroll, ChromiumElementWaiter, ChromiumWaiter
|
from .chromium_element import ChromiumElement, ChromiumScroll, ChromiumWaiter
|
||||||
from .chromium_frame import ChromiumFrame
|
from .chromium_frame import ChromiumFrame
|
||||||
from .session_element import SessionElement
|
from .session_element import SessionElement
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ class ChromiumBase(BasePage):
|
|||||||
def _set_runtime_settings(self) -> None: ...
|
def _set_runtime_settings(self) -> None: ...
|
||||||
|
|
||||||
def __call__(self, loc_or_str: Union[Tuple[str, str], str, ChromiumElement],
|
def __call__(self, loc_or_str: Union[Tuple[str, str], str, ChromiumElement],
|
||||||
timeout: float = None) -> Union[ChromiumElement, ChromiumFrame, None]: ...
|
timeout: float = None) -> Union[ChromiumElement, ChromiumFrame, NoneElement]: ...
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def title(self) -> str: ...
|
def title(self) -> str: ...
|
||||||
@ -164,6 +164,8 @@ class ChromiumBase(BasePage):
|
|||||||
|
|
||||||
def stop_loading(self) -> None: ...
|
def stop_loading(self) -> None: ...
|
||||||
|
|
||||||
|
def remove_ele(self, loc_or_ele: Union[ChromiumElement, ChromiumFrame, str, Tuple[str, str]]) -> None: ...
|
||||||
|
|
||||||
def run_cdp(self, cmd: str, **cmd_args) -> dict: ...
|
def run_cdp(self, cmd: str, **cmd_args) -> dict: ...
|
||||||
|
|
||||||
def run_cdp_loaded(self, cmd: str, **cmd_args) -> dict: ...
|
def run_cdp_loaded(self, cmd: str, **cmd_args) -> dict: ...
|
||||||
@ -202,6 +204,8 @@ class ChromiumPageWaiter(ChromiumWaiter):
|
|||||||
|
|
||||||
def load_complete(self, timeout: Union[int, float] = None) -> bool: ...
|
def load_complete(self, timeout: Union[int, float] = None) -> bool: ...
|
||||||
|
|
||||||
|
def input_upload_paths(self) -> None: ...
|
||||||
|
|
||||||
|
|
||||||
class ChromiumPageScroll(ChromiumScroll):
|
class ChromiumPageScroll(ChromiumScroll):
|
||||||
def __init__(self, page: ChromiumBase): ...
|
def __init__(self, page: ChromiumBase): ...
|
||||||
|
@ -4,11 +4,12 @@
|
|||||||
@Contact : g1879@qq.com
|
@Contact : g1879@qq.com
|
||||||
"""
|
"""
|
||||||
from re import search
|
from re import search
|
||||||
from time import sleep
|
from time import sleep, perf_counter
|
||||||
from warnings import warn
|
from warnings import warn
|
||||||
|
|
||||||
from .chromium_base import ChromiumBase, ChromiumPageScroll, ChromiumBaseSetter
|
from .chromium_base import ChromiumBase, ChromiumPageScroll, ChromiumBaseSetter
|
||||||
from .chromium_element import ChromiumElement
|
from .chromium_element import ChromiumElement
|
||||||
|
from .common.errors import ElementNotFoundError
|
||||||
|
|
||||||
|
|
||||||
class ChromiumFrame(ChromiumBase):
|
class ChromiumFrame(ChromiumBase):
|
||||||
@ -32,6 +33,10 @@ class ChromiumFrame(ChromiumBase):
|
|||||||
self.doc_ele = ChromiumElement(self, obj_id=obj_id)
|
self.doc_ele = ChromiumElement(self, obj_id=obj_id)
|
||||||
self._ids = ChromiumFrameIds(self)
|
self._ids = ChromiumFrameIds(self)
|
||||||
|
|
||||||
|
end_time = perf_counter() + 2
|
||||||
|
while perf_counter() < end_time and self.url == 'about:blank':
|
||||||
|
sleep(.1)
|
||||||
|
|
||||||
def __call__(self, loc_or_str, timeout=None):
|
def __call__(self, loc_or_str, timeout=None):
|
||||||
"""在内部查找元素
|
"""在内部查找元素
|
||||||
例:ele2 = ele1('@id=ele_id')
|
例:ele2 = ele1('@id=ele_id')
|
||||||
@ -79,7 +84,7 @@ class ChromiumFrame(ChromiumBase):
|
|||||||
self.doc_ele = ChromiumElement(self, obj_id=obj_id)
|
self.doc_ele = ChromiumElement(self, obj_id=obj_id)
|
||||||
|
|
||||||
def _check_ok(self):
|
def _check_ok(self):
|
||||||
""""""
|
"""检查iframe元素是否还能使用,不能使用则重新加载"""
|
||||||
if self._tab_obj._stopped.is_set():
|
if self._tab_obj._stopped.is_set():
|
||||||
self._reload()
|
self._reload()
|
||||||
|
|
||||||
@ -383,11 +388,13 @@ class ChromiumFrame(ChromiumBase):
|
|||||||
:param timeout: 查找超时时间
|
:param timeout: 查找超时时间
|
||||||
:return: ChromiumElement对象
|
:return: ChromiumElement对象
|
||||||
"""
|
"""
|
||||||
|
if not loc_or_ele:
|
||||||
|
raise ElementNotFoundError
|
||||||
|
|
||||||
if isinstance(loc_or_ele, ChromiumElement):
|
if isinstance(loc_or_ele, ChromiumElement):
|
||||||
return loc_or_ele
|
return loc_or_ele
|
||||||
|
|
||||||
while self.is_loading:
|
self.wait.load_complete()
|
||||||
sleep(.05)
|
|
||||||
|
|
||||||
return self.doc_ele.ele(loc_or_ele, timeout) if single else self.doc_ele.eles(loc_or_ele, timeout)
|
return self.doc_ele.ele(loc_or_ele, timeout) if single else self.doc_ele.eles(loc_or_ele, timeout)
|
||||||
|
|
||||||
@ -409,8 +416,7 @@ class ChromiumFrame(ChromiumBase):
|
|||||||
result = self.driver.Page.navigate(url=to_url, frameId=self.frame_id)
|
result = self.driver.Page.navigate(url=to_url, frameId=self.frame_id)
|
||||||
|
|
||||||
is_timeout = not self._wait_loaded(timeout)
|
is_timeout = not self._wait_loaded(timeout)
|
||||||
while self.is_loading:
|
self.wait.load_complete()
|
||||||
sleep(.1)
|
|
||||||
|
|
||||||
if is_timeout:
|
if is_timeout:
|
||||||
err = TimeoutError('页面连接超时。')
|
err = TimeoutError('页面连接超时。')
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# -*- coding:utf-8 -*-
|
# -*- coding:utf-8 -*-
|
||||||
from .errors import NotElementFoundError
|
from .errors import ElementNotFoundError
|
||||||
|
|
||||||
HANDLE_ALERT_METHOD = 'Page.handleJavaScriptDialog'
|
HANDLE_ALERT_METHOD = 'Page.handleJavaScriptDialog'
|
||||||
FRAME_ELEMENT = ('iframe', 'frame')
|
FRAME_ELEMENT = ('iframe', 'frame')
|
||||||
@ -9,16 +9,16 @@ ERROR = 'error'
|
|||||||
class NoneElement(object):
|
class NoneElement(object):
|
||||||
_instance = None
|
_instance = None
|
||||||
|
|
||||||
def __new__(cls, *args, **kwargs):
|
def __new__(cls):
|
||||||
if not cls._instance:
|
if not cls._instance:
|
||||||
cls._instance = super(NoneElement, cls).__new__(cls, *args, **kwargs)
|
cls._instance = super(NoneElement, cls).__new__(cls)
|
||||||
return cls._instance
|
return cls._instance
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
def __call__(self, *args, **kwargs):
|
||||||
raise NotElementFoundError
|
raise ElementNotFoundError
|
||||||
|
|
||||||
def __getattr__(self, item):
|
def __getattr__(self, item):
|
||||||
raise NotElementFoundError
|
raise ElementNotFoundError
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if other is None:
|
if other is None:
|
||||||
|
@ -21,7 +21,7 @@ class ContextLossError(BaseError):
|
|||||||
|
|
||||||
|
|
||||||
class ElementLossError(BaseError):
|
class ElementLossError(BaseError):
|
||||||
_info = '该元素对象已不在当前页面中。'
|
_info = '页面内无此对象,可能因刷新已失效。'
|
||||||
|
|
||||||
|
|
||||||
class CallMethodError(BaseError):
|
class CallMethodError(BaseError):
|
||||||
@ -32,7 +32,7 @@ class TabClosedError(BaseError):
|
|||||||
_info = '标签页已关闭。'
|
_info = '标签页已关闭。'
|
||||||
|
|
||||||
|
|
||||||
class NotElementFoundError(BaseError):
|
class ElementNotFoundError(BaseError):
|
||||||
_info = '没有找到元素。'
|
_info = '没有找到元素。'
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,11 +10,11 @@ from typing import Union
|
|||||||
|
|
||||||
from selenium import webdriver
|
from selenium import webdriver
|
||||||
|
|
||||||
|
from DrissionPage.mixpage.drission import Drission
|
||||||
|
from .common.tools import unzip
|
||||||
from .configs.chromium_options import ChromiumOptions
|
from .configs.chromium_options import ChromiumOptions
|
||||||
from .configs.driver_options import DriverOptions
|
from .configs.driver_options import DriverOptions
|
||||||
from .configs.options_manage import OptionsManager
|
from .configs.options_manage import OptionsManager
|
||||||
from DrissionPage.mixpage.drission import Drission
|
|
||||||
from .common.tools import unzip
|
|
||||||
from .session_page import SessionPage
|
from .session_page import SessionPage
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,8 +14,9 @@ from requests.structures import CaseInsensitiveDict
|
|||||||
from tldextract import extract
|
from tldextract import extract
|
||||||
|
|
||||||
from .base import BasePage
|
from .base import BasePage
|
||||||
from .configs.session_options import SessionOptions
|
from .common.errors import ElementNotFoundError
|
||||||
from .common.web import cookie_to_dict, set_session_cookies
|
from .common.web import cookie_to_dict, set_session_cookies
|
||||||
|
from .configs.session_options import SessionOptions
|
||||||
from .session_element import SessionElement, make_session_ele
|
from .session_element import SessionElement, make_session_ele
|
||||||
|
|
||||||
|
|
||||||
@ -199,6 +200,8 @@ class SessionPage(BasePage):
|
|||||||
:param single: True则返回第一个,False则返回全部
|
:param single: True则返回第一个,False则返回全部
|
||||||
:return: SessionElement对象
|
:return: SessionElement对象
|
||||||
"""
|
"""
|
||||||
|
if not loc_or_ele:
|
||||||
|
raise ElementNotFoundError
|
||||||
return loc_or_ele if isinstance(loc_or_ele, SessionElement) else make_session_ele(self, loc_or_ele, single)
|
return loc_or_ele if isinstance(loc_or_ele, SessionElement) else make_session_ele(self, loc_or_ele, single)
|
||||||
|
|
||||||
def get_cookies(self, as_dict=False, all_domains=False):
|
def get_cookies(self, as_dict=False, all_domains=False):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user