From 912f69269af11776899ccb4d89f542d75a8d8196 Mon Sep 17 00:00:00 2001 From: g1879 Date: Tue, 17 May 2022 13:04:23 +0800 Subject: [PATCH] =?UTF-8?q?2.6.1=EF=BC=8Csteps()=E5=8F=AF=E5=AE=9E?= =?UTF-8?q?=E6=97=B6=E8=BF=94=E5=9B=9E=E7=9B=91=E5=90=AC=E5=88=B0=E7=9A=84?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=8C=85=EF=BC=9Btargets=E8=AE=BE=E4=B8=BATr?= =?UTF-8?q?ue=E7=9B=91=E5=90=AC=E6=89=80=E6=9C=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DrissionPage/tools.py | 68 ++++++++++++++++++----------- docs/_sidebar.md | 58 ++++++++++++------------ docs/使用方法/监听浏览器网络数据.md | 11 +++++ setup.py | 2 +- 4 files changed, 85 insertions(+), 54 deletions(-) create mode 100644 docs/使用方法/监听浏览器网络数据.md diff --git a/DrissionPage/tools.py b/DrissionPage/tools.py index 6731109..482044b 100644 --- a/DrissionPage/tools.py +++ b/DrissionPage/tools.py @@ -58,14 +58,15 @@ class Listener(object): self.set_tab(tab_handle) self.listening = False - self.targets = None + self.targets = True self.results = {} self._response_count = 0 self._requestIds = {} self._a_response_loaded = False + self._all_response = [] # 捕捉到的所有数据格式[(target, ResponseData), ...] - def set_targets(self, targets: Union[str, List[str], Tuple[str]]) -> None: + def set_targets(self, targets: Union[str, List[str], Tuple[str], bool, None]) -> None: """设置要拦截的目标,可以设置多个 \n :param targets: 字符串或字符串组成的列表 :return: None @@ -74,6 +75,10 @@ class Listener(object): self.targets = [targets] elif isinstance(targets, tuple): self.targets = list(targets) + elif isinstance(targets, list) or targets is True: + self.targets = targets + else: + raise TypeError('targets参数只接收字符串、字符串组成的列表、True、None') def set_tab(self, tab_handle: str) -> None: """设置要监听的标签页 \n @@ -83,8 +88,10 @@ class Listener(object): url = self.page.drission.driver_options.debugger_address if not url: raise RuntimeError('必须设置debugger_address参数才能使用此功能。') + if tab_handle is None: tab_handle = self.page.current_tab_handle + tab_id = tab_handle.split('-')[-1] tab_data = {"id": tab_id, "type": "page", @@ -92,18 +99,20 @@ class Listener(object): self.tab = Tab(**tab_data) - def listen(self, targets: Union[str, List[str], Tuple[str]] = None, + def listen(self, targets: Union[str, List[str], Tuple[str], bool, None] = None, count: int = None, timeout: float = None, asyn: bool = False) -> None: - """拦截目标请求,直到超时或达到拦截个数,每次拦截前清空结果 \n - :param targets: 要监听的目标字符串,可输入多个,请求url包含这些字符串就会被记录 + """拦截目标请求,直到超时或达到拦截个数,每次拦截前清空结果 \n + 可监听多个目标,请求url包含这些字符串就会被记录 \n + :param targets: 要监听的目标字符串或其组成的列表,True监听所有,None则保留之前的目标不变 :param count: 要记录的个数,到达个数停止监听 :param timeout: 监听最长时间,到时间即使未达到记录个数也停止,None为无限长 :param asyn: 是否异步执行 :return: None """ - self.set_targets(targets) + if targets: + self.set_targets(targets) self.tab.Network.responseReceived = self._response_received self.tab.Network.loadingFinished = self._loading_finished @@ -150,24 +159,9 @@ class Listener(object): break sleep(.5) - self.listening = False self.tab.Network.responseReceived = self._null_function self.tab.Network.loadingFinished = self._null_function - - def _loading_finished(self, **kwargs): - """请求完成时处理方法""" - requestId = kwargs['requestId'] - target = self._requestIds.pop(requestId, None) - if target is not None: - response = ResponseData(target['response'], self._get_response_body(requestId)) - target = target['target'] - if target in self.results: - self.results[target].append(response) - else: - self.results[target] = [response] - self._response_count += 1 - - self._a_response_loaded = True + self.listening = False def steps(self, gap: int = 1) -> Iterable: """用于单步操作,可实现没收到若干个数据包执行一步操作(如翻页) \n @@ -187,13 +181,35 @@ class Listener(object): self._a_response_loaded = False count += 1 if count % gap == 0: - yield + yield self._all_response[-gap:] + + def _loading_finished(self, **kwargs): + """请求完成时处理方法""" + requestId = kwargs['requestId'] + target = self._requestIds.pop(requestId, None) + + if target is not None: + response = ResponseData(target['response'], self._get_response_body(requestId)) + target = target['target'] + self._response_count += 1 + + if target in self.results: + self.results[target].append(response) + else: + self.results[target] = [response] + + self._all_response.append((target, response)) + self._a_response_loaded = True def _response_received(self, **kwargs) -> None: """接收到返回信息时处理方法""" - for target in self.targets: - if target in kwargs['response']['url']: - self._requestIds[kwargs['requestId']] = {'target': target, 'response': kwargs['response']} + if self.targets is True: + self._requestIds[kwargs['requestId']] = {'target': True, 'response': kwargs['response']} + + else: + for target in self.targets: + if target in kwargs['response']['url']: + self._requestIds[kwargs['requestId']] = {'target': target, 'response': kwargs['response']} def _null_function(self, **kwargs) -> None: """空方法,用于清除绑定的方法""" diff --git a/docs/_sidebar.md b/docs/_sidebar.md index d71f6d6..81fc1e8 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -1,30 +1,32 @@ * [⭐️ 简介](README.md) * [🧭 入门指南](#) - * [🔥 基本概念](入门指南\基本概念.md) - * [👍 快速上手](入门指南\快速上手.md) - * [🍀 特性演示](#) - * [🌿 与 requests 对比](入门指南\特性演示\与requests代码对比.md) - * [🌿 与 selenium 对比](入门指南\特性演示\与selenium代码对比.md) - * [🌿 模式切换](入门指南\特性演示\模式切换.md) - * [🌿 获取并打印元素属性](入门指南\特性演示\获取并打印元素属性.md) - * [🌿 下载文件](入门指南\特性演示\下载文件.md) + + * [🔥 基本概念](入门指南\基本概念.md) + * [👍 快速上手](入门指南\快速上手.md) + * [🍀 特性演示](#) + * [🌿 与 requests 对比](入门指南\特性演示\与requests代码对比.md) + * [🌿 与 selenium 对比](入门指南\特性演示\与selenium代码对比.md) + * [🌿 模式切换](入门指南\特性演示\模式切换.md) + * [🌿 获取并打印元素属性](入门指南\特性演示\获取并打印元素属性.md) + * [🌿 下载文件](入门指南\特性演示\下载文件.md) * [🛠 使用方法](#) - * [🔨 创建页面对象](使用方法\创建页面对象.md) - * [🔨 访问网页](使用方法\访问网页.md) - * [🔨 查找页面元素](使用方法\查找页面元素.md) - * [🔨 获取元素信息](使用方法\获取元素信息.md) - * [🔨 元素操作](使用方法\元素操作.md) - * [🔨 获取网页信息](使用方法\获取网页信息.md) - * [🔨 页面操作](使用方法\页面操作.md) - * [🔨 启动配置](#) - * [🔧 概述](使用方法\启动配置\概述.md) - * [🔧 Chrome 启动配置](使用方法\启动配置\Chrome启动配置.md) - * [🔧 Session 启动配置](使用方法\启动配置\Session启动配置.md) - * [🔧 使用配置文件](使用方法\启动配置\使用配置文件.md) + + * [🔨 创建页面对象](使用方法\创建页面对象.md) + * [🔨 访问网页](使用方法\访问网页.md) + * [🔨 查找页面元素](使用方法\查找页面元素.md) + * [🔨 获取元素信息](使用方法\获取元素信息.md) + * [🔨 元素操作](使用方法\元素操作.md) + * [🔨 获取网页信息](使用方法\获取网页信息.md) + * [🔨 页面操作](使用方法\页面操作.md) + * [🔨 启动配置](#) + * [🔧 概述](使用方法\启动配置\概述.md) + * [🔧 Chrome 启动配置](使用方法\启动配置\Chrome启动配置.md) + * [🔧 Session 启动配置](使用方法\启动配置\Session启动配置.md) + * [🔧 使用配置文件](使用方法\启动配置\使用配置文件.md) * [🔨 下载文件](使用方法\下载文件.md) - * [🔨 监听浏览器网络数据包](使用方法\监听浏览器网络数据包.md) + * [🔨 监听浏览器网络数据](使用方法\监听浏览器网络数据.md) * [🔨 cookies 的使用](使用方法\cookies的使用.md) * [🔨 Drission 对象](使用方法\Drission对象.md) * [🔨 对接 selenium 及 requests 代码](使用方法\对接selenium及requests代码.md) @@ -33,12 +35,14 @@ * [🔨 打包程序](使用方法\打包程序.md) * [💖 实用示例](#) - * [🧡 自动登录码云](实用示例\自动登录码云.md) - * [🧡 获取各国疫情排名](实用示例\获取各国疫情排名.md) - * [🧡 下载星巴克产品图片](实用示例\下载星巴克产品图片.md) - * [🧡 同时操作多个浏览器](实用示例\同时操作多个浏览器.md) + + * [🧡 自动登录码云](实用示例\自动登录码云.md) + * [🧡 获取各国疫情排名](实用示例\获取各国疫情排名.md) + * [🧡 下载星巴克产品图片](实用示例\下载星巴克产品图片.md) + * [🧡 同时操作多个浏览器](实用示例\同时操作多个浏览器.md) * [⚡️ Tips大集合](Tips大集合.md) -* [🎯️ 版本历史](版本历史.md) -* [💐 鸣谢](鸣谢.md) +* [🎯️ 版本历史](版本历史.md) + +* [💐 鸣谢](鸣谢.md) diff --git a/docs/使用方法/监听浏览器网络数据.md b/docs/使用方法/监听浏览器网络数据.md new file mode 100644 index 0000000..f802c9e --- /dev/null +++ b/docs/使用方法/监听浏览器网络数据.md @@ -0,0 +1,11 @@ +# 施工中。。。 + + + +# 监听浏览器网络数据 + +许多网页的数据来自接口,在网站使用过程中动态加载,如使用 JS 加载内容的翻页列表。 + +这些数据通常以 json 形式发送,浏览器接收后,对其进行解析,再加载到 DOM 相应位置。 + +以前,我们从 DOM 中去获取解析后数据的,可能存在 diff --git a/setup.py b/setup.py index 2888818..9afac5e 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ with open("README.md", "r", encoding='utf-8') as fh: setup( name="DrissionPage", - version="2.6.0", + version="2.6.1", author="g1879", author_email="g1879@qq.com", description="A module that integrates selenium and requests session, encapsulates common page operations.",