1

我想从网站上抓取实时数据,我决定使用 webSocket - 锋利的库。我的问题是,使用相同的代码,我可以解析来自特定网站的数据,而不能从另一个网站解析数据。

程序抛出此异常:WebSocket.connect:0|WebSocketSharp.WebSocketException: Not a WebSocket 握手响应。

using (var wss = new WebSocket("wss://..."))
{
    wss.SslConfiguration.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12;
    wss.Origin = "https://www.blabla.com";
           
    wss.CustomHeaders = new Dictionary<string, string>
    {
        { "Accept-Encoding", "gzip, deflate, br" },
        { "Accept-Language", "el-GR,el;q=0.9,en;q=0.8" },
        { "Cache-Control", "no-cache" },
        { "Connection", "Upgrade" },
        { "Host", "blabla.com" },
        { "Origin", "https://www.bla.com" },
        { "Pragma", "no-cache" },
        //{ "Sec-WebSocket-Key", secWebSocketKey },
        //{ "Sec-WebSocket-Protocol", "zap-protocol-v1" },
        { "Sec-WebSocket-Extensions", "permessage-deflate; client_max_window_bits" },
        { "Sec-WebSocket-Version", "13" },
        { "Upgrade", "websocket" },
        { "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36" }
     };

     //wss.OnOpen += Ws_OnOpen;
     wss.OnMessage += (sender, e) => Console.WriteLine($"Server: {e.Data}");
     wss.OnError += (sender, e) => Console.WriteLine($"Error: {e.Message}");

     wss.Connect();

     Console.ReadKey();
 }

我尝试使用或不使用自定义标题。

我该怎么做才能进行有效的握手?

(PS:我可以解析没有来自第一个网站的自定义标题的数据)

更新

在 URL 中有一个 uid 参数 wss://blabla.com/zap/? uid=5829062969032768

每次刷新网页时,此 uid 都会发生变化。我认为握手是必要的。有没有办法重现它?

4

1 回答 1

1

每次页面加载时,此 uid 都会更改。我发现这个网站使用了代码混淆,所以我很难理解 js 代码,所以我使用了 selenium 4 devtools,最后抓取了实时数据。

首先要初始化chrome devtools

public async static Task<DevToolsSession> InitializeChromeDevTools(IWebDriver driver)
{
    var devTools = driver as IDevTools;
    var output = devTools.CreateDevToolsSession();
    await output.Network.Enable(new OpenQA.Selenium.DevTools.Network.EnableCommandSettings());

    return output;
}

接着

var session = await ChromeDriverSettings.InitializeChromeDevTools(driver);
session.Network.WebSocketFrameReceived += Network_WebSocketFrameReceived; 

private static void Network_WebSocketFrameReceived(object sender, OpenQA.Selenium.DevTools.Network.WebSocketFrameReceivedEventArgs e)
{
    var message = e.Response.PayloadData;
}
于 2020-10-13T15:42:29.367 回答