完善监听器逻辑;修复to_tab()报错

This commit is contained in:
g1879 2023-10-24 16:54:35 +08:00
parent 90c715aeae
commit 301569a9cb
7 changed files with 71 additions and 35 deletions

View File

@ -93,14 +93,15 @@ class ChromiumBase(BasePage):
self._get_document() self._get_document()
self._first_run = False self._first_run = False
def _driver_init(self, tab_id): def _driver_init(self, tab_id, is_init=True):
"""新建页面、页面刷新、切换标签页后要进行的cdp参数初始化 """新建页面、页面刷新、切换标签页后要进行的cdp参数初始化
:param tab_id: 要跳转到的标签页id :param tab_id: 要跳转到的标签页id
:param is_init: 是否初始化时执行本方法用于判断是否to_tab()调用
:return: None :return: None
""" """
self._is_loading = True self._is_loading = True
if hasattr(self, '_driver'): if is_init and hasattr(self, '_driver'):
return return # ChromiumPage接收ChromiumDriver方式启动时
self._driver = ChromiumDriver(tab_id=tab_id, tab_type='page', address=self.address) self._driver = ChromiumDriver(tab_id=tab_id, tab_type='page', address=self.address)
self._driver.call_method('DOM.enable') self._driver.call_method('DOM.enable')
@ -379,6 +380,7 @@ class ChromiumBase(BasePage):
self.wait.load_complete() self.wait.load_complete()
if self._scroll is None: if self._scroll is None:
self._scroll = ChromiumPageScroll(self) self._scroll = ChromiumPageScroll(self)
self.set.scroll.smooth(False)
return self._scroll return self._scroll
@property @property

View File

@ -50,7 +50,7 @@ class ChromiumBase(BasePage):
def _connect_browser(self, tab_id: str = None) -> None: ... def _connect_browser(self, tab_id: str = None) -> None: ...
def _driver_init(self, tab_id: str) -> None: ... def _driver_init(self, tab_id: str, is_init:bool=True) -> None: ...
def _get_document(self) -> None: ... def _get_document(self) -> None: ...

View File

@ -81,9 +81,8 @@ class ChromiumFrame(ChromiumBase):
self.retry_interval = self._target_page.retry_interval self.retry_interval = self._target_page.retry_interval
self._page_load_strategy = self._target_page.page_load_strategy self._page_load_strategy = self._target_page.page_load_strategy
self._download_path = self._target_page.download_path self._download_path = self._target_page.download_path
# self._when_download_file_exists = self._target_page._when_download_file_exists
def _driver_init(self, tab_id): def _driver_init(self, tab_id, is_init=True):
"""避免出现服务器500错误 """避免出现服务器500错误
:param tab_id: 要跳转到的标签页id :param tab_id: 要跳转到的标签页id
:return: None :return: None

View File

@ -17,6 +17,7 @@ from .._pages.chromium_tab import ChromiumTab
from .._units.setter import ChromiumPageSetter from .._units.setter import ChromiumPageSetter
from .._units.tab_rect import ChromiumTabRect from .._units.tab_rect import ChromiumTabRect
from .._units.waiter import ChromiumPageWaiter from .._units.waiter import ChromiumPageWaiter
from ..errors import BrowserConnectError
class ChromiumPage(ChromiumBase): class ChromiumPage(ChromiumBase):
@ -65,8 +66,11 @@ class ChromiumPage(ChromiumBase):
"""连接浏览器""" """连接浏览器"""
connect_browser(self._driver_options) connect_browser(self._driver_options)
ws = get(f'http://{self._driver_options.debugger_address}/json/version', ws = get(f'http://{self._driver_options.debugger_address}/json/version',
headers={'Connection': 'close'}).json()['webSocketDebuggerUrl'] headers={'Connection': 'close'})
self._browser = Browser(self._driver_options.debugger_address, ws.split('/')[-1], self) if not ws:
raise BrowserConnectError('\n浏览器连接失败请检查是否启用全局代理。如有须开放127.0.0.1地址。')
ws = ws.json()['webSocketDebuggerUrl'].split('/')[-1]
self._browser = Browser(self._driver_options.debugger_address, ws, self)
def _d_set_runtime_settings(self): def _d_set_runtime_settings(self):
"""设置运行时用到的属性""" """设置运行时用到的属性"""
@ -230,7 +234,7 @@ class ChromiumPage(ChromiumBase):
return return
self.driver.stop() self.driver.stop()
self._driver_init(tab_id) self._driver_init(tab_id, False)
if read_doc and self.ready_state in ('complete', None): if read_doc and self.ready_state in ('complete', None):
self._get_document() self._get_document()

