如何使用puppeteer转储WebSocket数据

sou*_*ine 13 websocket google-chrome-headless puppeteer

我想在此页面获取websocket数据https://upbit.com/exchange?code=CRIX.UPBIT.KRW-BTC,其websocket URL是动态的,仅在第一次连接时有效,第二次连接到它时将不再发送数据.

在此输入图像描述

所以我想知道也许无头镀铬可以帮助我监控websocket数据.

有任何想法吗?谢谢!

Tar*_*ani 20

你实际上不需要做任何复杂的事情.虽然URL似乎是动态的,但也可以通过代码正常工作.它不起作用的原因是你需要了解后台发生的事情.

首先让我们看看网络选项卡.

Websocket URL

Cookie和Origin可能对连接很重要.所以我们注意到这些.

现在让我们看一下socket上的数据交换

起始帧

中间框架

如果您查看初始帧接收的帧o作为数据,这可能表示打开连接.然后网站将一些数据发送到套接字,这可能与我们想要查询的内容有关.当连接暂停一段时间后,套接字将h作为数据接收.这可能表示持有或某事(如第二张图所示)

为了获得确切的数据,我们在代码中放置了一个断点

断点

然后在控制台中打印该值

发送的数据

现在我们有足够的信息来打击编码部分.我发现下面是一个很好的websocket库

https://github.com/websockets/ws

所以我们做了

yarn add ws || npm install ws --save
Run Code Online (Sandbox Code Playgroud)

现在我们编写代码

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)

    }
});
Run Code Online (Sandbox Code Playgroud)

并运行我们得到的代码

工作代码

现在,如果我更换

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",
})
Run Code Online (Sandbox Code Playgroud)

const ws = new WebSocket("wss://example.com/sockjs/299/enavklnl/websocket")
Run Code Online (Sandbox Code Playgroud)

这意味着什么cookies,origin从来就不需要.但我仍然建议你使用它们

  • 如果您只想使用puppeteer进行此操作,那么这可能不是您要找的答案 (2认同)
  • 惊人的答案,非常详尽和启发性的分析。我将在另一个问题/sf/ask/3385537431/下采用您的答案,对于这个问题,我仍然想知道如何通过Puppeteer或无头Chrome转储数据 (2认同)

zag*_*art 11

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)
})
Run Code Online (Sandbox Code Playgroud)

它是通过直接使用DevTools协议- https://chromedevtools.github.io/devtools-protocol/tot/Network#event-webSocketClosed

  • 看来目前唯一的方法就是拦截 websocket 连接请求并将其重定向到您自己的 websocket 服务器。也许这会有所帮助https://forum.katalon.com/t/intercepting-request-with-chrome-devtools-protocol/36081 (2认同)

bro*_*ess 6

我不认为操纵木偶有这种支持,但低级别的协议确实在这里:https://chromedevtools.github.io/devtools-protocol/tot/Network/#event-webSocketFrameSenthttps://开头chromedevtools。 github.io/devtools-protocol/tot/Network#type-WebSocketResponse。这意味着如果您愿意,您也可以在库中自己实现它。