From 5578bf57a568b740ac3834a7704fea057d8c595f Mon Sep 17 00:00:00 2001 From: g1879 Date: Sun, 31 Mar 2024 11:02:51 +0800 Subject: [PATCH] =?UTF-8?q?4.0.4.20add=5Fele()=E6=B7=BB=E5=8A=A0=E5=85=83?= =?UTF-8?q?=E7=B4=A0=E5=8F=AF=E4=B8=8D=E6=8F=92=E5=85=A5DOM=EF=BC=9B?= =?UTF-8?q?=E4=BF=AE=E5=A4=8Drun=5Fjs()=E4=B8=8D=E5=8F=AF=E4=BC=A0?= =?UTF-8?q?=E5=85=A5dict=E5=8F=82=E6=95=B0=E9=97=AE=E9=A2=98=EF=BC=9Bwhile?= =?UTF-8?q?=E5=9D=87=E6=B7=BB=E5=8A=A0sleep()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DrissionPage/__init__.py | 2 +- DrissionPage/_base/browser.py | 3 + DrissionPage/_elements/chromium_element.py | 14 +++-- DrissionPage/_functions/tools.py | 3 +- DrissionPage/_pages/chromium_base.py | 69 ++++++++++++++++------ DrissionPage/_pages/chromium_base.pyi | 2 +- DrissionPage/_pages/chromium_frame.py | 3 +- DrissionPage/_units/selector.py | 4 +- DrissionPage/_units/waiter.py | 3 + 9 files changed, 74 insertions(+), 29 deletions(-) diff --git a/DrissionPage/__init__.py b/DrissionPage/__init__.py index 634be2c..a77e654 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.4.18' +__version__ = '4.0.4.20' diff --git a/DrissionPage/_base/browser.py b/DrissionPage/_base/browser.py index f17de5e..c877013 100644 --- a/DrissionPage/_base/browser.py +++ b/DrissionPage/_base/browser.py @@ -274,6 +274,8 @@ class Browser(object): if ok: break + sleep(.05) + if self.process_id: waitpid(self.process_id, 0) @@ -291,3 +293,4 @@ class Browser(object): break except (PermissionError, FileNotFoundError, OSError): pass + sleep(.05) diff --git a/DrissionPage/_elements/chromium_element.py b/DrissionPage/_elements/chromium_element.py index 87d39c6..cfc58e7 100644 --- a/DrissionPage/_elements/chromium_element.py +++ b/DrissionPage/_elements/chromium_element.py @@ -520,13 +520,15 @@ class ChromiumElement(DrissionElement): is_blob = src.startswith('blob') result = None end_time = perf_counter() + timeout - while perf_counter() < end_time: - if is_blob: + if is_blob: + while perf_counter() < end_time: result = get_blob(self.owner, src, base64_to_bytes) if result: break + sleep(.05) - else: + else: + while perf_counter() < end_time: src = self.property('currentSrc') if not src: continue @@ -538,7 +540,8 @@ class ChromiumElement(DrissionElement): result = self.owner.run_cdp('Page.getResourceContent', frameId=frame, url=src) break except CDPError: - sleep(.1) + pass + sleep(.1) if not result: return None @@ -1428,6 +1431,7 @@ def run_js(page_or_ele, script, as_expr, timeout, args=None): obj_id = page_or_ele._root_id if obj_id is not None: break + sleep(.01) else: raise RuntimeError('js运行环境出错。') @@ -1528,7 +1532,7 @@ def convert_argument(arg): if isinstance(arg, ChromiumElement): return {'objectId': arg._obj_id} - elif isinstance(arg, (int, float, str, bool)): + elif isinstance(arg, (int, float, str, bool, dict)): return {'value': arg} from math import inf diff --git a/DrissionPage/_functions/tools.py b/DrissionPage/_functions/tools.py index bb23115..2486718 100644 --- a/DrissionPage/_functions/tools.py +++ b/DrissionPage/_functions/tools.py @@ -10,7 +10,7 @@ from platform import system from shutil import rmtree from tempfile import gettempdir, TemporaryDirectory from threading import Lock -from time import perf_counter +from time import perf_counter, sleep from .._configs.options_manage import OptionsManager from ..errors import (ContextLostError, ElementLostError, CDPError, PageDisconnectedError, NoRectError, @@ -177,6 +177,7 @@ def wait_until(function, kwargs=None, timeout=10): value = function(**kwargs) if value: return value + sleep(.01) raise TimeoutError diff --git a/DrissionPage/_pages/chromium_base.py b/DrissionPage/_pages/chromium_base.py index 0fde9e4..4920af4 100644 --- a/DrissionPage/_pages/chromium_base.py +++ b/DrissionPage/_pages/chromium_base.py @@ -673,30 +673,60 @@ class ChromiumBase(BasePage): if ele: self.run_cdp('DOM.removeNode', nodeId=ele._node_id) - def add_ele(self, outerHTML, insert_to=None, before=None): + def add_ele(self, html_or_info, insert_to=None, before=None): """新建一个元素 - :param outerHTML: 新元素的html文本 - :param insert_to: 插入到哪个元素中,可接收元素对象和定位符,为None添加到body + :param html_or_info: 新元素的html文本或信息。信息格式为:(tag, {attr1: value, ...}) + :param insert_to: 插入到哪个元素中,可接收元素对象和定位符,为None且为html添加到body,不为html不插入 :param before: 在哪个子节点前面插入,可接收对象和定位符,为None插入到父元素末尾 :return: 元素对象 """ - insert_to = self.ele(insert_to) if insert_to else self.ele('t:body') - args = [outerHTML, insert_to] - if before: - args.append(self.ele(before)) - js = ''' - ele = document.createElement(null); - arguments[1].insertBefore(ele, arguments[2]); - ele.outerHTML = arguments[0]; - return arguments[2].previousElementSibling; - ''' + if isinstance(html_or_info, str): + insert_to = self.ele(insert_to) if insert_to else self.ele('t:body') + args = [html_or_info, insert_to] + if before: + args.append(self.ele(before)) + js = ''' + ele = document.createElement(null); + arguments[1].insertBefore(ele, arguments[2]); + ele.outerHTML = arguments[0]; + return arguments[2].previousElementSibling; + ''' + else: + js = ''' + ele = document.createElement(null); + arguments[1].appendChild(ele); + ele.outerHTML = arguments[0]; + return arguments[1].lastElementChild; + ''' + + elif isinstance(html_or_info, tuple): + args = [html_or_info[0], html_or_info[1]] + txt = '' + if insert_to: + args.append(self.ele(insert_to)) + if before: + args.append(self.ele(before)) + txt = ''' + arguments[2].insertBefore(ele, arguments[3]); + ''' + else: + txt = ''' + arguments[2].appendChild(ele); + ''' + js = f''' + ele = document.createElement(arguments[0]); + for(let k in arguments[1]){{ + if(k=="innerHTML"){{ele.innerHTML=arguments[1][k]}} + else if(k=="innerText"){{ele.innerText=arguments[1][k]}} + else{{ele.setAttribute(k, arguments[1][k]);}} + }} + {txt} + return ele; + ''' + else: - js = ''' - ele = document.createElement(null); - arguments[1].appendChild(ele); - ele.outerHTML = arguments[0]; - return arguments[1].lastElementChild; - ''' + raise TypeError('html_or_info参数必须是html文本或tuple,tuple格式为(tag, {name: value})。') + ele = self.run_js(js, *args) return ele @@ -1188,6 +1218,7 @@ def close_privacy_dialog(page, tid): break except KeyError: pass + sleep(.05) driver.run('DOM.discardSearchResults', searchId=sid) r = driver.run('DOM.resolveNode', backendNodeId=r)['object']['objectId'] r = driver.run('Runtime.callFunctionOn', objectId=r, diff --git a/DrissionPage/_pages/chromium_base.pyi b/DrissionPage/_pages/chromium_base.pyi index fe8050f..ddb89b7 100644 --- a/DrissionPage/_pages/chromium_base.pyi +++ b/DrissionPage/_pages/chromium_base.pyi @@ -216,7 +216,7 @@ class ChromiumBase(BasePage): def remove_ele(self, loc_or_ele: Union[ChromiumElement, ChromiumFrame, str, Tuple[str, str]]) -> None: ... def add_ele(self, - outerHTML: str, + html_or_info: Union[str, Tuple[str, dict]], insert_to: Union[ChromiumElement, str, Tuple[str, str], None] = None, before: Union[ChromiumElement, str, Tuple[str, str], None] = None) -> ChromiumElement: ... diff --git a/DrissionPage/_pages/chromium_frame.py b/DrissionPage/_pages/chromium_frame.py index f2f08de..500859f 100644 --- a/DrissionPage/_pages/chromium_frame.py +++ b/DrissionPage/_pages/chromium_frame.py @@ -59,7 +59,7 @@ class ChromiumFrame(ChromiumBase): self._rect = None self._type = 'ChromiumFrame' end_time = perf_counter() + 2 - while perf_counter() < end_time: + while perf_counter() < end_time: # todo: 优化 if self.url not in (None, 'about:blank'): break sleep(.1) @@ -119,6 +119,7 @@ class ChromiumFrame(ChromiumBase): node = self._target_page.run_cdp('DOM.describeNode', backendNodeId=self._frame_ele._backend_id)['node'] if 'frameId' in node: break + sleep(.05) else: return diff --git a/DrissionPage/_units/selector.py b/DrissionPage/_units/selector.py index 6682f64..fe5a23a 100644 --- a/DrissionPage/_units/selector.py +++ b/DrissionPage/_units/selector.py @@ -5,7 +5,7 @@ @Copyright: (c) 2024 by g1879, Inc. All Rights Reserved. @License : BSD 3-Clause. """ -from time import perf_counter +from time import perf_counter, sleep class SelectElement(object): @@ -215,6 +215,7 @@ class SelectElement(object): if len(eles) >= text_len: ok = True break + sleep(.01) if ok: self._select_options(eles, mode) @@ -237,6 +238,7 @@ class SelectElement(object): if len(self.options) >= text_len: ok = True break + sleep(.01) if ok: eles = self.options diff --git a/DrissionPage/_units/waiter.py b/DrissionPage/_units/waiter.py index b8a1bc5..f244479 100644 --- a/DrissionPage/_units/waiter.py +++ b/DrissionPage/_units/waiter.py @@ -121,6 +121,7 @@ class BaseWaiter(OriginWaiter): while perf_counter() < end_time: if method([_find(l, self._driver.driver) for l in locators]): return True + sleep(.01) if raise_err is True or Settings.raise_when_wait_failed is True: raise WaitTimeoutError(f'等待元素{locators}加载失败(等待{timeout}秒)。') else: @@ -170,6 +171,7 @@ class BaseWaiter(OriginWaiter): if not isinstance(v, bool): r = v break + sleep(.005) self._driver.browser._dl_mgr.set_flag(self._driver.tab_id, None) return r @@ -472,6 +474,7 @@ class ElementWaiter(OriginWaiter): break except NoRectError: pass + sleep(.005) else: raise NoRectError