From a4bf7da0bd06fb8e6d15c6945d211cf882f9f4d9 Mon Sep 17 00:00:00 2001 From: g1879 Date: Wed, 15 Nov 2023 00:31:46 +0800 Subject: [PATCH] =?UTF-8?q?run=5Fjs()=E7=AD=89=E6=96=B9=E6=B3=95=E5=8A=A0?= =?UTF-8?q?=E4=B8=8Atimeout=E5=8F=82=E6=95=B0=EF=BC=9B=E4=BF=AE=E5=A4=8Dta?= =?UTF-8?q?b=E7=9B=B8=E5=85=B3=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DrissionPage/_elements/chromium_element.py | 22 ++++++++----- DrissionPage/_elements/chromium_element.pyi | 8 ++--- DrissionPage/_pages/chromium_base.py | 16 ++++++---- DrissionPage/_pages/chromium_base.pyi | 34 +++++++-------------- DrissionPage/_pages/chromium_frame.py | 15 ++++----- DrissionPage/_pages/chromium_frame.pyi | 2 +- DrissionPage/_pages/chromium_page.py | 7 +++-- 7 files changed, 52 insertions(+), 52 deletions(-) diff --git a/DrissionPage/_elements/chromium_element.py b/DrissionPage/_elements/chromium_element.py index a6549bf..a19b02f 100644 --- a/DrissionPage/_elements/chromium_element.py +++ b/DrissionPage/_elements/chromium_element.py @@ -375,24 +375,27 @@ class ChromiumElement(DrissionElement): except: return None - def run_js(self, script, *args, as_expr=False): + def run_js(self, script, *args, as_expr=False, timeout=None): """对本元素执行javascript代码 :param script: js文本 :param args: 参数,按顺序在js文本中对应arguments[0]、arguments[1]... :param as_expr: 是否作为表达式运行,为True时args无效 + :param timeout: js超时时间,为None则使用页面timeouts.script设置 :return: 运行的结果 """ - return run_js(self, script, as_expr, self.page.timeouts.script, args) + return run_js(self, script, as_expr, self.page.timeouts.script if timeout is None else timeout, args) - def run_async_js(self, script, *args, as_expr=False): + def run_async_js(self, script, *args, as_expr=False, timeout=None): """以异步方式对本元素执行javascript代码 :param script: js文本 :param args: 参数,按顺序在js文本中对应arguments[0]、arguments[1]... :param as_expr: 是否作为表达式运行,为True时args无效 + :param timeout: js超时时间,为None则使用页面timeouts.script设置 :return: None """ from threading import Thread - Thread(target=run_js, args=(self, script, as_expr, self.page.timeouts.script, args, True)).start() + Thread(target=run_js, args=(self, script, as_expr, self.page.timeouts.script if timeout is None else timeout, + args, True)).start() def ele(self, loc_or_str, timeout=None): """返回当前元素下级符合条件的第一个元素、属性或节点文本 @@ -814,24 +817,27 @@ class ChromiumShadowRoot(BaseElement): self._states = ShadowRootStates(self) return self._states - def run_js(self, script, *args, as_expr=False): + def run_js(self, script, *args, as_expr=False, timeout=None): """运行javascript代码 :param script: js文本 :param args: 参数,按顺序在js文本中对应arguments[0]、arguments[1]... :param as_expr: 是否作为表达式运行,为True时args无效 + :param timeout: js超时时间,为None则使用页面timeouts.script设置 :return: 运行的结果 """ - return run_js(self, script, as_expr, self.page.timeouts.script, args) + return run_js(self, script, as_expr, self.page.timeouts.script if timeout is None else timeout, args) - def run_async_js(self, script, *args, as_expr=False): + def run_async_js(self, script, *args, as_expr=False, timeout=None): """以异步方式执行js代码 :param script: js文本 :param args: 参数,按顺序在js文本中对应arguments[0]、arguments[1]... :param as_expr: 是否作为表达式运行,为True时args无效 + :param timeout: js超时时间,为None则使用页面timeouts.script设置 :return: None """ from threading import Thread - Thread(target=run_js, args=(self, script, as_expr, self.page.timeouts.script, args)).start() + Thread(target=run_js, args=(self, script, as_expr, + self.page.timeouts.script if timeout is None else timeout, args)).start() def parent(self, level_or_loc=1, index=1): """返回上面某一级父元素,可指定层数或用查询语法定位 diff --git a/DrissionPage/_elements/chromium_element.pyi b/DrissionPage/_elements/chromium_element.pyi index 1108d9d..315461e 100644 --- a/DrissionPage/_elements/chromium_element.pyi +++ b/DrissionPage/_elements/chromium_element.pyi @@ -160,9 +160,9 @@ class ChromiumElement(DrissionElement): def prop(self, prop: str) -> Union[str, int, None]: ... - def run_js(self, script: str, *args: Any, as_expr: bool = False) -> Any: ... + def run_js(self, script: str, *args, as_expr: bool = False, timeout: float = None) -> Any: ... - def run_async_js(self, script: str, *args: Any, as_expr: bool = False) -> None: ... + def run_async_js(self, script: str, *args, as_expr: bool = False, timeout: float = None) -> None: ... def ele(self, loc_or_str: Union[Tuple[str, str], str], timeout: float = None) -> Union[ChromiumElement, str]: ... @@ -244,9 +244,9 @@ class ChromiumShadowRoot(BaseElement): @property def inner_html(self) -> str: ... - def run_js(self, script: str, *args: Any, as_expr: bool = False) -> Any: ... + def run_js(self, script: str, *args, as_expr: bool = False, timeout: float = None) -> Any: ... - def run_async_js(self, script: str, *args: Any, as_expr: bool = False) -> None: ... + def run_async_js(self, script: str, *args, as_expr: bool = False, timeout: float = None) -> None: ... def parent(self, level_or_loc: Union[str, int] = 1, index: int = 1) -> ChromiumElement: ... diff --git a/DrissionPage/_pages/chromium_base.py b/DrissionPage/_pages/chromium_base.py index e9d4bde..91c2e06 100644 --- a/DrissionPage/_pages/chromium_base.py +++ b/DrissionPage/_pages/chromium_base.py @@ -456,34 +456,38 @@ class ChromiumBase(BasePage): self.wait.load_complete() return self.run_cdp(cmd, **cmd_args) - def run_js(self, script, *args, as_expr=False): + def run_js(self, script, *args, as_expr=False, timeout=None): """运行javascript代码 :param script: js文本 :param args: 参数,按顺序在js文本中对应arguments[0]、arguments[1]... :param as_expr: 是否作为表达式运行,为True时args无效 + :param timeout: js超时时间,为None则使用页面timeouts.script设置 :return: 运行的结果 """ - return run_js(self, script, as_expr, self.timeouts.script, args) + return run_js(self, script, as_expr, self.timeouts.script if timeout is None else timeout, args) - def run_js_loaded(self, script, *args, as_expr=False): + def run_js_loaded(self, script, *args, as_expr=False, timeout=None): """运行javascript代码,执行前等待页面加载完毕 :param script: js文本 :param args: 参数,按顺序在js文本中对应arguments[0]、arguments[1]... :param as_expr: 是否作为表达式运行,为True时args无效 + :param timeout: js超时时间,为None则使用页面timeouts.script设置 :return: 运行的结果 """ self.wait.load_complete() - return run_js(self, script, as_expr, self.timeouts.script, args) + return run_js(self, script, as_expr, self.timeouts.script if timeout is None else timeout, args) - def run_async_js(self, script, *args, as_expr=False): + def run_async_js(self, script, *args, as_expr=False, timeout=None): """以异步方式执行js代码 :param script: js文本 :param args: 参数,按顺序在js文本中对应arguments[0]、arguments[1]... :param as_expr: 是否作为表达式运行,为True时args无效 + :param timeout: js超时时间,为None则使用页面timeouts.script设置 :return: None """ from threading import Thread - Thread(target=run_js, args=(self, script, as_expr, self.timeouts.script, args)).start() + Thread(target=run_js, args=(self, script, as_expr, self.timeouts.script if timeout is None else timeout, + args)).start() def get(self, url, show_errmsg=False, retry=None, interval=None, timeout=None): """访问url diff --git a/DrissionPage/_pages/chromium_base.pyi b/DrissionPage/_pages/chromium_base.pyi index 826e95e..8d3a1ca 100644 --- a/DrissionPage/_pages/chromium_base.pyi +++ b/DrissionPage/_pages/chromium_base.pyi @@ -164,11 +164,11 @@ class ChromiumBase(BasePage): @property def has_alert(self) -> bool: ... - def run_js(self, script: str, *args: Any, as_expr: bool = False) -> Any: ... + def run_js(self, script: str, *args, as_expr: bool = False, timeout: float = None) -> Any: ... - def run_js_loaded(self, script: str, *args: Any, as_expr: bool = False) -> Any: ... + def run_js_loaded(self, script: str, *args, as_expr: bool = False, timeout: float = None) -> Any: ... - def run_async_js(self, script: str, *args: Any, as_expr: bool = False) -> None: ... + def run_async_js(self, script: str, *args, as_expr: bool = False, timeout: float = None) -> None: ... def get(self, url: str, show_errmsg: bool = False, retry: int = None, interval: float = None, timeout: float = None) -> Union[None, bool]: ... @@ -215,23 +215,15 @@ class ChromiumBase(BasePage): def get_local_storage(self, item: str = None) -> Union[str, dict, None]: ... - def get_screenshot(self, path: [str, Path] = None, name: str = None, - as_bytes: [bool, str] = None, as_base64: [bool, str] = None, - full_page: bool = False, - left_top: Tuple[int, int] = None, - right_bottom: Tuple[int, int] = None) -> Union[str, bytes]: ... + def get_screenshot(self, path: [str, Path] = None, name: str = None, as_bytes: [bool, str] = None, + as_base64: [bool, str] = None, full_page: bool = False, + left_top: Tuple[int, int] = None, right_bottom: Tuple[int, int] = None) -> Union[str, bytes]: ... - def _get_screenshot(self, path: [str, Path] = None, name: str = None, - as_bytes: [bool, str] = None, as_base64: [bool, str] = None, - full_page: bool = False, - left_top: Tuple[int, int] = None, - right_bottom: Tuple[int, int] = None, - ele: ChromiumElement = None) -> Union[str, bytes]: ... + def _get_screenshot(self, path: [str, Path] = None, name: str = None, as_bytes: [bool, str] = None, + as_base64: [bool, str] = None, full_page: bool = False, left_top: Tuple[int, int] = None, + right_bottom: Tuple[int, int] = None, ele: ChromiumElement = None) -> Union[str, bytes]: ... - def clear_cache(self, - session_storage: bool = True, - local_storage: bool = True, - cache: bool = True, + def clear_cache(self, session_storage: bool = True, local_storage: bool = True, cache: bool = True, cookies: bool = True) -> None: ... def handle_alert(self, accept: bool = True, send: str = None, timeout: float = None) -> Union[str, False]: ... @@ -240,11 +232,7 @@ class ChromiumBase(BasePage): def _on_alert_open(self, **kwargs): ... - def _d_connect(self, - to_url: str, - times: int = 0, - interval: float = 1, - show_errmsg: bool = False, + def _d_connect(self, to_url: str, times: int = 0, interval: float = 1, show_errmsg: bool = False, timeout: float = None) -> Union[bool, None]: ... diff --git a/DrissionPage/_pages/chromium_frame.py b/DrissionPage/_pages/chromium_frame.py index dc8f5ec..887e697 100644 --- a/DrissionPage/_pages/chromium_frame.py +++ b/DrissionPage/_pages/chromium_frame.py @@ -13,7 +13,7 @@ from .._units.ids import FrameIds from .._units.scroller import FrameScroller from .._units.setter import ChromiumFrameSetter from .._units.waiter import FrameWaiter -from ..errors import ContextLossError, ElementLossError, GetDocumentError +from ..errors import ContextLossError, ElementLossError, GetDocumentError, TabClosedError class ChromiumFrame(ChromiumBase): @@ -67,7 +67,7 @@ class ChromiumFrame(ChromiumBase): return self.ele(loc_or_str, timeout) def __repr__(self): - attrs = self.frame_ele.attrs + attrs = self._frame_ele.attrs attrs = [f"{attr}='{attrs[attr]}'" for attr in attrs] return f'' @@ -238,7 +238,7 @@ class ChromiumFrame(ChromiumBase): try: self._frame_ele.attrs - except ElementLossError: + except (ElementLossError, TabClosedError): self._driver.stop() self._reload() @@ -254,7 +254,7 @@ class ChromiumFrame(ChromiumBase): try: self._frame_ele.attrs - except ElementLossError: + except (ElementLossError, TabClosedError): self._driver.stop() self._reload() @@ -431,17 +431,18 @@ class ChromiumFrame(ChromiumBase): """ self.frame_ele.remove_attr(attr) - def run_js(self, script, *args, as_expr=False): + def run_js(self, script, *args, as_expr=False, timeout=None): """运行javascript代码 :param script: js文本 :param args: 参数,按顺序在js文本中对应arguments[0]、arguments[1]... :param as_expr: 是否作为表达式运行,为True时args无效 + :param timeout: js超时时间,为None则使用页面timeouts.script设置 :return: 运行的结果 """ if script.startswith('this.scrollIntoView'): - return self.frame_ele.run_js(script, *args, as_expr=as_expr) + return self.frame_ele.run_js(script, args, as_expr=as_expr, timeout=timeout) else: - return self.doc_ele.run_js(script, *args, as_expr=as_expr) + return self.doc_ele.run_js(script, args, as_expr=as_expr, timeout=timeout) def parent(self, level_or_loc=1, index=1): """返回上面某一级父元素,可指定层数或用查询语法定位 diff --git a/DrissionPage/_pages/chromium_frame.pyi b/DrissionPage/_pages/chromium_frame.pyi index 12aff73..1aebd95 100644 --- a/DrissionPage/_pages/chromium_frame.pyi +++ b/DrissionPage/_pages/chromium_frame.pyi @@ -138,7 +138,7 @@ class ChromiumFrame(ChromiumBase): def remove_attr(self, attr: str) -> None: ... - def run_js(self, script: str, *args: Any, as_expr: bool = False) -> Any: ... + def run_js(self, script: str, *args, as_expr: bool = False, timeout: float = None) -> Any: ... def parent(self, level_or_loc: Union[tuple, str, int] = 1, index: int = 1) -> Union[ChromiumElement, None]: ... diff --git a/DrissionPage/_pages/chromium_page.py b/DrissionPage/_pages/chromium_page.py index c5fa80f..11353fb 100644 --- a/DrissionPage/_pages/chromium_page.py +++ b/DrissionPage/_pages/chromium_page.py @@ -4,7 +4,7 @@ @Contact : g1879@qq.com """ from pathlib import Path -from time import sleep +from time import sleep, perf_counter from requests import get @@ -214,7 +214,7 @@ class ChromiumPage(ChromiumBase): if others: tabs = all_tabs - tabs - end_len = len(all_tabs) - len(tabs) + end_len = len(set(all_tabs) - set(tabs)) if end_len <= 0: self.quit() return @@ -222,7 +222,8 @@ class ChromiumPage(ChromiumBase): for tab in tabs: self.browser.close_tab(tab) sleep(.2) - while self.tabs_count != end_len: + end_time = perf_counter() + 3 + while self.tabs_count != end_len and perf_counter() < end_time: sleep(.1) def close_other_tabs(self, tabs_or_ids=None):