4.0.0b18(+)

SessionPage增加设置编码功能;
listen.wait()增加raise_err参数;
优化set.local_storage()、set.session_storage()和clear_cache();
各类增加__repr__;
指定新版DownloadKit
This commit is contained in:
g1879 2023-12-10 01:07:37 +08:00
parent 1a5ec884f1
commit ae417542b7
14 changed files with 89 additions and 18 deletions

View File

@ -593,6 +593,9 @@ class ChromiumOptions(object):
on_off = None if on_off else False
return self.set_argument('--mute-audio', on_off)
def __repr__(self):
return f'<ChromiumOptions at {id(self)}>'
class PortFinder(object):
used_port = {}

View File

@ -457,6 +457,9 @@ class SessionOptions(object):
self._download_path = str(download_path)
return self
def __repr__(self):
return f'<SessionOptions at {id(self)}>'
def session_options_to_dict(options):
"""把session配置对象转换为字典

View File

@ -820,12 +820,18 @@ class ChromiumBase(BasePage):
:param cookies: 是否清除cookies
:return: None
"""
if session_storage:
self.run_js('sessionStorage.clear();', as_expr=True)
if local_storage:
self.run_js('localStorage.clear();', as_expr=True)
if session_storage or local_storage:
self.run_cdp_loaded('DOMStorage.enable')
i = self.run_cdp('Storage.getStorageKeyForFrame', frameId=self._frame_id)['storageKey']
if session_storage:
self.run_cdp('DOMStorage.clear', storageId={'storageKey': i, 'isLocalStorage': False})
if local_storage:
self.run_cdp('DOMStorage.clear', storageId={'storageKey': i, 'isLocalStorage': True})
self.run_cdp_loaded('DOMStorage.disable')
if cache:
self.run_cdp_loaded('Network.clearBrowserCache')
if cookies:
self.run_cdp_loaded('Network.clearBrowserCookies')

View File

