ElementLossError改为ElementLostError;修复_reload()小问题;SessionPage和WebPage增加close()

This commit is contained in:
g1879 2023-11-22 15:48:06 +08:00
parent bd18b8e427
commit 8699bc82d3
9 changed files with 55 additions and 29 deletions

View File

@ -22,7 +22,7 @@ from .._units.select_element import SelectElement
from .._units.setter import ChromiumElementSetter from .._units.setter import ChromiumElementSetter
from .._units.states import ElementStates, ShadowRootStates from .._units.states import ElementStates, ShadowRootStates
from .._units.waiter import ElementWaiter from .._units.waiter import ElementWaiter
from ..errors import (ContextLossError, ElementLossError, JavaScriptError, ElementNotFoundError, from ..errors import (ContextLostError, ElementLostError, JavaScriptError, ElementNotFoundError,
CDPError, NoResourceError, AlertExistsError) CDPError, NoResourceError, AlertExistsError)
__FRAME_ELEMENT__ = ('iframe', 'frame') __FRAME_ELEMENT__ = ('iframe', 'frame')
@ -66,7 +66,7 @@ class ChromiumElement(DrissionElement):
self._node_id = self._get_node_id(obj_id=self._obj_id) self._node_id = self._get_node_id(obj_id=self._obj_id)
self._backend_id = backend_id self._backend_id = backend_id
else: else:
raise ElementLossError raise ElementLostError
doc = self.run_js('return this.ownerDocument;') doc = self.run_js('return this.ownerDocument;')
self._doc_id = doc['objectId'] if doc else None self._doc_id = doc['objectId'] if doc else None
@ -1199,7 +1199,7 @@ def make_chromium_ele(page, node_id=None, obj_id=None):
node_id = node['node']['nodeId'] node_id = node['node']['nodeId']
else: else:
raise ElementLossError raise ElementLostError
ele = ChromiumElement(page, obj_id=obj_id, node_id=node_id, backend_id=backend_id) ele = ChromiumElement(page, obj_id=obj_id, node_id=node_id, backend_id=backend_id)
if ele.tag in __FRAME_ELEMENT__: if ele.tag in __FRAME_ELEMENT__:
@ -1285,11 +1285,11 @@ def run_js(page_or_ele, script, as_expr=False, timeout=None, args=None):
arguments=[convert_argument(arg) for arg in args], returnByValue=False, arguments=[convert_argument(arg) for arg in args], returnByValue=False,
awaitPromise=True, userGesture=True, _timeout=timeout) awaitPromise=True, userGesture=True, _timeout=timeout)
except ContextLossError: except ContextLostError:
if is_page: if is_page:
raise ContextLossError('页面已被刷新,请尝试等待页面加载完成再执行操作。') raise ContextLostError('页面已被刷新,请尝试等待页面加载完成再执行操作。')
else: else:
raise ElementLossError('原来获取到的元素对象已不在页面内。') raise ElementLostError('原来获取到的元素对象已不在页面内。')
if res is None and page.driver.has_alert: # 存在alert的情况 if res is None and page.driver.has_alert: # 存在alert的情况
return None return None

View File