View File

@ -23,8 +23,7 @@ class NetworkListener(object):
:param page: ChromiumBase对象 :param page: ChromiumBase对象
""" """
self._page = page self._page = page
self._driver = ChromiumDriver(page.tab_id, 'page', page.address) self._driver = None
self._driver.call_method('Network.enable')
self._caught = None # 临存捕捉到的数据 self._caught = None # 临存捕捉到的数据
self._request_ids = None # 暂存须要拦截的请求id self._request_ids = None # 暂存须要拦截的请求id
@ -75,6 +74,11 @@ class NetworkListener(object):
""" """
if targets: if targets:
self.set_targets(targets, is_regex, method) self.set_targets(targets, is_regex, method)
if self.listening:
return
self._driver = ChromiumDriver(self._page.tab_id, 'page', self._page.address)
self._driver.call_method('Network.enable')
self.listening = True self.listening = True
self._request_ids = {} self._request_ids = {}
@ -118,10 +122,10 @@ class NetworkListener(object):
return [self._caught.get_nowait() for _ in range(count)] return [self._caught.get_nowait() for _ in range(count)]
def steps(self, count=None, timeout=None, gap=1): def steps(self, count=None, timeout=None, gap=1):
"""用于单步操作,可实现收到若干个数据包执行一步操作(如翻页) """用于单步操作,可实现收到若干个数据包执行一步操作(如翻页)
:param count: 需捕获的数据包总数为None表示无限 :param count: 需捕获的数据包总数为None表示无限
:param timeout: 每个数据包等待时间为None表示无限 :param timeout: 每个数据包等待时间为None表示无限
:param gap: 每接收到多少个数据包触发 :param gap: 每接收到多少个数据包返回一次数据
:return: 用于在接收到监听目标时触发动作的可迭代对象 :return: 用于在接收到监听目标时触发动作的可迭代对象
""" """
caught = 0 caught = 0
@ -144,6 +148,8 @@ class NetworkListener(object):
if self.listening: if self.listening:
self.pause() self.pause()
self.clear() self.clear()
self._driver.stop()
self._driver = None
def pause(self, clear=True): def pause(self, clear=True):
"""暂停监听 """暂停监听
@ -181,7 +187,7 @@ class NetworkListener(object):
def _requestWillBeSent(self, **kwargs): def _requestWillBeSent(self, **kwargs):
"""接收到请求时的回调函数""" """接收到请求时的回调函数"""
if not self._targets: if not self._targets:
self._request_ids[kwargs['requestId']] = DataPacket(self._driver.id, None, kwargs) self._request_ids[kwargs['requestId']] = DataPacket(self._page.tab_id, None, kwargs)
if kwargs['request'].get('hasPostData', None) and not kwargs['request'].get('postData', None): if kwargs['request'].get('hasPostData', None) and not kwargs['request'].get('postData', None):
self._request_ids[kwargs['requestId']]._raw_post_data = \ self._request_ids[kwargs['requestId']]._raw_post_data = \
self._driver.call_method('Network.getRequestPostData', requestId=kwargs['requestId'])['postData'] self._driver.call_method('Network.getRequestPostData', requestId=kwargs['requestId'])['postData']
@ -192,7 +198,7 @@ class NetworkListener(object):
if ((self._is_regex and search(target, kwargs['request']['url'])) or if ((self._is_regex and search(target, kwargs['request']['url'])) or
(not self._is_regex and target in kwargs['request']['url'])) and ( (not self._is_regex and target in kwargs['request']['url'])) and (
not self._method or kwargs['request']['method'] in self._method): not self._method or kwargs['request']['method'] in self._method):
self._request_ids[kwargs['requestId']] = DataPacket(self._driver.id, target, kwargs) self._request_ids[kwargs['requestId']] = DataPacket(self._page.tab_id, target, kwargs)
if kwargs['request'].get('hasPostData', None) and not kwargs['request'].get('postData', None): if kwargs['request'].get('hasPostData', None) and not kwargs['request'].get('postData', None):
self._request_ids[kwargs['requestId']]._raw_post_data = \ self._request_ids[kwargs['requestId']]._raw_post_data = \
@ -253,7 +259,7 @@ class DataPacket(object):
:param target: 监听目标 :param target: 监听目标
:param raw_request: 原始request数据从cdp获得 :param raw_request: 原始request数据从cdp获得
""" """
self.tab = tab_id self.tab_id = tab_id
self.target = target self.target = target
self._raw_request = raw_request self._raw_request = raw_request
@ -353,6 +359,11 @@ class Response(object):
self._headers = CaseInsensitiveDict(self._response['headers']) self._headers = CaseInsensitiveDict(self._response['headers'])
return self._headers return self._headers
@property
def raw_body(self):
"""返回未被处理的body文本"""
return self._raw_body
@property @property
def body(self): def body(self):
"""返回body内容如果是json格式自动进行转换如果时图片格式进行base64转换其它格式直接返回文本""" """返回body内容如果是json格式自动进行转换如果时图片格式进行base64转换其它格式直接返回文本"""