@ -248,6 +248,9 @@ class ChromiumPage(ChromiumBase):
"""
self.browser.quit(timeout, force)
def __repr__(self):
return f'<ChromiumPage browser_id={self.browser.id} tab_id={self.tab_id}>'
def get_rename(original, rename):
if '.' in rename:

View File

@ -58,6 +58,9 @@ class ChromiumTab(ChromiumBase):
self._wait = TabWaiter(self)
return self._wait
def __repr__(self):
return f'<ChromiumTab browser_id={self.browser.id} tab_id={self.tab_id}>'
class WebPageTab(SessionPage, ChromiumTab, BasePage):
def __init__(self, page, tab_id):
@ -353,3 +356,6 @@ class WebPageTab(SessionPage, ChromiumTab, BasePage):
elif self._mode == 'd':
return super(SessionPage, self)._find_elements(loc_or_ele, timeout=timeout, single=single,
relative=relative)
def __repr__(self):
return f'<WebPageTab browser_id={self.browser.id} tab_id={self.tab_id}>'

View File

@ -32,6 +32,7 @@ class SessionPage(BasePage):
self._response = None
self._session = None
self._set = None
self._encoding = None
self._s_set_start_options(session_or_options)
self._s_set_runtime_settings()
self._create_session()
@ -122,6 +123,11 @@ class SessionPage(BasePage):
"""返回访问url得到的response对象"""
return self._response
@property
def encoding(self):
"""返回设置的编码"""
return self._encoding
@property
def set(self):
"""返回用于等待的对象"""
@ -151,7 +157,6 @@ class SessionPage(BasePage):
r.status_code = 200
self._response = r
return
retry, interval = self._before_connect(url, retry, interval)
return self._s_connect(url, 'get', None, show_errmsg, retry, interval, **kwargs)
def ele(self, loc_or_ele, timeout=None):
@ -233,7 +238,6 @@ class SessionPage(BasePage):
:param kwargs: 连接参数
:return: url是否可用
"""
retry, interval = self._before_connect(url, retry, interval)
return self._s_connect(url, 'post', data, show_errmsg, retry, interval, **kwargs)
def close(self):
@ -289,7 +293,7 @@ class SessionPage(BasePage):
:param data: post方式要提交的数据
:param show_errmsg: 是否显示和抛出异常
:param kwargs: 其它参数
:return: tuple第一位为Response或None第二位为出错信息或'Success'
:return: tuple第一位为Response或None第二位为出错信息或 'Success'
"""
kwargs = CaseInsensitiveDict(kwargs)
if 'headers' not in kwargs:
@ -322,6 +326,9 @@ class SessionPage(BasePage):
r = self.session.post(url, data=data, **kwargs)
if r and r.content:
if self._encoding:
r.encoding = self._encoding
return r, 'Success'
return set_charset(r), 'Success'
except Exception as e:
@ -348,6 +355,9 @@ class SessionPage(BasePage):
raise ConnectionError(f'状态码:{r.status_code}')
return r, f'状态码:{r.status_code}'
def __repr__(self):
return f'<SessionPage url={self.url}>'
def check_headers(kwargs, headers, arg):
"""检查kwargs或headers中是否有arg所示属性"""

View File

@ -30,6 +30,7 @@ class SessionPage(BasePage):
self.retry_times: int = ...
self.retry_interval: float = ...
self._set: SessionPageSetter = ...
self._encoding: str = ...
def _s_set_start_options(self, session_or_options: Union[Session, SessionOptions]) -> None: ...
@ -114,6 +115,9 @@ class SessionPage(BasePage):
@property
def response(self) -> Response: ...
@property
def encoding(self) -> str: ...
@property
def set(self) -> SessionPageSetter: ...

View File

@ -387,3 +387,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
super(SessionPage, self).quit(timeout, force)
self._driver = None
self._has_driver = None
def __repr__(self):
return f'<WebPage browser_id={self.browser.id} tab_id={self.tab_id}>'

View File

@ -12,6 +12,8 @@ from time import perf_counter, sleep
from requests.structures import CaseInsensitiveDict
from .._base.chromium_driver import ChromiumDriver
from .._functions.settings import Settings
from ..errors import WaitTimeoutError
class Listener(object):
@ -87,11 +89,12 @@ class Listener(object):
self._set_callback()
def wait(self, count=1, timeout=None, fit_count=True):
def wait(self, count=1, timeout=None, fit_count=True, raise_err=None):
"""等待符合要求的数据包到达指定数量
:param count: 需要捕捉的数据包数量
:param timeout: 超时时间为None无限等待
:param fit_count: 是否必须满足总数要求发生超时为True返回False为False返回已捕捉到的数据包
:param raise_err: 超时时是否抛出错误为None时根据Settings设置
:return: count为1时返回数据包对象大于1时返回列表超时且fit_count为True时返回False
"""
if not self.listening:
@ -113,7 +116,10 @@ class Listener(object):
if fail:
if fit_count or not self._caught.qsize():
return False
if raise_err is True or Settings.raise_when_wait_failed is True:
raise WaitTimeoutError('等待数据包失败。')
else:
return False
else:
return [self._caught.get_nowait() for _ in range(self._caught.qsize())]

View File

@ -40,8 +40,8 @@ class Listener(object):
def go_on(self) -> None: ...
def wait(self, count: int = 1, timeout: float = None,
fit_count: bool = True) -> Union[List[DataPacket], DataPacket, None]: ...
def wait(self, count: int = 1, timeout: float = None, fit_count: bool = True,
raise_err: bool = None) -> Union[List[DataPacket], DataPacket, None]: ...
@property
def results(self) -> Union[DataPacket, Dict[str, List[DataPacket]], False]: ...

View File

@ -82,8 +82,15 @@ class ChromiumBaseSetter(BasePageSetter):
:param value: 项的值设置为False时删除该项
:return: None
"""
js = f'sessionStorage.removeItem("{item}");' if item is False else f'sessionStorage.setItem("{item}","{value}");'
return self._page.run_js_loaded(js, as_expr=True)
self._page.run_cdp_loaded('DOMStorage.enable')
i = self._page.run_cdp('Storage.getStorageKeyForFrame', frameId=self._page._frame_id)['storageKey']
if value is False:
self._page.run_cdp('DOMStorage.removeDOMStorageItem',
storageId={'storageKey': i, 'isLocalStorage': False}, key=item)
else:
self._page.run_cdp('DOMStorage.setDOMStorageItem', storageId={'storageKey': i, 'isLocalStorage': False},
key=item, value=value)
self._page.run_cdp_loaded('DOMStorage.disable')
def local_storage(self, item, value):
"""设置或删除某项localStorage信息
@ -91,8 +98,15 @@ class ChromiumBaseSetter(BasePageSetter):
:param value: 项的值设置为False时删除该项
:return: None
"""
js = f'localStorage.removeItem("{item}");' if item is False else f'localStorage.setItem("{item}","{value}");'
return self._page.run_js_loaded(js, as_expr=True)
self._page.run_cdp_loaded('DOMStorage.enable')
i = self._page.run_cdp('Storage.getStorageKeyForFrame', frameId=self._page._frame_id)['storageKey']
if value is False:
self._page.run_cdp('DOMStorage.removeDOMStorageItem',
storageId={'storageKey': i, 'isLocalStorage': True}, key=item)
else:
self._page.run_cdp('DOMStorage.setDOMStorageItem', storageId={'storageKey': i, 'isLocalStorage': True},
key=item, value=value)
self._page.run_cdp_loaded('DOMStorage.disable')
def cookie(self, cookie):
"""设置单个cookie
@ -237,6 +251,17 @@ class SessionPageSetter(BasePageSetter):
"""
self._page.timeout = second
def encoding(self, encoding, set_all=True):
"""设置编码
:param encoding: 编码名称
:param set_all: 是否设置对象参数为False则只设置当前response
:return: None
"""
if set_all:
self._page._encoding = encoding
if self._page.response:
self._page.response.encoding = encoding
def cookie(self, cookie):
"""为Session对象设置单个cookie
:param cookie: cookie信息

View File

@ -100,6 +100,8 @@ class SessionPageSetter(BasePageSetter):
def timeout(self, second: float) -> None: ...
def encoding(self, encoding: str, set_all: bool = True) -> None: ...
def cookie(self, cookie: Union[Cookie, str, dict]) -> None: ...
def cookies(self, cookies: Union[RequestsCookieJar, list, tuple, str, dict]) -> None: ...

View File

@ -1,7 +1,7 @@
requests
lxml
cssselect
DownloadKit>=1.0.0
DownloadKit>=2.0.0b0
FlowViewer>=0.3.0
websocket-client
click

View File

@ -22,7 +22,7 @@ setup(
'lxml',
'requests',
'cssselect',
'DownloadKit>=1.0.0',
'DownloadKit>=2.0.0b0',
'FlowViewer>=0.3.0',
'websocket-client',
'click',