首页 / DrissionPage 入门教程 / 监听网络数据

DrissionPage 入门教程

监听网络数据

本教程共 42 篇 · 第 29 篇 · 更新于 2026-07-29 · 约 8 分钟阅读

DrissionPageDrissionPage 入门教程网络监听listener数据包DataPacket

29. 监听网络数据

本节目标:学会用 listener 监听器捕获浏览器收发的数据包,掌握等待和实时两种获取方式,能根据 URL 特征过滤目标请求。

很多网页的数据不是直接嵌在 HTML 里的,而是通过 JS 动态加载。

比如翻页列表,点下一页时浏览器会悄悄发个请求,拿到 json 数据后再渲染到页面上。

如果你只从 DOM 去抓,可能遇到数据不全、加载来不及的问题。

DrissionPage 每个页面对象都内置了一个监听器,专门抓浏览器数据包。

它能帮你等待指定数据包到达,也能实时遍历所有经过的请求。

监听器的工作逻辑

监听器的使用有个关键顺序:先启动,再动作

listen.start() 这行代码之前产生的数据包,是抓不到的。

from DrissionPage import Chromium

tab = Chromium().latest_tab
tab.get('https://gitee.com/explore/all')  # 这行产生的数据包不会被监听

tab.listen.start('gitee.com/explore')  # 启动监听,只抓 URL 包含该文本的数据包
for _ in range(5):
    tab('@rel=next').click()  # 点击下一页
    res = tab.listen.wait()  # 等待并拿到一个数据包
    print(res.url)

输出:

https://gitee.com/explore/all?page=2
https://gitee.com/explore/all?page=3
https://gitee.com/explore/all?page=4
https://gitee.com/explore/all?page=5
https://gitee.com/explore/all?page=6

注意顺序

listen.start() 必须在触发动作之前调用。否则动作产生的数据已经跑掉了,监听器还没开始工作。

两种获取方式

监听器提供两种消费数据的方式:等待获取和实时获取。

等待获取:listen.wait()

wait() 会阻塞等待,直到有符合条件的数据包到达。

适合”触发一个动作,等一个响应”的场景,比如点击按钮后等接口返回。

from DrissionPage import Chromium

tab = Chromium().latest_tab
tab.listen.start('api/data')  # 启动监听
tab.get('https://example.com/list')

# 点击加载更多
tab('#load-more').click()

# 等待一个数据包
packet = tab.listen.wait()
if packet:
    print(packet.url)
    print(packet.response.body)  # 拿到响应体

wait() 支持设置超时和数量:

# 等 3 个数据包,最多等 10 秒
packets = tab.listen.wait(count=3, timeout=10)

实时获取:listen.steps()

steps() 返回一个迭代器,用 for 循环逐个拿到数据包。

适合需要持续监听、边听边处理的场景。

from DrissionPage import Chromium

tab = Chromium().latest_tab
tab.listen.start('gitee.com/explore')
tab.get('https://gitee.com/explore/all')

i = 0
for packet in tab.listen.steps():
    print(packet.url)
    tab('@rel=next').click()
    i += 1
    if i == 5:
        break

两种方式选哪个?

等一个响应用 wait(),持续监听用 steps()。本质上 wait() 是从队列里取,steps() 是迭代队列,数据都存着不会丢。

设置过滤规则

监听器默认不抓所有请求,你需要告诉它抓哪些。

按 URL 过滤

# 抓 URL 包含 'api' 的数据包
tab.listen.start('api')

# 抓多个特征
tab.listen.start(['api', 'data', 'json'])

使用正则

# 第二个参数开启正则匹配
tab.listen.start(r'api/\d+', is_regex=True)

按请求方法过滤

# 只抓 POST 请求
tab.listen.start('api', method='POST')

# 抓 GET 和 POST
tab.listen.start('api', method=['GET', 'POST'])

按资源类型过滤

# 只抓 XHR 类型的请求
tab.listen.start(res_type='XHR')

动态修改目标

监听过程中可以用 set_targets() 改规则,不用重启监听。

tab.listen.start('api/v1')
# 抓到几个后,改抓另一个接口
tab.listen.set_targets('api/v2')

控制监听器状态

tab.listen.start('api')  # 启动
tab.listen.pause()       # 暂停(不清队列)
tab.listen.resume()      # 恢复
tab.listen.stop()        # 终止(清空队列)

wait_silent() 可以等所有进行中的请求都结束:

tab.listen.wait_silent(timeout=5)

DataPacket 对象

每个数据包都是一个 DataPacket 对象,包含请求和响应的完整信息。

属性说明
url请求网址
method请求方法 GET/POST
resourceType资源类型 XHR/Document 等
request请求对象
response响应对象
is_failed是否失败

更多属性

DataPacket 还有 tab_idframeIdtargetfail_info 等属性,按需使用。

Request 对象

packet.request 包含请求的详细信息:

packet = tab.listen.wait()
print(packet.request.url)        # 请求 URL
print(packet.request.method)     # 请求方法
print(packet.request.headers)    # 请求头
print(packet.request.postData)   # POST 提交的数据
print(packet.request.cookies)    # 携带的 cookies

Response 对象

packet.response 包含响应内容:

print(packet.response.status)    # 状态码 200/404
print(packet.response.headers)   # 响应头
print(packet.response.body)      # 响应体(json 自动转 dict)
print(packet.response.raw_body)  # 原始文本

body 自动解析

response.body 会自动识别 json 并转成 dict,base64 转 bytes,其他返回文本。raw_body 始终是原始字符串。

等待附加信息

有些数据包的 extra_info 会晚于主体返回,需要额外等一下:

packet = tab.listen.wait()
packet.wait_extra_info(timeout=5)  # 等附加信息到位

小结

监听器是抓接口数据的利器,核心就三步:

  1. listen.start() 启动并设过滤规则
  2. 执行触发动作(点击、翻页等)
  3. wait()steps() 拿到数据包

记住先启动再动作,这个顺序搞反了就什么都抓不到。