Python爬蟲之JS逆向採集某易雲音樂網站
在獲取音樂的詳情資訊時,遇到請求引數全為加密的情況,現解解決方案整理如下:
JS逆向有兩種思路:
一種是整理出js檔案在Python中直接使用execjs呼叫js檔案(可見我的另一篇文章《 python爬蟲之企某科技JS逆向》)。
一種是根據JS中的邏輯,使用Python重寫相應的方法。(可見另一篇文章《爬蟲之JS逆向》)
本文介紹的也是第一種思路,即從目標網站中提取JS檔案,然後由Python中使用execjs呼叫,得到我們想要的資料。
需求:爬取音樂網站中的飆升榜資料https://music.163.com/#/discover/toplist
遇到的問題:在請求單條音樂詳情時遇到請求引數均是加密的情況。
第一步:獲取列表資料,此條沒什麼限制,跳過。
GET請求https://music.163.com/discover/toplist,即可獲取到頁面資訊,從頁面中提取資訊即可。
第二步:單條音樂播放時,網站傳送了請求,在請求回撥中返回了音樂檔案的地址。
切換到載荷頁籤,可以看到params和encSecKey兩個引數均是加密狀態的資料。
根據關鍵詞encSecKey來搜尋一下指令碼檔案。通過ctrl+f再次搜尋定位到這一行,params和encSecKey兩個引數最終的位置定位到了。
具體程式碼為:
var bKB3x = window.asrsea(JSON.stringify(i6c), buV0x(["流淚", "強"]), buV0x(Rg2x.md), buV0x(["愛心", "女孩", "驚恐", "大笑"])); e6c.data = j6d.cr7k({ params: bKB3x.encText, encSecKey: bKB3x.encSecKey })
也就是說我們需要的params和encSecKey是由window.asrsea方法生成,此方法有四個引數,多次除錯發現第一個引數與音樂屬性相關,後三個引數均為固定的字串。
在控制檯輸入window.asrsea敲擊回車,檢視方法定義,點選一下即可定位到指令碼中實際的位置。
根據方法中的相互引用關係,將JS指令碼中相應程式碼複製到一個JS檔案中。
然後根據最終返回的需要,我們再定義一個方法來實現。
function get_params() { let d1 = { "ids": "[1945262840]", "level": "standard", "encodeType": "aac", "csrf_token": "" }, d2 = buV0x(["流淚", "強"]), d3 = buV0x(Rg2x.md), d4 = buV0x(["愛心", "女孩", "驚恐", "大笑"]); let res = asrsea(JSON.stringify(d1), d2, d3, d4); return j6d.cr7k({ params: res.encText, encSecKey: res.encSecKey, }); }
此處定義的get_parmas中音樂ID寫死了的,這個後續可以改成動態的即可。
至此,這個音樂網站的JS逆向算是搞完了。下面來看一下效果。