@ -25,7 +25,7 @@ from .._units.scroller import PageScroller
from .._units.setter import ChromiumBaseSetter from .._units.setter import ChromiumBaseSetter
from .._units.states import PageStates from .._units.states import PageStates
from .._units.waiter import BaseWaiter from .._units.waiter import BaseWaiter
from ..errors import (ContextLossError, ElementLossError, CDPError, PageClosedError, NoRectError, AlertExistsError, from ..errors import (ContextLostError, ElementLostError, CDPError, PageClosedError, NoRectError, AlertExistsError,
GetDocumentError, ElementNotFoundError) GetDocumentError, ElementNotFoundError)
__ERROR__ = 'error' __ERROR__ = 'error'
@ -429,7 +429,7 @@ class ChromiumBase(BasePage):
try: try:
return self.run_cdp('Runtime.evaluate', expression='document.readyState;', return self.run_cdp('Runtime.evaluate', expression='document.readyState;',
_timeout=3)['result']['value'] _timeout=3)['result']['value']
except ContextLossError: except ContextLostError:
return None return None
except TimeoutError: except TimeoutError:
return 'timeout' return 'timeout'
@ -446,11 +446,11 @@ class ChromiumBase(BasePage):
error = r[__ERROR__] error = r[__ERROR__]
if error in ('Cannot find context with specified id', 'Inspected target navigated or closed'): if error in ('Cannot find context with specified id', 'Inspected target navigated or closed'):
raise ContextLossError raise ContextLostError
elif error in ('Could not find node with given id', 'Could not find object with given id', elif error in ('Could not find node with given id', 'Could not find object with given id',
'No node with given id found', 'Node with given id does not belong to the document', 'No node with given id found', 'Node with given id does not belong to the document',
'No node found for given backend id'): 'No node found for given backend id'):
raise ElementLossError raise ElementLostError
elif error == 'tab closed': elif error == 'tab closed':
raise PageClosedError raise PageClosedError
elif error == 'timeout': elif error == 'timeout':
@ -600,7 +600,7 @@ class ChromiumBase(BasePage):
try: try:
search_result = self.run_cdp_loaded('DOM.performSearch', query=loc, includeUserAgentShadowDOM=True) search_result = self.run_cdp_loaded('DOM.performSearch', query=loc, includeUserAgentShadowDOM=True)
count = search_result['resultCount'] count = search_result['resultCount']
except ContextLossError: except ContextLostError:
search_result = None search_result = None
count = 0 count = 0
@ -626,13 +626,13 @@ class ChromiumBase(BasePage):
r = [make_chromium_ele(self, node_id=i) for i in nodeIds['nodeIds']] r = [make_chromium_ele(self, node_id=i) for i in nodeIds['nodeIds']]
break break
except ElementLossError: except ElementLostError:
ok = False ok = False
try: try:
search_result = self.run_cdp_loaded('DOM.performSearch', query=loc, includeUserAgentShadowDOM=True) search_result = self.run_cdp_loaded('DOM.performSearch', query=loc, includeUserAgentShadowDOM=True)
count = search_result['resultCount'] count = search_result['resultCount']
except ContextLossError: except ContextLostError:
pass pass
if perf_counter() >= end_time: if perf_counter() >= end_time:
@ -1099,7 +1099,7 @@ def close_privacy_dialog(page, tid):
"""关闭隐私声明弹窗 """关闭隐私声明弹窗
:param page: ChromiumBase对象 :param page: ChromiumBase对象
:param tid: tab id :param tid: tab id
:return: ChromiumDriver对象 :return: None
""" """
try: try:
driver = page.browser._get_driver(tid) driver = page.browser._get_driver(tid)

View File

@ -14,7 +14,7 @@ from .._units.scroller import FrameScroller
from .._units.setter import ChromiumFrameSetter from .._units.setter import ChromiumFrameSetter
from .._units.states import FrameStates from .._units.states import FrameStates
from .._units.waiter import FrameWaiter from .._units.waiter import FrameWaiter
from ..errors import ContextLossError, ElementLossError, GetDocumentError, PageClosedError from ..errors import ContextLostError, ElementLostError, GetDocumentError, PageClosedError
class ChromiumFrame(ChromiumBase): class ChromiumFrame(ChromiumBase):
@ -106,17 +106,17 @@ class ChromiumFrame(ChromiumBase):
self._driver.stop() self._driver.stop()
try: try:
self._frame_ele = ChromiumElement(self._target_page, backend_id=self._backend_id) self._frame_ele = ChromiumElement(self._target_page, backend_id=self._backend_id)
except (ElementLossError, PageClosedError): end_time = perf_counter() + 2
return while perf_counter() < end_time:
node = self._target_page.run_cdp('DOM.describeNode',
backendNodeId=self._frame_ele._backend_id)['node']
if 'frameId' in node:
break
end_time = perf_counter() + 2 else:
while perf_counter() < end_time: return
node = self._target_page.run_cdp('DOM.describeNode',
backendNodeId=self._frame_ele._backend_id)['node']
if 'frameId' in node:
break
else: except (ElementLostError, PageClosedError):
return return
if self._is_inner_frame(): if self._is_inner_frame():
@ -347,7 +347,7 @@ class ChromiumFrame(ChromiumBase):
else: else:
try: try:
return self.doc_ele.run_js('return this.readyState;') return self.doc_ele.run_js('return this.readyState;')
except ContextLossError: except ContextLostError:
try: try:
node = self.run_cdp('DOM.describeNode', backendNodeId=self.frame_ele._backend_id)['node'] node = self.run_cdp('DOM.describeNode', backendNodeId=self.frame_ele._backend_id)['node']
doc = ChromiumElement(self._target_page, backend_id=node['contentDocument']['backendNodeId']) doc = ChromiumElement(self._target_page, backend_id=node['contentDocument']['backendNodeId'])

View File

