4.0.0b38修复问题

This commit is contained in:
g1879 2024-01-12 17:39:56 +08:00
parent d2068e49b5
commit bc9bc71777
7 changed files with 43 additions and 17 deletions

View File

@ -14,4 +14,4 @@ from ._configs.chromium_options import ChromiumOptions
from ._configs.session_options import SessionOptions from ._configs.session_options import SessionOptions
__all__ = ['ChromiumPage', 'ChromiumOptions', 'SessionOptions', 'SessionPage', 'WebPage', '__version__'] __all__ = ['ChromiumPage', 'ChromiumOptions', 'SessionOptions', 'SessionPage', 'WebPage', '__version__']
__version__ = '4.0.0b37' __version__ = '4.0.0b38'

View File

@ -1393,7 +1393,7 @@ else{a.push(e.snapshotItem(i));}}"""
return js 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代码 """运行javascript代码
:param page_or_ele: 页面对象或元素对象 :param page_or_ele: 页面对象或元素对象
:param script: js文本 :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: if page.states.has_alert:
raise AlertExistsError raise AlertExistsError
end_time = perf_counter() + timeout
try: try:
if as_expr: if as_expr:
res = page.run_cdp('Runtime.evaluate', expression=script, returnByValue=False, 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}') raise JavaScriptError(f'\njavascript运行错误\n{script}\n错误信息: \n{exceptionDetails}')
try: 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: except Exception:
return res return res
def parse_js_result(page, ele, result): def parse_js_result(page, ele, result, end_time):
"""解析js返回的结果""" """解析js返回的结果"""
if 'unserializableValue' in result: if 'unserializableValue' in result:
return result['unserializableValue'] return result['unserializableValue']
@ -1478,17 +1479,21 @@ def parse_js_result(page, ele, result):
elif sub_type == 'array': elif sub_type == 'array':
r = page.run_cdp('Runtime.getProperties', objectId=result['objectId'], ownProperties=True)['result'] 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 elif 'objectId' in result and result['className'].lower() == 'object': # dict
r = page.run_cdp('Runtime.getProperties', objectId=result['objectId'], ownProperties=True)['result'] 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: elif 'objectId' in result:
timeout = end_time - perf_counter()
if timeout < 0:
return
js = 'function(){return JSON.stringify(this);}' js = 'function(){return JSON.stringify(this);}'
r = page.run_cdp('Runtime.callFunctionOn', functionDeclaration=js, objectId=result['objectId'], r = page.run_cdp('Runtime.callFunctionOn', functionDeclaration=js, objectId=result['objectId'],
returnByValue=False, awaitPromise=True, userGesture=True, _ignore=AlertExistsError) returnByValue=False, awaitPromise=True, userGesture=True, _ignore=AlertExistsError,
return loads(parse_js_result(page, ele, r['result'])) _timeout=timeout)
return loads(parse_js_result(page, ele, r['result'], end_time))
else: else:
return result.get('value', result) return result.get('value', result)

View File

@ -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], def run_js(page_or_ele: Union[ChromiumBase, ChromiumElement, ShadowRoot],
script: str, script: str,
as_expr: bool = False, as_expr: bool,
timeout: float = None, timeout: float,
args: tuple = ...) -> Any: ... 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: ... def convert_argument(arg: Any) -> dict: ...

View File

@ -31,8 +31,8 @@ class ChromiumPage(ChromiumBase):
:param timeout: 超时时间 :param timeout: 超时时间
""" """
addr_or_opts = addr_or_opts or addr_driver_opts addr_or_opts = addr_or_opts or addr_driver_opts
opt = _handle_options(addr_or_opts) opt = handle_options(addr_or_opts)
is_exist, browser_id = _run_browser(opt) is_exist, browser_id = run_browser(opt)
if browser_id in cls.PAGES: if browser_id in cls.PAGES:
return cls.PAGES[browser_id] return cls.PAGES[browser_id]
r = object.__new__(cls) r = object.__new__(cls)
@ -261,7 +261,7 @@ class ChromiumPage(ChromiumBase):
self.close_tabs(tabs_or_ids, True) 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'ChromiumOptionsDriver :param addr_or_opts: 'ip:port'ChromiumOptionsDriver
:return: 返回ChromiumOptions对象 :return: 返回ChromiumOptions对象
@ -291,7 +291,7 @@ def _handle_options(addr_or_opts):
return _chromium_options return _chromium_options
def _run_browser(chromium_options): def run_browser(chromium_options):
"""连接浏览器""" """连接浏览器"""
is_exist = connect_browser(chromium_options) is_exist = connect_browser(chromium_options)
try: try:

View File

@ -106,4 +106,10 @@ class ChromiumPage(ChromiumBase):
def _on_disconnect(self) -> None: ... def _on_disconnect(self) -> None: ...
def handle_options(addr_or_opts): ...
def run_browser(chromium_options): ...
def get_rename(original: str, rename: str) -> str: ... def get_rename(original: str, rename: str) -> str: ...

View File

@ -17,6 +17,16 @@ from .._units.setter import WebPageSetter
class WebPage(SessionPage, ChromiumPage, BasePage): class WebPage(SessionPage, ChromiumPage, BasePage):
"""整合浏览器和request的页面类""" """整合浏览器和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): def __init__(self, mode='d', timeout=None, chromium_options=None, session_or_options=None, driver_or_options=None):
"""初始化函数 """初始化函数
:param mode: 'd' 's'即driver模式和session模式 :param mode: 'd' 's'即driver模式和session模式
@ -24,7 +34,9 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
:param chromium_options: Driver对象只使用s模式时应传入False :param chromium_options: Driver对象只使用s模式时应传入False
:param session_or_options: Session对象或SessionOptions对象只使用d模式时应传入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() self._mode = mode.lower()
if self._mode not in ('s', 'd'): if self._mode not in ('s', 'd'):
raise ValueError('mode参数只能是s或d。') raise ValueError('mode参数只能是s或d。')

View File

@ -6,7 +6,7 @@ with open("README.md", "r", encoding='utf-8') as fh:
setup( setup(
name="DrissionPage", name="DrissionPage",
version="4.0.0b37", version="4.0.0b38",
author="g1879", author="g1879",
author_email="g1879@qq.com", author_email="g1879@qq.com",
description="Python based web automation tool. It can control the browser and send and receive data packets.", description="Python based web automation tool. It can control the browser and send and receive data packets.",