惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 司徒正美
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
美团技术团队
WordPress大学
WordPress大学
罗磊的独立博客
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
爱范儿
爱范儿
MongoDB | Blog
MongoDB | Blog
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
H
Help Net Security
S
SegmentFault 最新的问题
C
Check Point Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
腾讯CDC
Engineering at Meta
Engineering at Meta
The GitHub Blog
The GitHub Blog
F
Fortinet All Blogs
D
DataBreaches.Net
雷峰网
雷峰网
GbyAI
GbyAI
宝玉的分享
宝玉的分享

晚花行乐

马克卡尼在2026年达沃斯论坛上的讲话(阅读材料) | 晚花行乐 鸡娃如何用力才是恰到好处 | 晚花行乐 读万卷书,行万里路的辩证关系 | 晚花行乐 反对培训机构掐尖招生 | 晚花行乐 小泽和建国会谈最后10分钟全文(阅读材料) | 晚花行乐 来看看 DeepSeek 怎么鸡娃 | 晚花行乐 谈谈基本功 | 晚花行乐 惠普 ProDesk SFF PC 各系列参数对比 | 晚花行乐 解决瘦客户机上安装 Debian 12 启动失败问题 | 晚花行乐 意拾喻言:老外写的文言文 | 晚花行乐 笠翁对韵中的典故(十三元) | 晚花行乐 谈谈中考取消四小门 | 晚花行乐 亚马逊云科技产品免费试用攻略(3) - 对象存储服务 | 晚花行乐 在 Windows 10 LTSC 版本上安装 WSL2 | 晚花行乐 Debian 12 的常用配置项 | 晚花行乐 在 Debian 12 上安装 Nvidia 显卡驱动程序 | 晚花行乐 解决 Debian 12 关机失败问题 | 晚花行乐 解决 VS Code 自动更新版本后卡在连接界面 | 晚花行乐 观看巴黎奥运会有感 | 晚花行乐 在 Windows10 上安装惠普旧打印机驱动程序 | 晚花行乐 欢迎关注公众号:晚花行乐 | 晚花行乐 如何编写拼写检查器 | 晚花行乐 亚马逊云科技产品免费试用攻略(2) - 云服务器 | 晚花行乐 Pandas 中 axis 参数的理解(附实例) | 晚花行乐 我打算命个名,叫什么什么 Manager | 晚花行乐 上海武康路历史建筑一览 | 晚花行乐 Python 实现简单的数学表达式解析并处理 | 晚花行乐 观看马拉松的感悟 | 晚花行乐 Python 保存 Cookies 到文件并再次读取 | 晚花行乐 如何为 Hugo 静态网站添加评论功能 | 晚花行乐
Puppeteer 获取 WebSocket 响应 | 晚花行乐
2019-05-15 · via 晚花行乐

正如 Puppeteer 获取 http 请求的响应 一文里提到的方法,除了获取 HTTP 响应以外,还能获取 WebSocket 响应。因为有些页面通过 WebSocket 实现异步传输,仅仅从HTTP通道上获取响应是不够的,如何使用 Puppeteer 得到 WebSocket 响应内容,本文讨论一种方法。

基本原理

截止目前,Puppeteer 没有提供原生的用于处理 WebSocket 的 API 接口。只能通过更底层的 Chrome DevTool Protocol (CDP) 协议获得。

Puppeteer 使用 CDPSession 对象处理 CDP 协议相关

获取 WebSocket 响应

下面这段代码可以将接收到的 WebSocket 响应打印在控制台上:

// 打开浏览器,打开新页面
browser = await puppeteer.launch()
page = await browser.newPage()

// 创建 CDP 对象
const client = await page.target().createCDPSession()

// 打开网络跟踪,允许网络事件通知到浏览器
await client.send('Network.enable')

// 订阅收到 WebSocket 的事件,响应包含在 params 参数中
client.on('Network.webSocketFrameReceived', 
    function(params){
        console.log(params.response.payloadData)
    }
})

// 开始浏览
await page.goto(url)

上面这段代码首先启用了网络跟踪 Network.enable ,再订阅了 Network.webSocketFrameReceived 事件,当有进来的 WebSocket 帧时会触发,注意:包括握手、心跳帧,都会触发该事件。

其他事件

下面这段代码,可以观察到 WebSocket 的各种事件:

browser = await puppeteer.launch()
page = await browser.newPage()
const client = await page.target().createCDPSession()
await client.send('Network.enable')

client.on('Network.webSocketCreated', 
    function(params){
        console.log(`创建 WebSocket 连接:${params.url}`)
    }
)
client.on('Network.webSocketClosed', 
    function(params){
       console.log(`WebSocket 连接关闭`) 
    }
)
client.on('Network.webSocketFrameSent', 
    function(params){
       console.log(`发送 WebSocket 消息:${params.response.payloadData}`)
    }
)
client.on('Network.webSocketFrameReceived', 
    function(params){
       console.log(`收到 WebSocket 消息:${params.response.payloadData}`)
    }
)
client.on('Network.webSocketWillSendHandshakeRequest', 
    function(params){
       console.log(`准备发送 WebSocket 握手消息`)
    }
)
client.on('Network.webSocketHandshakeResponseReceived', 
    function(params){
       console.log(`接收到 WebSocket 握手消息`)
    }
)
// 开始浏览
await page.goto(url)

Promise 化

外面包一层 Promise 后,可以方便的使用 await 得到响应结果,放在其他的同步语句中。具体来说,首先准备类似下面的函数:

function getWebSocketResponse(resolve, reject){
  client.on('Network.webSocketFrameReceived', (params)=>{
    resolve(params.response.payloadData)
  })
}

然后在测试用例里可以像下面这么写:

describe('获取ws响应', function() {
    it('检查 ws 响应中的值', async function(){
         //其他语句

         wsResponse = new Promise(getWebSocketResponse)
         await page.goto(url, {waitUntil: 'networkidle0'})
         response = await wsResponse 
         expect(response).to.equal(someValue)
     })
})

这样,测试用例就可以写的很简洁、易读。

(完)

各位读后有什么想法,请在下方留言吧!如果对本文有疑问或者寻求合作,欢迎 联系邮箱邮箱已到剪贴板

精彩评论