diff --git a/DrissionPage/_elements/chromium_element.py b/DrissionPage/_elements/chromium_element.py index 115bdd0..6be8334 100644 --- a/DrissionPage/_elements/chromium_element.py +++ b/DrissionPage/_elements/chromium_element.py @@ -22,7 +22,7 @@ from .._units.select_element import SelectElement from .._units.setter import ChromiumElementSetter from .._units.states import ElementStates, ShadowRootStates from .._units.waiter import ElementWaiter -from ..errors import (ContextLossError, ElementLossError, JavaScriptError, ElementNotFoundError, +from ..errors import (ContextLostError, ElementLostError, JavaScriptError, ElementNotFoundError, CDPError, NoResourceError, AlertExistsError) __FRAME_ELEMENT__ = ('iframe', 'frame') @@ -66,7 +66,7 @@ class ChromiumElement(DrissionElement): self._node_id = self._get_node_id(obj_id=self._obj_id) self._backend_id = backend_id else: - raise ElementLossError + raise ElementLostError doc = self.run_js('return this.ownerDocument;') 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'] else: - raise ElementLossError + raise ElementLostError ele = ChromiumElement(page, obj_id=obj_id, node_id=node_id, backend_id=backend_id) 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, awaitPromise=True, userGesture=True, _timeout=timeout) - except ContextLossError: + except ContextLostError: if is_page: - raise ContextLossError('页面已被刷新,请尝试等待页面加载完成再执行操作。') + raise ContextLostError('页面已被刷新,请尝试等待页面加载完成再执行操作。') else: - raise ElementLossError('原来获取到的元素对象已不在页面内。') + raise ElementLostError('原来获取到的元素对象已不在页面内。') if res is None and page.driver.has_alert: # 存在alert的情况 return None diff --git a/DrissionPage/_pages/chromium_base.py b/DrissionPage/_pages/chromium_base.py index 69f5ec7..d1e9cc7 100644 --- a/DrissionPage/_pages/chromium_base.py +++ b/DrissionPage/_pages/chromium_base.py @@ -25,7 +25,7 @@ from .._units.scroller import PageScroller from .._units.setter import ChromiumBaseSetter from .._units.states import PageStates 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) __ERROR__ = 'error' @@ -429,7 +429,7 @@ class ChromiumBase(BasePage): try: return self.run_cdp('Runtime.evaluate', expression='document.readyState;', _timeout=3)['result']['value'] - except ContextLossError: + except ContextLostError: return None except TimeoutError: return 'timeout' @@ -446,11 +446,11 @@ class ChromiumBase(BasePage): error = r[__ERROR__] 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', 'No node with given id found', 'Node with given id does not belong to the document', 'No node found for given backend id'): - raise ElementLossError + raise ElementLostError elif error == 'tab closed': raise PageClosedError elif error == 'timeout': @@ -600,7 +600,7 @@ class ChromiumBase(BasePage): try: search_result = self.run_cdp_loaded('DOM.performSearch', query=loc, includeUserAgentShadowDOM=True) count = search_result['resultCount'] - except ContextLossError: + except ContextLostError: search_result = None count = 0 @@ -626,13 +626,13 @@ class ChromiumBase(BasePage): r = [make_chromium_ele(self, node_id=i) for i in nodeIds['nodeIds']] break - except ElementLossError: + except ElementLostError: ok = False try: search_result = self.run_cdp_loaded('DOM.performSearch', query=loc, includeUserAgentShadowDOM=True) count = search_result['resultCount'] - except ContextLossError: + except ContextLostError: pass if perf_counter() >= end_time: @@ -1099,7 +1099,7 @@ def close_privacy_dialog(page, tid): """关闭隐私声明弹窗 :param page: ChromiumBase对象 :param tid: tab id - :return: ChromiumDriver对象 + :return: None """ try: driver = page.browser._get_driver(tid) diff --git a/DrissionPage/_pages/chromium_frame.py b/DrissionPage/_pages/chromium_frame.py index 681d143..16460b6 100644 --- a/DrissionPage/_pages/chromium_frame.py +++ b/DrissionPage/_pages/chromium_frame.py @@ -14,7 +14,7 @@ from .._units.scroller import FrameScroller from .._units.setter import ChromiumFrameSetter from .._units.states import FrameStates from .._units.waiter import FrameWaiter -from ..errors import ContextLossError, ElementLossError, GetDocumentError, PageClosedError +from ..errors import ContextLostError, ElementLostError, GetDocumentError, PageClosedError class ChromiumFrame(ChromiumBase): @@ -106,17 +106,17 @@ class ChromiumFrame(ChromiumBase): self._driver.stop() try: self._frame_ele = ChromiumElement(self._target_page, backend_id=self._backend_id) - except (ElementLossError, PageClosedError): - return + end_time = perf_counter() + 2 + 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 - 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 + else: + return - else: + except (ElementLostError, PageClosedError): return if self._is_inner_frame(): @@ -347,7 +347,7 @@ class ChromiumFrame(ChromiumBase): else: try: return self.doc_ele.run_js('return this.readyState;') - except ContextLossError: + except ContextLostError: try: node = self.run_cdp('DOM.describeNode', backendNodeId=self.frame_ele._backend_id)['node'] doc = ChromiumElement(self._target_page, backend_id=node['contentDocument']['backendNodeId']) diff --git a/DrissionPage/_pages/chromium_tab.py b/DrissionPage/_pages/chromium_tab.py index fdd9a57..f7a5514 100644 --- a/DrissionPage/_pages/chromium_tab.py +++ b/DrissionPage/_pages/chromium_tab.py @@ -332,6 +332,13 @@ class WebPageTab(SessionPage, ChromiumTab, BasePage): elif self._mode == 'd': 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): """返回页面中符合条件的元素、属性或节点文本,默认返回第一个 :param loc_or_ele: 元素的定位信息,可以是元素对象,loc元组,或查询字符串 diff --git a/DrissionPage/_pages/chromium_tab.pyi b/DrissionPage/_pages/chromium_tab.pyi index d00e710..29c5c7b 100644 --- a/DrissionPage/_pages/chromium_tab.pyi +++ b/DrissionPage/_pages/chromium_tab.pyi @@ -140,6 +140,8 @@ class WebPageTab(SessionPage, ChromiumTab): def get_cookies(self, as_dict: bool = False, all_domains: bool = False, all_info: bool = False) -> Union[dict, list]: ... + def close(self) -> None: ... + # ----------------重写SessionPage的函数----------------------- def post(self, url: str, diff --git a/DrissionPage/_pages/session_page.py b/DrissionPage/_pages/session_page.py index 811b44a..eed198f 100644 --- a/DrissionPage/_pages/session_page.py +++ b/DrissionPage/_pages/session_page.py @@ -220,6 +220,12 @@ class SessionPage(BasePage): """ 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): """执行get或post连接 :param url: 目标url diff --git a/DrissionPage/_pages/web_page.py b/DrissionPage/_pages/web_page.py index 98b1da2..e17d4ae 100644 --- a/DrissionPage/_pages/web_page.py +++ b/DrissionPage/_pages/web_page.py @@ -334,10 +334,21 @@ class WebPage(SessionPage, ChromiumPage, BasePage): if self._has_session: self.change_mode('d') self._session.close() + if self._response is not None: + self._response.close() self._session = None self._response = 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): """返回页面中符合条件的元素、属性或节点文本,默认返回第一个 :param loc_or_ele: 元素的定位信息,可以是元素对象,loc元组,或查询字符串 diff --git a/DrissionPage/_units/states.py b/DrissionPage/_units/states.py index 2e3214f..c178d5e 100644 --- a/DrissionPage/_units/states.py +++ b/DrissionPage/_units/states.py @@ -4,7 +4,7 @@ @Contact : g1879@qq.com """ from .._commons.web import location_in_viewport -from ..errors import CDPError, NoRectError, PageClosedError, ElementLossError +from ..errors import CDPError, NoRectError, PageClosedError, ElementLostError class ElementStates(object): @@ -146,7 +146,7 @@ class FrameStates(object): try: node = self._frame._target_page.run_cdp('DOM.describeNode', backendNodeId=self._frame._frame_ele._backend_id)['node'] - except (ElementLossError, PageClosedError): + except (ElementLostError, PageClosedError): return False return 'frameId' in node diff --git a/DrissionPage/errors.py b/DrissionPage/errors.py index 88bb001..6bd9abd 100644 --- a/DrissionPage/errors.py +++ b/DrissionPage/errors.py @@ -33,11 +33,11 @@ class AlertExistsError(BaseError): _info = '存在未处理的提示框。' -class ContextLossError(BaseError): +class ContextLostError(BaseError): _info = '页面被刷新,请操作前尝试等待页面刷新或加载完成。' -class ElementLossError(BaseError): +class ElementLostError(BaseError): _info = '元素对象因刷新已失效。'