如何使用 puppeteer 转储 WebSocket 数据
How to use puppeteer to dump WebSocket data
我想获取这个页面的websocket数据https://upbit.com/exchange?code=CRIX.UPBIT.KRW-BTC,它的websocketURL是动态的,只在第一次连接时有效,第二次连接就不会再发送数据了.
所以我想知道也许 headless chrome 可以帮助我监控 websocket 数据。
有什么想法吗?谢谢!
我认为 puppeteer 尚不支持此功能,但较低级别的协议 支持 此处:https://chromedevtools.github.io/devtools-protocol/tot/Network/#event-webSocketFrameSent and https://chromedevtools.github.io/devtools-protocol/tot/Network#type-WebSocketResponse。这意味着如果您愿意,也可以自己在库中实现它。
您实际上不需要为此做任何复杂的事情。 URL 虽然看起来是动态的,但通过代码也能正常工作。它不起作用的原因是您需要了解后台发生的事情。
首先让我们看看“网络”选项卡。
cookie 和 Origin 可能对连接很重要。所以我们把这些记下来。
现在让我们看看套接字上的数据交换
如果您查看初始帧接收 o
作为数据的帧,这可能表示正在打开连接。然后网站向socket发送一些数据,这可能与我们要查询的内容有关。当连接暂停一段时间后,套接字接收 h
作为数据。这可能表示暂停或其他内容(如第二张图片所示)
为了获得准确的数据,我们在代码中放置了一个断点
然后在控制台打印值
现在我们有足够的信息可以进入编码部分了。我发现下面是一个很好的 websocket 库
https://github.com/websockets/ws
所以我们做一个
yarn add ws || npm install ws --save
现在我们写代码
const WebSocket = require("ws")
const ws = new WebSocket("wss://example.com/sockjs/299/enavklnl/websocket",null,{
headers: {
"Cookie":"<cookie data noted earlier>",
"User-Agent": "<Your browser agent>"
},
origin: "https://example.com",
})
const opening_message = '["[{\"ticket\":\"ram macbook\"},{\"type\":\"recentCrix\",\"codes\":[\"CRIX.UPBIT.KRW-BTC\",\"CRIX.BITFINEX.USD-BTC\",\"CRIX.BITFLYER.JPY-BTC\",\"CRIX.OKCOIN.CNY-BTC\",\"CRIX.KRAKEN.EUR-BTC\",\"CRIX.UPBIT.KRW-DASH\",\"CRIX.UPBIT.KRW-ETH\",\"CRIX.UPBIT.KRW-NEO\",\"CRIX.UPBIT.KRW-BCC\",\"CRIX.UPBIT.KRW-MTL\",\"CRIX.UPBIT.KRW-LTC\",\"CRIX.UPBIT.KRW-STRAT\",\"CRIX.UPBIT.KRW-XRP\",\"CRIX.UPBIT.KRW-ETC\",\"CRIX.UPBIT.KRW-OMG\",\"CRIX.UPBIT.KRW-SNT\",\"CRIX.UPBIT.KRW-WAVES\",\"CRIX.UPBIT.KRW-PIVX\",\"CRIX.UPBIT.KRW-XEM\",\"CRIX.UPBIT.KRW-ZEC\",\"CRIX.UPBIT.KRW-XMR\",\"CRIX.UPBIT.KRW-QTUM\",\"CRIX.UPBIT.KRW-LSK\",\"CRIX.UPBIT.KRW-STEEM\",\"CRIX.UPBIT.KRW-XLM\",\"CRIX.UPBIT.KRW-ARDR\",\"CRIX.UPBIT.KRW-KMD\",\"CRIX.UPBIT.KRW-ARK\",\"CRIX.UPBIT.KRW-STORJ\",\"CRIX.UPBIT.KRW-GRS\",\"CRIX.UPBIT.KRW-VTC\",\"CRIX.UPBIT.KRW-REP\",\"CRIX.UPBIT.KRW-EMC2\",\"CRIX.UPBIT.KRW-ADA\",\"CRIX.UPBIT.KRW-SBD\",\"CRIX.UPBIT.KRW-TIX\",\"CRIX.UPBIT.KRW-POWR\",\"CRIX.UPBIT.KRW-MER\",\"CRIX.UPBIT.KRW-BTG\",\"CRIX.COINMARKETCAP.KRW-USDT\"]},{\"type\":\"crixTrade\",\"codes\":[\"CRIX.UPBIT.KRW-BTC\"]},{\"type\":\"crixOrderbook\",\"codes\":[\"CRIX.UPBIT.KRW-BTC\"]}]"]'
ws.on('open', function open() {
console.log("opened");
});
ws.on('message', function incoming(data) {
if (data == "o" || data == "h") {
console.log("sending opening message")
ws.send(opening_message)
}
else {
console.log("Received", data)
}
});
和运行我们得到的代码
现在如果我替换
const ws = new WebSocket("wss://example.com/sockjs/299/enavklnl/websocket",null,{
headers: {
"Cookie":"<cookie data noted earlier>",
"User-Agent": "<Your browser agent>"
},
origin: "https://example.com",
})
至
const ws = new WebSocket("wss://example.com/sockjs/299/enavklnl/websocket")
这意味着从来不需要 cookies
和 origin
。但我仍然建议您使用它们
const client = page._client
client.on('Network.webSocketCreated', ({requestId, url}) => {
console.log('Network.webSocketCreated', requestId, url)
})
client.on('Network.webSocketClosed', ({requestId, timestamp}) => {
console.log('Network.webSocketClosed', requestId, timestamp)
})
client.on('Network.webSocketFrameSent', ({requestId, timestamp, response}) => {
console.log('Network.webSocketFrameSent', requestId, timestamp, response.payloadData)
})
client.on('Network.webSocketFrameReceived', ({requestId, timestamp, response}) => {
console.log('Network.webSocketFrameReceived', requestId, timestamp, response.payloadData)
})
直接使用 DevTools 协议 - https://chromedevtools.github.io/devtools-protocol/tot/Network#event-webSocketClosed
我想获取这个页面的websocket数据https://upbit.com/exchange?code=CRIX.UPBIT.KRW-BTC,它的websocketURL是动态的,只在第一次连接时有效,第二次连接就不会再发送数据了.
所以我想知道也许 headless chrome 可以帮助我监控 websocket 数据。
有什么想法吗?谢谢!
我认为 puppeteer 尚不支持此功能,但较低级别的协议 支持 此处:https://chromedevtools.github.io/devtools-protocol/tot/Network/#event-webSocketFrameSent and https://chromedevtools.github.io/devtools-protocol/tot/Network#type-WebSocketResponse。这意味着如果您愿意,也可以自己在库中实现它。
您实际上不需要为此做任何复杂的事情。 URL 虽然看起来是动态的,但通过代码也能正常工作。它不起作用的原因是您需要了解后台发生的事情。
首先让我们看看“网络”选项卡。
cookie 和 Origin 可能对连接很重要。所以我们把这些记下来。
现在让我们看看套接字上的数据交换
如果您查看初始帧接收 o
作为数据的帧,这可能表示正在打开连接。然后网站向socket发送一些数据,这可能与我们要查询的内容有关。当连接暂停一段时间后,套接字接收 h
作为数据。这可能表示暂停或其他内容(如第二张图片所示)
为了获得准确的数据,我们在代码中放置了一个断点
然后在控制台打印值
现在我们有足够的信息可以进入编码部分了。我发现下面是一个很好的 websocket 库
https://github.com/websockets/ws
所以我们做一个
yarn add ws || npm install ws --save
现在我们写代码
const WebSocket = require("ws")
const ws = new WebSocket("wss://example.com/sockjs/299/enavklnl/websocket",null,{
headers: {
"Cookie":"<cookie data noted earlier>",
"User-Agent": "<Your browser agent>"
},
origin: "https://example.com",
})
const opening_message = '["[{\"ticket\":\"ram macbook\"},{\"type\":\"recentCrix\",\"codes\":[\"CRIX.UPBIT.KRW-BTC\",\"CRIX.BITFINEX.USD-BTC\",\"CRIX.BITFLYER.JPY-BTC\",\"CRIX.OKCOIN.CNY-BTC\",\"CRIX.KRAKEN.EUR-BTC\",\"CRIX.UPBIT.KRW-DASH\",\"CRIX.UPBIT.KRW-ETH\",\"CRIX.UPBIT.KRW-NEO\",\"CRIX.UPBIT.KRW-BCC\",\"CRIX.UPBIT.KRW-MTL\",\"CRIX.UPBIT.KRW-LTC\",\"CRIX.UPBIT.KRW-STRAT\",\"CRIX.UPBIT.KRW-XRP\",\"CRIX.UPBIT.KRW-ETC\",\"CRIX.UPBIT.KRW-OMG\",\"CRIX.UPBIT.KRW-SNT\",\"CRIX.UPBIT.KRW-WAVES\",\"CRIX.UPBIT.KRW-PIVX\",\"CRIX.UPBIT.KRW-XEM\",\"CRIX.UPBIT.KRW-ZEC\",\"CRIX.UPBIT.KRW-XMR\",\"CRIX.UPBIT.KRW-QTUM\",\"CRIX.UPBIT.KRW-LSK\",\"CRIX.UPBIT.KRW-STEEM\",\"CRIX.UPBIT.KRW-XLM\",\"CRIX.UPBIT.KRW-ARDR\",\"CRIX.UPBIT.KRW-KMD\",\"CRIX.UPBIT.KRW-ARK\",\"CRIX.UPBIT.KRW-STORJ\",\"CRIX.UPBIT.KRW-GRS\",\"CRIX.UPBIT.KRW-VTC\",\"CRIX.UPBIT.KRW-REP\",\"CRIX.UPBIT.KRW-EMC2\",\"CRIX.UPBIT.KRW-ADA\",\"CRIX.UPBIT.KRW-SBD\",\"CRIX.UPBIT.KRW-TIX\",\"CRIX.UPBIT.KRW-POWR\",\"CRIX.UPBIT.KRW-MER\",\"CRIX.UPBIT.KRW-BTG\",\"CRIX.COINMARKETCAP.KRW-USDT\"]},{\"type\":\"crixTrade\",\"codes\":[\"CRIX.UPBIT.KRW-BTC\"]},{\"type\":\"crixOrderbook\",\"codes\":[\"CRIX.UPBIT.KRW-BTC\"]}]"]'
ws.on('open', function open() {
console.log("opened");
});
ws.on('message', function incoming(data) {
if (data == "o" || data == "h") {
console.log("sending opening message")
ws.send(opening_message)
}
else {
console.log("Received", data)
}
});
和运行我们得到的代码
现在如果我替换
const ws = new WebSocket("wss://example.com/sockjs/299/enavklnl/websocket",null,{
headers: {
"Cookie":"<cookie data noted earlier>",
"User-Agent": "<Your browser agent>"
},
origin: "https://example.com",
})
至
const ws = new WebSocket("wss://example.com/sockjs/299/enavklnl/websocket")
这意味着从来不需要 cookies
和 origin
。但我仍然建议您使用它们
const client = page._client
client.on('Network.webSocketCreated', ({requestId, url}) => {
console.log('Network.webSocketCreated', requestId, url)
})
client.on('Network.webSocketClosed', ({requestId, timestamp}) => {
console.log('Network.webSocketClosed', requestId, timestamp)
})
client.on('Network.webSocketFrameSent', ({requestId, timestamp, response}) => {
console.log('Network.webSocketFrameSent', requestId, timestamp, response.payloadData)
})
client.on('Network.webSocketFrameReceived', ({requestId, timestamp, response}) => {
console.log('Network.webSocketFrameReceived', requestId, timestamp, response.payloadData)
})
直接使用 DevTools 协议 - https://chromedevtools.github.io/devtools-protocol/tot/Network#event-webSocketClosed