如何在Puppeteer中使用代理捕获请求响应及WebSocket通信
解决Puppeteer配合代理捕获请求/响应及监控WebSocket的问题
我明白你作为新手碰到这种情况有多闹心——想用代理配合Puppeteer抓请求响应、监控WebSocket,但折腾了半天http-proxy各种变体都没成,确实容易卡壳。你的核心问题在于代理服务器没有实现实际的拦截逻辑,而且WebSocket需要单独处理HTTP升级流程,我给你整理了一套完整的可运行方案:
关键问题分析
你的原代码里runProxy函数是空的,没有配置代理的请求/响应捕获逻辑;另外WebSocket是通过HTTP协议升级实现的,http-proxy需要单独监听upgrade事件才能处理这类通信,这也是你之前没成功的核心原因之一。
完整解决方案代码
首先确保安装依赖:
npm install puppeteer http-proxy
然后用下面的代码替换你的原有脚本:
const puppeteer = require('puppeteer'); const httpProxy = require('http-proxy'); const url = require('url'); let proxyServer; const runProxy = async () => { return new Promise((resolve) => { // 创建代理服务器实例 proxyServer = httpProxy.createProxyServer({}); // 捕获所有HTTP请求 proxyServer.on('request', (req, res, proxyReq) => { console.log(`📤 [REQUEST] ${req.method} ${req.url}`); // 若需要捕获请求体,可在这里监听req的data事件拼接内容 // let body = ''; // req.on('data', chunk => body += chunk); // req.on('end', () => console.log('Request body:', body)); }); // 捕获所有HTTP响应 proxyServer.on('response', (req, res, proxyRes) => { console.log(`📥 [RESPONSE] ${req.url} | Status: ${proxyRes.statusCode}`); // 若需要捕获响应体,可在这里监听proxyRes的data事件拼接内容 // let body = ''; // proxyRes.on('data', chunk => body += chunk); // proxyRes.on('end', () => console.log('Response body:', body)); }); // 处理WebSocket连接升级请求 proxyServer.on('upgrade', (req, socket, head) => { console.log(`🔌 [WEBSOCKET] 连接升级: ${req.url}`); // 转发WebSocket请求到目标服务器 proxyServer.ws(req, socket, head); // 监听WebSocket传入消息 socket.on('data', (data) => { console.log(`🔵 [WEBSOCKET IN] ${data.toString()}`); }); // 监听WebSocket传出消息(可选) socket.on('write', (data) => { console.log(`🟡 [WEBSOCKET OUT] ${data.toString()}`); }); // 监听WebSocket连接关闭 socket.on('end', () => { console.log(`🔌 [WEBSOCKET] 连接关闭: ${req.url}`); }); }); // 启动代理服务器 const proxyPort = 8096; proxyServer.listen(proxyPort, () => { console.log(`✅ 代理服务器已启动: localhost:${proxyPort}`); resolve(); }); // 处理代理错误 proxyServer.on('error', (err, req, res) => { console.error(`❌ 代理错误: ${err.message}`); if (res) { res.writeHead(500); res.end(`Proxy Error: ${err.message}`); } }); }); }; const run = async () => { await runProxy(); const browser = await puppeteer.launch({ headless: false, args: [ '--start-fullscreen', '--proxy-server=localhost:8096', '--ignore-certificate-errors' // 忽略HTTPS证书错误,避免代理时的证书问题 ], ignoreHTTPSErrors: true // Puppeteer层面忽略HTTPS错误 }); const page = await browser.newPage(); await page.setViewport({ width: 1920, height: 1080 }); // 可选:也可以直接在Puppeteer页面内监听WebSocket事件 page.on('websocket', (ws) => { console.log(`📄 [页面WebSocket] 连接到: ${ws.url()}`); ws.on('message', (message) => { console.log(`📄 [页面WebSocket消息] ${message.text()}`); }); ws.on('close', () => { console.log(`📄 [页面WebSocket] 断开连接: ${ws.url()}`); }); }); await page.goto('http://www.google.com', { waitUntil: 'networkidle2', timeout: 120000 }); // 脚本结束后关闭资源(可选) // await browser.close(); // proxyServer.close(); }; // 执行脚本并捕获全局错误 run().catch((err) => { console.error('❌ 脚本执行错误:', err); if (proxyServer) proxyServer.close(); });
核心要点说明
- 代理逻辑完善:用Promise封装
runProxy,确保代理完全启动后再启动Puppeteer,避免连接失败。 - WebSocket处理:通过
upgrade事件捕获WebSocket升级请求,同时监听socket的data和write事件获取双向消息。 - HTTPS兼容:添加了证书忽略参数,避免访问HTTPS网站时的证书验证错误。
- 双维度监控:既可以通过代理全局捕获所有通信,也可以通过Puppeteer页面内的
websocket事件单独监控当前页面的WebSocket连接。
额外注意事项
- 如果目标网站有反爬机制,可能会检测代理,此时需要确保代理配置符合网站要求(比如添加代理认证参数
--proxy-auth=user:pass)。 - 若需要捕获请求/响应的完整内容,需要在对应的事件里监听
data事件拼接数据(代码中已给出注释示例)。
内容的提问来源于stack exchange,提问作者Captain_Meow_Meow
相关产品推荐
相关产品推荐

