mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
修复WebPage的set.cookies问题;添加add_init_js()和remove_init_js();尝试修复获取元素大小报错
This commit is contained in:
parent
28544e2532
commit
c0f50e2bbf
@ -269,10 +269,6 @@ def raise_error(result, ignore=None):
|
|||||||
r = ElementLostError()
|
r = ElementLostError()
|
||||||
elif error in ('connection disconnected', 'No target with given id found'):
|
elif error in ('connection disconnected', 'No target with given id found'):
|
||||||
r = PageDisconnectedError()
|
r = PageDisconnectedError()
|
||||||
elif error == 'timeout':
|
|
||||||
r = TimeoutError(f'超时(等待{result["timeout"]}秒)。\n错误:{result["error"]}\nmethod:{result["method"]}\nargs:'
|
|
||||||
f'{result["args"]}\n出现这个错误可能意味着程序有bug,请把错误信息和重现方法告知作者,谢谢。\n'
|
|
||||||
'报告网站:https://gitee.com/g1879/DrissionPage/issues')
|
|
||||||
elif error == 'alert exists.':
|
elif error == 'alert exists.':
|
||||||
r = AlertExistsError()
|
r = AlertExistsError()
|
||||||
elif error in ('Node does not have a layout object', 'Could not compute box model.'):
|
elif error in ('Node does not have a layout object', 'Could not compute box model.'):
|
||||||
@ -283,10 +279,12 @@ def raise_error(result, ignore=None):
|
|||||||
r = StorageError()
|
r = StorageError()
|
||||||
elif error == 'Sanitizing cookie failed':
|
elif error == 'Sanitizing cookie failed':
|
||||||
r = CookieFormatError(f'cookie格式不正确:{result["args"]}')
|
r = CookieFormatError(f'cookie格式不正确:{result["args"]}')
|
||||||
elif result['type'] == 'call_method_error':
|
elif result['type'] in ('call_method_error', 'timeout'):
|
||||||
|
from DrissionPage import __version__
|
||||||
|
from time import process_time
|
||||||
r = CDPError(f'\n错误:{result["error"]}\nmethod:{result["method"]}\nargs:{result["args"]}\n'
|
r = CDPError(f'\n错误:{result["error"]}\nmethod:{result["method"]}\nargs:{result["args"]}\n'
|
||||||
f'出现这个错误可能意味着程序有bug,请把错误信息和重现方法告知作者,谢谢。'
|
f'版本:{__version__}\n运行时间:{process_time()}\n出现这个错误可能意味着程序有bug,请把错误信息和重现方法'
|
||||||
f'\n报告网站:https://gitee.com/g1879/DrissionPage/issues')
|
'告知作者,谢谢。\n报告网站:https://gitee.com/g1879/DrissionPage/issues')
|
||||||
else:
|
else:
|
||||||
r = RuntimeError(result)
|
r = RuntimeError(result)
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ class ChromiumBase(BasePage):
|
|||||||
self._doc_got = False # 用于在LoadEventFired和FrameStoppedLoading间标记是否已获取doc
|
self._doc_got = False # 用于在LoadEventFired和FrameStoppedLoading间标记是否已获取doc
|
||||||
self._download_path = None
|
self._download_path = None
|
||||||
self._load_end_time = 0
|
self._load_end_time = 0
|
||||||
|
self._init_jss = []
|
||||||
if not hasattr(self, '_listener'):
|
if not hasattr(self, '_listener'):
|
||||||
self._listener = None
|
self._listener = None
|
||||||
|
|
||||||
@ -492,7 +493,7 @@ class ChromiumBase(BasePage):
|
|||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
run_js(self, script, as_expr, 0, args)
|
run_js(self, script, as_expr, 0, args)
|
||||||
|
|
||||||
def get(self, url, show_errmsg=False, retry=None, interval=None, timeout=None):
|
def get(self, url, show_errmsg=False, retry=None, interval=None, timeout=None):
|
||||||
"""访问url
|
"""访问url
|
||||||
:param url: 目标url
|
:param url: 目标url
|
||||||
@ -796,6 +797,30 @@ class ChromiumBase(BasePage):
|
|||||||
return self._get_screenshot(path=path, name=name, as_bytes=as_bytes, as_base64=as_base64,
|
return self._get_screenshot(path=path, name=name, as_bytes=as_bytes, as_base64=as_base64,
|
||||||
full_page=full_page, left_top=left_top, right_bottom=right_bottom)
|
full_page=full_page, left_top=left_top, right_bottom=right_bottom)
|
||||||
|
|
||||||
|
def add_init_js(self, js):
|
||||||
|
"""添加初始化脚本,在页面加载任何脚本前执行
|
||||||
|
:param js: js文本
|
||||||
|
:return: 添加的脚本的id
|
||||||
|
"""
|
||||||
|
js_id = self.run_cdp('Page.addScriptToEvaluateOnNewDocument', source=js,
|
||||||
|
includeCommandLineAPI=True)['identifier']
|
||||||
|
self._init_jss.append(js_id)
|
||||||
|
return js_id
|
||||||
|
|
||||||
|
def remove_init_js(self, js_id=None):
|
||||||
|
"""删除初始化脚本,js_id传入None时删除所有
|
||||||
|
:param js_id: 脚本的id
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
if js_id is None:
|
||||||
|
for js_id in self._init_jss:
|
||||||
|
self.run_cdp('Page.removeScriptToEvaluateOnNewDocument', identifier=js_id)
|
||||||
|
self._init_jss.clear()
|
||||||
|
|
||||||
|
elif js_id in self._init_jss:
|
||||||
|
self.run_cdp('Page.removeScriptToEvaluateOnNewDocument', identifier=js_id)
|
||||||
|
self._init_jss.remove(js_id)
|
||||||
|
|
||||||
def clear_cache(self, session_storage=True, local_storage=True, cache=True, cookies=True):
|
def clear_cache(self, session_storage=True, local_storage=True, cache=True, cookies=True):
|
||||||
"""清除缓存,可选要清除的项
|
"""清除缓存,可选要清除的项
|
||||||
:param session_storage: 是否清除sessionStorage
|
:param session_storage: 是否清除sessionStorage
|
||||||
|
@ -58,6 +58,7 @@ class ChromiumBase(BasePage):
|
|||||||
self._has_alert: bool = ...
|
self._has_alert: bool = ...
|
||||||
self._doc_got: bool = ...
|
self._doc_got: bool = ...
|
||||||
self._load_end_time: float = ...
|
self._load_end_time: float = ...
|
||||||
|
self._init_jss: list = ...
|
||||||
self._ready_state: Optional[str] = ...
|
self._ready_state: Optional[str] = ...
|
||||||
self._rect: TabRect = ...
|
self._rect: TabRect = ...
|
||||||
|
|
||||||
@ -214,6 +215,10 @@ class ChromiumBase(BasePage):
|
|||||||
|
|
||||||
def get_local_storage(self, item: str = None) -> Union[str, dict, None]: ...
|
def get_local_storage(self, item: str = None) -> Union[str, dict, None]: ...
|
||||||
|
|
||||||
|
def add_init_js(self, js: str) -> str: ...
|
||||||
|
|
||||||
|
def remove_init_js(self, js_id: str = None) -> None: ...
|
||||||
|
|
||||||
def get_screenshot(self, path: [str, Path] = None, name: str = None, as_bytes: PIC_TYPE = None,
|
def get_screenshot(self, path: [str, Path] = None, name: str = None, as_bytes: PIC_TYPE = None,
|
||||||
as_base64: PIC_TYPE = None, full_page: bool = False, left_top: Tuple[int, int] = None,
|
as_base64: PIC_TYPE = None, full_page: bool = False, left_top: Tuple[int, int] = None,
|
||||||
right_bottom: Tuple[int, int] = None) -> Union[str, bytes]: ...
|
right_bottom: Tuple[int, int] = None) -> Union[str, bytes]: ...
|
||||||
|
@ -66,3 +66,38 @@ class SessionCookiesSetter(object):
|
|||||||
def clear(self):
|
def clear(self):
|
||||||
"""清除cookies"""
|
"""清除cookies"""
|
||||||
self._page.session.cookies.clear()
|
self._page.session.cookies.clear()
|
||||||
|
|
||||||
|
|
||||||
|
class WebPageCookiesSetter(CookiesSetter, SessionCookiesSetter):
|
||||||
|
|
||||||
|
def __call__(self, cookies):
|
||||||
|
"""设置多个cookie,注意不要传入单个
|
||||||
|
:param cookies: cookies信息
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
if self._page.mode == 'd' and self._page._has_driver:
|
||||||
|
super().__call__(cookies)
|
||||||
|
elif self._page.mode == 's' and self._page._has_session:
|
||||||
|
super(CookiesSetter, self).__call__(cookies)
|
||||||
|
|
||||||
|
def remove(self, name, url=None, domain=None, path=None):
|
||||||
|
"""删除一个cookie
|
||||||
|
:param name: cookie的name字段
|
||||||
|
:param url: cookie的url字段,可选,d模式时才有效
|
||||||
|
:param domain: cookie的domain字段,可选,d模式时才有效
|
||||||
|
:param path: cookie的path字段,可选,d模式时才有效
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
if self._page.mode == 'd' and self._page._has_driver:
|
||||||
|
super().remove(name, url, domain, path)
|
||||||
|
elif self._page.mode == 's' and self._page._has_session:
|
||||||
|
if url or domain or path:
|
||||||
|
raise AttributeError('url、domain、path参数只有d模式下有效。')
|
||||||
|
super(CookiesSetter, self).remove(name)
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
"""清除cookies"""
|
||||||
|
if self._page.mode == 'd' and self._page._has_driver:
|
||||||
|
super().clear()
|
||||||
|
elif self._page.mode == 's' and self._page._has_session:
|
||||||
|
super(CookiesSetter, self).clear()
|
||||||
|
@ -4,13 +4,16 @@ from typing import Union
|
|||||||
|
|
||||||
from requests.cookies import RequestsCookieJar
|
from requests.cookies import RequestsCookieJar
|
||||||
|
|
||||||
from .._pages.session_page import SessionPage
|
|
||||||
from .._pages.chromium_base import ChromiumBase
|
from .._pages.chromium_base import ChromiumBase
|
||||||
|
from .._pages.chromium_tab import WebPageTab
|
||||||
|
from .._pages.session_page import SessionPage
|
||||||
|
from .._pages.web_page import WebPage
|
||||||
|
|
||||||
|
|
||||||
class CookiesSetter(object):
|
class CookiesSetter(object):
|
||||||
def __init__(self, page: ChromiumBase):
|
_page: ChromiumBase
|
||||||
self._page: ChromiumBase = ...
|
|
||||||
|
def __init__(self, page: ChromiumBase): ...
|
||||||
|
|
||||||
def __call__(self, cookies: Union[RequestsCookieJar, Cookie, list, tuple, str, dict]) -> None: ...
|
def __call__(self, cookies: Union[RequestsCookieJar, Cookie, list, tuple, str, dict]) -> None: ...
|
||||||
|
|
||||||
@ -20,11 +23,24 @@ class CookiesSetter(object):
|
|||||||
|
|
||||||
|
|
||||||
class SessionCookiesSetter(object):
|
class SessionCookiesSetter(object):
|
||||||
def __init__(self, page: SessionPage):
|
_page: SessionPage
|
||||||
self._page: SessionPage = ...
|
|
||||||
|
def __init__(self, page: SessionPage): ...
|
||||||
|
|
||||||
def __call__(self, cookies: Union[RequestsCookieJar, Cookie, list, tuple, str, dict]) -> None: ...
|
def __call__(self, cookies: Union[RequestsCookieJar, Cookie, list, tuple, str, dict]) -> None: ...
|
||||||
|
|
||||||
def remove(self, name: str) -> None: ...
|
def remove(self, name: str) -> None: ...
|
||||||
|
|
||||||
def clear(self) -> None: ...
|
def clear(self) -> None: ...
|
||||||
|
|
||||||
|
|
||||||
|
class WebPageCookiesSetter(CookiesSetter, SessionCookiesSetter):
|
||||||
|
_page: Union[WebPage, WebPageTab]
|
||||||
|
|
||||||
|
def __init__(self, page: SessionPage): ...
|
||||||
|
|
||||||
|
def __call__(self, cookies: Union[RequestsCookieJar, Cookie, list, tuple, str, dict]) -> None: ...
|
||||||
|
|
||||||
|
def remove(self, name: str, url: str = None, domain: str = None, path: str = None) -> None: ...
|
||||||
|
|
||||||
|
def clear(self) -> None: ...
|
||||||
|
@ -30,7 +30,8 @@ class ElementRect(object):
|
|||||||
@property
|
@property
|
||||||
def size(self):
|
def size(self):
|
||||||
"""返回元素大小,格式(宽, 高)"""
|
"""返回元素大小,格式(宽, 高)"""
|
||||||
border = self._ele.page.run_cdp('DOM.getBoxModel', backendNodeId=self._ele._backend_id)['model']['border']
|
border = self._ele.page.run_cdp('DOM.getBoxModel', backendNodeId=self._ele._backend_id,
|
||||||
|
nodeId=self._ele._node_id, objectId=self._ele._obj_id)['model']['border']
|
||||||
return border[2] - border[0], border[5] - border[1]
|
return border[2] - border[0], border[5] - border[1]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -98,7 +99,8 @@ class ElementRect(object):
|
|||||||
:param quad: 方框类型,margin border padding
|
:param quad: 方框类型,margin border padding
|
||||||
:return: 四个角坐标
|
:return: 四个角坐标
|
||||||
"""
|
"""
|
||||||
return self._ele.page.run_cdp('DOM.getBoxModel', backendNodeId=self._ele._backend_id)['model'][quad]
|
return self._ele.page.run_cdp('DOM.getBoxModel', backendNodeId=self._ele._backend_id,
|
||||||
|
nodeId=self._ele._node_id, objectId=self._ele._obj_id)['model'][quad]
|
||||||
|
|
||||||
def _get_page_coord(self, x, y):
|
def _get_page_coord(self, x, y):
|
||||||
"""根据视口坐标获取绝对坐标"""
|
"""根据视口坐标获取绝对坐标"""
|
||||||
|
@ -7,10 +7,9 @@ from pathlib import Path
|
|||||||
|
|
||||||
from requests.structures import CaseInsensitiveDict
|
from requests.structures import CaseInsensitiveDict
|
||||||
|
|
||||||
from .cookies_setter import SessionCookiesSetter, CookiesSetter
|
from .cookies_setter import SessionCookiesSetter, CookiesSetter, WebPageCookiesSetter
|
||||||
from .._functions.tools import show_or_hide_browser
|
from .._functions.tools import show_or_hide_browser
|
||||||
|
|
||||||
__ERROR__ = 'error'
|
|
||||||
|
|
||||||
class BasePageSetter(object):
|
class BasePageSetter(object):
|
||||||
def __init__(self, page):
|
def __init__(self, page):
|
||||||
@ -199,19 +198,6 @@ class TabSetter(ChromiumBaseSetter):
|
|||||||
"""使标签页处于最前面"""
|
"""使标签页处于最前面"""
|
||||||
self._page.browser.activate_tab(self._page.tab_id)
|
self._page.browser.activate_tab(self._page.tab_id)
|
||||||
|
|
||||||
def add_init_script(self, script: str, raise_error=True):
|
|
||||||
'''添加初始化脚本,在页面加载任何脚本前执行
|
|
||||||
:param script: js文本
|
|
||||||
:return: identifier 添加的脚本的标识符,失败时返回False,或raise Error
|
|
||||||
'''
|
|
||||||
result = self.driver.run('Page.addScriptToEvaluateOnNewDocument', source=script)
|
|
||||||
if not result or __ERROR__ not in result:
|
|
||||||
return result['identifier']
|
|
||||||
else:
|
|
||||||
if raise_error:
|
|
||||||
raise_error(str(result))
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class ChromiumPageSetter(TabSetter):
|
class ChromiumPageSetter(TabSetter):
|
||||||
|
|
||||||
@ -384,15 +370,12 @@ class WebPageSetter(ChromiumPageSetter):
|
|||||||
self._session_setter = SessionPageSetter(self._page)
|
self._session_setter = SessionPageSetter(self._page)
|
||||||
self._chromium_setter = ChromiumPageSetter(self._page)
|
self._chromium_setter = ChromiumPageSetter(self._page)
|
||||||
|
|
||||||
def cookies(self, cookies):
|
@property
|
||||||
"""添加cookies信息到浏览器或session对象
|
def cookies(self):
|
||||||
:param cookies: 可以接收`CookieJar`、`list`、`tuple`、`str`、`dict`格式的`cookies`
|
"""返回用于设置cookies的对象"""
|
||||||
:return: None
|
if self._cookies_setter is None:
|
||||||
"""
|
self._cookies_setter = WebPageCookiesSetter(self._page)
|
||||||
if self._page.mode == 'd' and self._page._has_driver:
|
return self._cookies_setter
|
||||||
self._chromium_setter.cookies(cookies)
|
|
||||||
elif self._page.mode == 's' and self._page._has_session:
|
|
||||||
self._session_setter.cookies(cookies)
|
|
||||||
|
|
||||||
def headers(self, headers) -> None:
|
def headers(self, headers) -> None:
|
||||||
"""设置固定发送的headers
|
"""设置固定发送的headers
|
||||||
@ -418,15 +401,12 @@ class WebPageTabSetter(TabSetter):
|
|||||||
self._session_setter = SessionPageSetter(self._page)
|
self._session_setter = SessionPageSetter(self._page)
|
||||||
self._chromium_setter = ChromiumBaseSetter(self._page)
|
self._chromium_setter = ChromiumBaseSetter(self._page)
|
||||||
|
|
||||||
def cookies(self, cookies):
|
@property
|
||||||
"""添加多个cookies信息到浏览器或session对象,注意不要传入单个
|
def cookies(self):
|
||||||
:param cookies: 可以接收`CookieJar`、`list`、`tuple`、`str`、`dict`格式的`cookies`
|
"""返回用于设置cookies的对象"""
|
||||||
:return: None
|
if self._cookies_setter is None:
|
||||||
"""
|
self._cookies_setter = WebPageCookiesSetter(self._page)
|
||||||
if self._page.mode == 'd' and self._page._has_driver:
|
return self._cookies_setter
|
||||||
self._chromium_setter.cookies(cookies)
|
|
||||||
elif self._page.mode == 's' and self._page._has_session:
|
|
||||||
self._session_setter.cookies(cookies)
|
|
||||||
|
|
||||||
def headers(self, headers) -> None:
|
def headers(self, headers) -> None:
|
||||||
"""设置固定发送的headers
|
"""设置固定发送的headers
|
||||||
|
@ -9,7 +9,7 @@ from typing import Union, Tuple, Literal, Any, Optional
|
|||||||
from requests.adapters import HTTPAdapter
|
from requests.adapters import HTTPAdapter
|
||||||
from requests.auth import HTTPBasicAuth
|
from requests.auth import HTTPBasicAuth
|
||||||
|
|
||||||
from .cookies_setter import SessionCookiesSetter, CookiesSetter
|
from .cookies_setter import SessionCookiesSetter, CookiesSetter, WebPageCookiesSetter
|
||||||
from .scroller import PageScroller
|
from .scroller import PageScroller
|
||||||
from .._base.base import BasePage
|
from .._base.base import BasePage
|
||||||
from .._elements.chromium_element import ChromiumElement
|
from .._elements.chromium_element import ChromiumElement
|
||||||
@ -143,7 +143,8 @@ class WebPageSetter(ChromiumPageSetter):
|
|||||||
|
|
||||||
def headers(self, headers: dict) -> None: ...
|
def headers(self, headers: dict) -> None: ...
|
||||||
|
|
||||||
def cookies(self, cookies) -> None: ...
|
@property
|
||||||
|
def cookies(self) -> WebPageCookiesSetter: ...
|
||||||
|
|
||||||
|
|
||||||
class WebPageTabSetter(TabSetter):
|
class WebPageTabSetter(TabSetter):
|
||||||
@ -155,7 +156,8 @@ class WebPageTabSetter(TabSetter):
|
|||||||
|
|
||||||
def headers(self, headers: dict) -> None: ...
|
def headers(self, headers: dict) -> None: ...
|
||||||
|
|
||||||
def cookies(self, cookies) -> None: ...
|
@property
|
||||||
|
def cookies(self) -> WebPageCookiesSetter: ...
|
||||||
|
|
||||||
|
|
||||||
class ChromiumElementSetter(object):
|
class ChromiumElementSetter(object):
|
||||||
|
@ -412,7 +412,7 @@ class ElementWaiter(object):
|
|||||||
|
|
||||||
while perf_counter() < end_time:
|
while perf_counter() < end_time:
|
||||||
sleep(gap)
|
sleep(gap)
|
||||||
if self._ele.rect.size == size and location == self._ele.rect.location:
|
if self._ele.rect.size == size and self._ele.rect.location == location:
|
||||||
return True
|
return True
|
||||||
size = self._ele.rect.size
|
size = self._ele.rect.size
|
||||||
location = self._ele.rect.location
|
location = self._ele.rect.location
|
||||||
|
Loading…
x
Reference in New Issue
Block a user