4.0.4.20add_ele()添加元素可不插入DOM;修复run_js()不可传入dict参数问题;while均添加sleep()

This commit is contained in:
g1879 2024-03-31 11:02:51 +08:00
parent b938a85c9a
commit 5578bf57a5
9 changed files with 74 additions and 29 deletions

View File

@ -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'

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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文本或tupletuple格式为(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,

View File

@ -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: ...

View File

@ -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

View File

@ -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

View File

@ -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