<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                >文章背景: 公司最近在做現在很火的一個短視頻數據分析的項目,其中有一個功能需要快手直播間的數據,比如觀看直播間的人數,用戶彈幕數據,用戶的打賞信息。本來是有專門做python爬蟲的小哥,這個小哥是懵的,前端的事情還得前端來解決,沒辦法事情分配到我這里來了,一步步一分析的過程比較枯燥且乏味,不過別有一番樂趣,本文較長,將全程記錄此次難題的處理。 接到這個需求,我看了看快手直播間的代碼,webpack打包混淆后的js代碼就是一座屎山啊,那特么是給機器看的啊。 一開始我是拒絕的,畢竟壓縮加混淆的3W5千行代碼的文件就有好多個,看一眼就想打人,咋分析。 但是,作為一名孱弱無力的弱小前端,再苦再難也要堅強,畢竟要洽飯的嘛。 分析下此次目的: 1.騙過快手服務器,連接到快手直播間的websocket,讓它乖乖把消息推送到我們自己的服務器 2. 找到快手是采用何種方式對websocket傳輸的blob數據進行編碼與解碼 ## 先來看看快手的websocket ![](https://img.kancloud.cn/8b/00/8b00ccde7e8b7486246d958bd2190875_1711x790.png) 可以看到不停的閃爍,服務器再不停地往客戶端推消息 ## 首先找到對應需要分享的js文件 既然是分析websocket那我們首先得知道在那座屎山里游泳,打開快手直播間,F12查看源碼,搜索websocket關鍵字 ![](https://img.kancloud.cn/c9/e2/c9e29923324ca9619647429c5d642b52_752x912.png) 可以看到,有三個文件出現了websocket關鍵字。 1.app.js 2.common.js 3.vendor.js 從我們以往的經驗可以知道 app.js應該是主要的邏輯,vendor.js應該是一些依賴庫的打包,common.js不知道做什么的,但是從命名應該可以猜出是封裝了共用的庫。 然后websocket關鍵字出現最多地方就是common.js,通過本人的對每個文件的分析,果然如此common.js這個32623行混淆過的js就是我們要打的大boss。 ## 添加代理 將快手的js代理到本地來調試 這個時候我們打開這個common.js將壓縮后的代碼 展開 ![](https://img.kancloud.cn/15/2f/152fc545a0c6a9186af91896adac5329_771x782.png) 因為代碼3W多行代碼,我們發現無法編輯,除了打個斷點 好像什么都不能做,我們此刻要分析就迫切需要編輯調試這個代碼,所以這個時候我們需要用到一個利器charles > Charles其實是一款代理服務器,通過過將自己設置成系統(電腦或者瀏覽器)的網絡訪問代理服務器,然后截取請求和請求結果達到分析抓包的目的。 具體使用不再累述,檢索下到處都是教程。 安裝好charlses后 ,因為快手直播間采用的https協議,需要安裝下證書,如下圖 ![](https://img.kancloud.cn/12/aa/12aa807451bb17ed44462ef653ab3940_890x381.png) 點下就完事了,安裝好證書,可以設置下只監聽https的443端口 然后將快手的common.js下載到本地文件夾,在charsles中如下設置 ![](https://img.kancloud.cn/73/02/7302708e90933cb71efd0c24c34cd419_452x791.png) ![](https://img.kancloud.cn/11/98/119843e22db86b4443d63791a1515f1b_1191x498.png) 這個時候,我們刷新頁面,即可以在本地就可以隨意用vscode編輯調試線上的快手直播間的js啦。 ##猜測關鍵字找到關鍵的函數 這個時候通過一些猜測,比如從websocket關鍵字 一步一步往上推 是的 雖然混淆打包了,但是有很多的很多的關鍵字,需要耐著心去一步一步的看什么 t 函數 a函數 b函數,這期間的過程沒什么可寫的,但是這個過程是極其乏味與痛苦。 通過2天半的艱苦分析,總算將大致的關鍵字邏輯理順了,所有的socket消息發出去通過以下方法 ![](https://img.kancloud.cn/4e/39/4e39678cd87de9ad27fa5e4eaeeef009_628x399.png) 我們將他console出來看看,找到了對應的關鍵字 ![](https://img.kancloud.cn/a7/83/a7837bff85752a89c76f3c067b991a77_726x130.png) 這里對應說以下,通過之前的分析,我們大概梳理了快手直播間的websocket大致流程: 1.任何連接 任何端都可以連接,但是連接后必須要在50秒內發送第一個包以建立連接,不然服務器會主動斷開 2.每隔20秒發送一次心跳包 我們看到第一個包的數據如下: ``` . payload: . liveStreamId:"lG02idsTiKU" . pageId:"RFwi38MUiJQVqiUF\_1567150731045" 3token:"+bNZZ0V7XPjk5Eq7bHNxlGNPJUVkhBVKcmiE4cP+AkAxQaN5Fe17fqap9aCC9VNP97C3VboO2oIjjIgPOuI2qw==" . type:"CS\_ENTER\_ROOM" ``` 其中liveStreamId,pageId可以在頁面seesion中找到,token可以在頁面中找到。 嗯這里看起來好像就做完啦。但是我們拿到的這個數據是在3W5千行代碼中未經編碼前的數據, 快手在websocket中并不會以json的格式傳輸數據,而是采用二進制編碼后數據傳輸。 我們在調試中將其輸出編碼后的 ![](https://img.kancloud.cn/e5/d0/e5d0c05d5b30fb4e0c0a8d083538a4cd_740x119.png) 可以看到,被編碼成了arrayBuffer了,我們需要知道她如何編碼的,我們才能自由的將對應的數據編碼發送發哦快手的服務器,且之后收到了數據,也需要將對于的數據,還原成我們能看懂的json數據。 ## 解碼與編碼 事情到了這里 又卡住了 通過分析 ![](https://img.kancloud.cn/e4/20/e4203f849d4e8c707835bcda81a26b6e_547x388.png) 可以看到 調用了 _.encode _.decode 兩個方法,我們猜測 就是使用_這個對象的方法,但是我們將他輸出來,卻發現如下: ![](https://img.kancloud.cn/43/f8/43f89cf941a3f90b83062bde774d6fa4_353x342.png) ![](https://img.kancloud.cn/ef/c4/efc4aa12b34c82ad972981cc20eccf90_289x272.png) 這個時候又是懵的,壓根看不懂,為啥調用下這個方法就將對象編碼成arrayBuffer了啊 再上推也找不,感覺線索斷了(但是如果使用過谷歌protobuf 應該能從y.lookupType這個關鍵字得到啟發瞬間明白使用了什么,但是當時壓根沒用過,所以自然看到這個會很敏感,但當時我沒用過所以沒讓我敏感起來)。 接著繼續往上反推 推到了這個方法, ``` $Writer.create() ``` 這個方法我當時不知道什么意思,但是這個函數必然是某個框架的構造create方法,所以我們需要知道 $Writer是什么框架的方法,于是整個百度谷歌了個遍,找到一篇文章 > [Angular2+ 使用 Protocol Buffers 和 websocket]([https://www.jianshu.com/p/cdb12cbde506?utm\_campaign=studygolang.com&utm\_medium=studygolang.com&utm\_source=studygolang.com](https://www.jianshu.com/p/cdb12cbde506?utm_campaign=studygolang.com&utm_medium=studygolang.com&utm_source=studygolang.com)) 其中作者在文末,將**Protocol.js 文件源碼:**上傳上了,然后被檢索匹配到了,這個時候豁然開朗,原來就用的這個框架哦。 接著我們找到[protocol.js對應的github地址]([https://github.com/protobufjs/protobuf.js](https://github.com/protobufjs/protobuf.js)) 學習一邊昨用這個框架 這個時候我們知道他用了什么框架去編碼這個格式,所以我們在看看對應的代碼即可,然后在起打包的文件中找到 類似于文件的map 的對象,根據這個對象去寫對應的代碼,此處不再累述。 簡單建立鏈接的數據編碼過程如下: ![](https://img.kancloud.cn/e0/25/e0257225fec359ca02adb9016ac1a3b8_866x883.png) ## 最終結果 我們在node中直接起個websocket服務,并對應我們之前折騰了很久的編碼與解碼,直接連接快手服務端,讓它把消息數據乖乖推過來。 ![](https://img.kancloud.cn/24/1b/241b5b98ce6b058c3a734dda3a8e0172_1009x380.png) 解碼后用node寫入在data.json中數據: ![](https://img.kancloud.cn/78/3a/783a688c31d532fcc37ede00007b2bc6_877x877.png) 完美! ## 總結 限于文字的表現力,與自己的精力時間,不能把每一步都詳細的寫出來,實際做了大概3天,遇到的困難遠比穩重簡單的描述多 這次問題的總結的話就是: 1. 冷靜分析 2. 耐心,耐心
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看