如何使用puppeteer转储WebSocket数据

时间:2018-01-22 06:24:02

标签: websocket puppeteer google-chrome-headless

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

enter image description here

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

有什么想法吗?谢谢!

3 个答案:

答案 0 :(得分:19)

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

首先让我们看看网络标签。

Websocket URL

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

现在让我们看一下套接字上的数据交换

Starting frames

Middle frames

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

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

Breakpoint

然后在控制台中打印值

data sent

现在我们有足够的信息来打击编码部分。我在下面发现这是一个很好的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)

    }
});

运行我们得到的代码

Working code

现在如果我替换

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")

这意味着永远不需要cookiesorigin。但我仍然建议你使用它们

答案 1 :(得分:9)

  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

答案 2 :(得分:3)

我认为木偶操作者尚未支持此功能,但是较低级别的协议 https://chromedevtools.github.io/devtools-protocol/tot/Network/#event-webSocketFrameSenthttps://chromedevtools.github.io/devtools-protocol/tot/Network#type-WebSocketResponse。这意味着如果你也愿意,你可以自己在库中实现它。