@ -332,6 +332,13 @@ class WebPageTab(SessionPage, ChromiumTab, BasePage):
elif self._mode == 'd': elif self._mode == 'd':
return super(SessionPage, self).get_cookies(as_dict, all_domains, all_info) return super(SessionPage, self).get_cookies(as_dict, all_domains, all_info)
def close(self):
"""关闭当前标签页"""
self.page.close_tabs(self.tab_id)
self._session.close()
if self._response is not None:
self._response.close()
def _find_elements(self, loc_or_ele, timeout=None, single=True, relative=False, raise_err=None): def _find_elements(self, loc_or_ele, timeout=None, single=True, relative=False, raise_err=None):
"""返回页面中符合条件的元素、属性或节点文本,默认返回第一个 """返回页面中符合条件的元素、属性或节点文本,默认返回第一个
:param loc_or_ele: 元素的定位信息可以是元素对象loc元组或查询字符串 :param loc_or_ele: 元素的定位信息可以是元素对象loc元组或查询字符串

View File

@ -140,6 +140,8 @@ class WebPageTab(SessionPage, ChromiumTab):
def get_cookies(self, as_dict: bool = False, all_domains: bool = False, def get_cookies(self, as_dict: bool = False, all_domains: bool = False,
all_info: bool = False) -> Union[dict, list]: ... all_info: bool = False) -> Union[dict, list]: ...
def close(self) -> None: ...
# ----------------重写SessionPage的函数----------------------- # ----------------重写SessionPage的函数-----------------------
def post(self, def post(self,
url: str, url: str,

View File

@ -220,6 +220,12 @@ class SessionPage(BasePage):
""" """
return self._s_connect(url, 'post', data, show_errmsg, retry, interval, **kwargs) return self._s_connect(url, 'post', data, show_errmsg, retry, interval, **kwargs)
def close(self):
"""关闭Session对象"""
self._session.close()
if self._response is not None:
self._response.close()
def _s_connect(self, url, mode, data=None, show_errmsg=False, retry=None, interval=None, **kwargs): def _s_connect(self, url, mode, data=None, show_errmsg=False, retry=None, interval=None, **kwargs):
"""执行get或post连接 """执行get或post连接
:param url: 目标url :param url: 目标url

View File

@ -334,10 +334,21 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
if self._has_session: if self._has_session:
self.change_mode('d') self.change_mode('d')
self._session.close() self._session.close()
if self._response is not None:
self._response.close()
self._session = None self._session = None
self._response = None self._response = None
self._has_session = None self._has_session = None
def close(self):
"""关闭标签页"""
if self._has_driver:
self.close_tabs(self.tab_id)
if self._session:
self._session.close()
if self._response is not None:
self._response.close()
def _find_elements(self, loc_or_ele, timeout=None, single=True, relative=False, raise_err=None): def _find_elements(self, loc_or_ele, timeout=None, single=True, relative=False, raise_err=None):
"""返回页面中符合条件的元素、属性或节点文本,默认返回第一个 """返回页面中符合条件的元素、属性或节点文本,默认返回第一个
:param loc_or_ele: 元素的定位信息可以是元素对象loc元组或查询字符串 :param loc_or_ele: 元素的定位信息可以是元素对象loc元组或查询字符串

View File

@ -4,7 +4,7 @@
@Contact : g1879@qq.com @Contact : g1879@qq.com
""" """
from .._commons.web import location_in_viewport from .._commons.web import location_in_viewport
from ..errors import CDPError, NoRectError, PageClosedError, ElementLossError from ..errors import CDPError, NoRectError, PageClosedError, ElementLostError
class ElementStates(object): class ElementStates(object):
@ -146,7 +146,7 @@ class FrameStates(object):
try: try:
node = self._frame._target_page.run_cdp('DOM.describeNode', node = self._frame._target_page.run_cdp('DOM.describeNode',
backendNodeId=self._frame._frame_ele._backend_id)['node'] backendNodeId=self._frame._frame_ele._backend_id)['node']
except (ElementLossError, PageClosedError): except (ElementLostError, PageClosedError):
return False return False
return 'frameId' in node return 'frameId' in node

View File

@ -33,11 +33,11 @@ class AlertExistsError(BaseError):
_info = '存在未处理的提示框。' _info = '存在未处理的提示框。'
class ContextLossError(BaseError): class ContextLostError(BaseError):
_info = '页面被刷新,请操作前尝试等待页面刷新或加载完成。' _info = '页面被刷新,请操作前尝试等待页面刷新或加载完成。'
class ElementLossError(BaseError): class ElementLostError(BaseError):
_info = '元素对象因刷新已失效。' _info = '元素对象因刷新已失效。'