From bc9bc717772c60408844d95355b37171430df8ab Mon Sep 17 00:00:00 2001 From: g1879 Date: Fri, 12 Jan 2024 17:39:56 +0800 Subject: [PATCH] =?UTF-8?q?4.0.0b38=E4=BF=AE=E5=A4=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DrissionPage/__init__.py | 2 +- DrissionPage/_elements/chromium_element.py | 19 ++++++++++++------- DrissionPage/_elements/chromium_element.pyi | 9 ++++++--- DrissionPage/_pages/chromium_page.py | 8 ++++---- DrissionPage/_pages/chromium_page.pyi | 6 ++++++ DrissionPage/_pages/web_page.py | 14 +++++++++++++- setup.py | 2 +- 7 files changed, 43 insertions(+), 17 deletions(-) diff --git a/DrissionPage/__init__.py b/DrissionPage/__init__.py index 45f5381..632411f 100644 --- a/DrissionPage/__init__.py +++ b/DrissionPage/__init__.py @@ -14,4 +14,4 @@ from ._configs.chromium_options import ChromiumOptions from ._configs.session_options import SessionOptions __all__ = ['ChromiumPage', 'ChromiumOptions', 'SessionOptions', 'SessionPage', 'WebPage', '__version__'] -__version__ = '4.0.0b37' +__version__ = '4.0.0b38' diff --git a/DrissionPage/_elements/chromium_element.py b/DrissionPage/_elements/chromium_element.py index 570684c..a7e49fe 100644 --- a/DrissionPage/_elements/chromium_element.py +++ b/DrissionPage/_elements/chromium_element.py @@ -1393,7 +1393,7 @@ else{a.push(e.snapshotItem(i));}}""" return js -def run_js(page_or_ele, script, as_expr=False, timeout=None, args=None): +def run_js(page_or_ele, script, as_expr, timeout, args=None): """运行javascript代码 :param page_or_ele: 页面对象或元素对象 :param script: js文本 @@ -1420,6 +1420,7 @@ def run_js(page_or_ele, script, as_expr=False, timeout=None, args=None): if page.states.has_alert: raise AlertExistsError + end_time = perf_counter() + timeout try: if as_expr: res = page.run_cdp('Runtime.evaluate', expression=script, returnByValue=False, @@ -1448,12 +1449,12 @@ def run_js(page_or_ele, script, as_expr=False, timeout=None, args=None): raise JavaScriptError(f'\njavascript运行错误:\n{script}\n错误信息: \n{exceptionDetails}') try: - return parse_js_result(page, page_or_ele, res.get('result')) + return parse_js_result(page, page_or_ele, res.get('result'), end_time) except Exception: return res -def parse_js_result(page, ele, result): +def parse_js_result(page, ele, result, end_time): """解析js返回的结果""" if 'unserializableValue' in result: return result['unserializableValue'] @@ -1478,17 +1479,21 @@ def parse_js_result(page, ele, result): elif sub_type == 'array': r = page.run_cdp('Runtime.getProperties', objectId=result['objectId'], ownProperties=True)['result'] - return [parse_js_result(page, ele, result=i['value']) for i in r[:-1]] + return [parse_js_result(page, ele, result=i['value'], end_time=end_time) for i in r[:-1]] elif 'objectId' in result and result['className'].lower() == 'object': # dict r = page.run_cdp('Runtime.getProperties', objectId=result['objectId'], ownProperties=True)['result'] - return {i['name']: parse_js_result(page, ele, result=i['value']) for i in r} + return {i['name']: parse_js_result(page, ele, result=i['value'], end_time=end_time) for i in r} elif 'objectId' in result: + timeout = end_time - perf_counter() + if timeout < 0: + return js = 'function(){return JSON.stringify(this);}' r = page.run_cdp('Runtime.callFunctionOn', functionDeclaration=js, objectId=result['objectId'], - returnByValue=False, awaitPromise=True, userGesture=True, _ignore=AlertExistsError) - return loads(parse_js_result(page, ele, r['result'])) + returnByValue=False, awaitPromise=True, userGesture=True, _ignore=AlertExistsError, + _timeout=timeout) + return loads(parse_js_result(page, ele, r['result'], end_time)) else: return result.get('value', result) diff --git a/DrissionPage/_elements/chromium_element.pyi b/DrissionPage/_elements/chromium_element.pyi index 2549f32..cbddbdc 100644 --- a/DrissionPage/_elements/chromium_element.pyi +++ b/DrissionPage/_elements/chromium_element.pyi @@ -354,12 +354,15 @@ def make_js_for_find_ele_by_xpath(xpath: str, type_txt: str, node_txt: str) -> s def run_js(page_or_ele: Union[ChromiumBase, ChromiumElement, ShadowRoot], script: str, - as_expr: bool = False, - timeout: float = None, + as_expr: bool, + timeout: float, args: tuple = ...) -> Any: ... -def parse_js_result(page: ChromiumBase, ele: ChromiumElement, result: dict): ... +def parse_js_result(page: ChromiumBase, + ele: ChromiumElement, + result: dict, + end_time: float): ... def convert_argument(arg: Any) -> dict: ... diff --git a/DrissionPage/_pages/chromium_page.py b/DrissionPage/_pages/chromium_page.py index b925c9c..71b3f38 100644 --- a/DrissionPage/_pages/chromium_page.py +++ b/DrissionPage/_pages/chromium_page.py @@ -31,8 +31,8 @@ class ChromiumPage(ChromiumBase): :param timeout: 超时时间(秒) """ addr_or_opts = addr_or_opts or addr_driver_opts - opt = _handle_options(addr_or_opts) - is_exist, browser_id = _run_browser(opt) + opt = handle_options(addr_or_opts) + is_exist, browser_id = run_browser(opt) if browser_id in cls.PAGES: return cls.PAGES[browser_id] r = object.__new__(cls) @@ -261,7 +261,7 @@ class ChromiumPage(ChromiumBase): self.close_tabs(tabs_or_ids, True) -def _handle_options(addr_or_opts): +def handle_options(addr_or_opts): """设置浏览器启动属性 :param addr_or_opts: 'ip:port'、ChromiumOptions、Driver :return: 返回ChromiumOptions对象 @@ -291,7 +291,7 @@ def _handle_options(addr_or_opts): return _chromium_options -def _run_browser(chromium_options): +def run_browser(chromium_options): """连接浏览器""" is_exist = connect_browser(chromium_options) try: diff --git a/DrissionPage/_pages/chromium_page.pyi b/DrissionPage/_pages/chromium_page.pyi index 9ceabf4..171f488 100644 --- a/DrissionPage/_pages/chromium_page.pyi +++ b/DrissionPage/_pages/chromium_page.pyi @@ -106,4 +106,10 @@ class ChromiumPage(ChromiumBase): def _on_disconnect(self) -> None: ... +def handle_options(addr_or_opts): ... + + +def run_browser(chromium_options): ... + + def get_rename(original: str, rename: str) -> str: ... diff --git a/DrissionPage/_pages/web_page.py b/DrissionPage/_pages/web_page.py index 5f14da3..8727e3f 100644 --- a/DrissionPage/_pages/web_page.py +++ b/DrissionPage/_pages/web_page.py @@ -17,6 +17,16 @@ from .._units.setter import WebPageSetter class WebPage(SessionPage, ChromiumPage, BasePage): """整合浏览器和request的页面类""" + def __new__(cls, mode='d', timeout=None, chromium_options=None, session_or_options=None, driver_or_options=None): + """初始化函数 + :param mode: 'd' 或 's',即driver模式和session模式 + :param timeout: 超时时间(秒),d模式时为寻找元素时间,s模式时为连接时间,默认10秒 + :param chromium_options: Driver对象,只使用s模式时应传入False + :param session_or_options: Session对象或SessionOptions对象,只使用d模式时应传入False + """ + opts = chromium_options or driver_or_options + return super().__new__(cls, opts) + def __init__(self, mode='d', timeout=None, chromium_options=None, session_or_options=None, driver_or_options=None): """初始化函数 :param mode: 'd' 或 's',即driver模式和session模式 @@ -24,7 +34,9 @@ class WebPage(SessionPage, ChromiumPage, BasePage): :param chromium_options: Driver对象,只使用s模式时应传入False :param session_or_options: Session对象或SessionOptions对象,只使用d模式时应传入False """ - chromium_options = chromium_options or driver_or_options + if hasattr(self, '_created'): + return + self._mode = mode.lower() if self._mode not in ('s', 'd'): raise ValueError('mode参数只能是s或d。') diff --git a/setup.py b/setup.py index a8fca9c..1bef642 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ with open("README.md", "r", encoding='utf-8') as fh: setup( name="DrissionPage", - version="4.0.0b37", + version="4.0.0b38", author="g1879", author_email="g1879@qq.com", description="Python based web automation tool. It can control the browser and send and receive data packets.",