View File

@ -100,14 +100,15 @@ class Request(object):
_headers: Union[CaseInsensitiveDict, None] = ... _headers: Union[CaseInsensitiveDict, None] = ...
method: str = ... method: str = ...
# urlFragment: str = ... urlFragment = ...
# postDataEntries: list = ... hasPostData = ...
# mixedContentType: str = ... postDataEntries = ...
# initialPriority: str = ... mixedContentType = ...
# referrerPolicy: str = ... initialPriority = ...
# isLinkPreload: bool = ... referrerPolicy = ...
# trustTokenParams: dict = ... isLinkPreload = ...
# isSameSite: bool = ... trustTokenParams = ...
isSameSite = ...
def __init__(self, raw_request: dict, post_data: str): def __init__(self, raw_request: dict, post_data: str):
self._request: dict = ... self._request: dict = ...
@ -122,9 +123,29 @@ class Request(object):
class Response(object): class Response(object):
status: str = ... url = ...
statusText: int = ... status = ...
mimeType: str = ... statusText = ...
headersText = ...
mimeType = ...
requestHeaders = ...
requestHeadersText = ...
connectionReused = ...
connectionId = ...
remoteIPAddress = ...
remotePort = ...
fromDiskCache = ...
fromServiceWorker = ...
fromPrefetchCache = ...
encodedDataLength = ...
timing = ...
serviceWorkerResponseSource = ...
responseTime = ...
cacheStorageCacheName = ...
protocol = ...
alternateProtocolUsage = ...
securityState = ...
securityDetails = ...
def __init__(self, raw_response: dict, raw_body: str, base64_body: bool): def __init__(self, raw_response: dict, raw_body: str, base64_body: bool):
self._response: dict = ... self._response: dict = ...
@ -136,5 +157,8 @@ class Response(object):
@property @property
def headers(self) -> CaseInsensitiveDict: ... def headers(self) -> CaseInsensitiveDict: ...
@property
def raw_body(self) -> str: ...
@property @property
def body(self) -> Union[str, dict, bool]: ... def body(self) -> Union[str, dict, bool]: ...

View File

@ -28,6 +28,8 @@ python 版本3.6 及以上
--- ---
# 🛠 如何使用
**📖 使用文档:** [点击查看](http://g1879.gitee.io/drissionpagedocs) **📖 使用文档:** [点击查看](http://g1879.gitee.io/drissionpagedocs)
**交流 QQ 群:** 897838127[已满]、558778073 **交流 QQ 群:** 897838127[已满]、558778073
@ -36,7 +38,7 @@ python 版本3.6 及以上
# 🔥 新版预告 # 🔥 新版预告
查看下一步开发计划:[新版预告](http://g1879.gitee.io/drissionpagedocs/whatsnew/3_3/) 查看下一步开发计划:[新版预告](https://g1879.gitee.io/drissionpagedocs/whatsnew/3_3/)
--- ---
@ -110,15 +112,9 @@ python 版本3.6 及以上
--- ---
# 🛠 使用文档
[点击跳转到使用文档](http://g1879.gitee.io/drissionpage)
---
# 🔖 版本历史 # 🔖 版本历史
[点击查看版本历史](http://g1879.gitee.io/drissionpagedocs/history/3.x/) [点击查看版本历史](https://g1879.gitee.io/drissionpagedocs/history/)
--- ---