用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

sergiojune發表於2019-02-16

僅用於技術交流,不作任何商業用途

前兩天教了大家如何在控制檯上找到真實的mp3播放地址,但是不可以下載付費的,因為只能下載可播放的歌曲。至於怎樣下載付費網易雲音樂,還是開個會員吧,要知道免費是最貴的的這個道理。

有粉絲看了前兩天文章想用程式碼來裝逼,我就為了滿足他,特意去折騰了兩天,終於寫出來了,迫不及待與大家分享一把。不得不說,這裡面坑很大,遇到幾個大坑在那裡折騰了幾個小時,分享出來讓大家想裝逼的少踩點坑。廢話不多說,開始今天主題!

1.尋找目標請求

開啟網易雲主頁 ,開啟開發者工具,點選搜尋

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

是不是看到很多請求,不要慌,慢慢找。找了之後你會發現下面這個連結

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

這個連結返回的是json,裡面包含的是歌曲的資訊,但是沒有MP3播放連結,這個或許有用,因為有歌曲的id,先放著。

我試著點選歌曲播放,又增加了幾個請求。一看,裡面就有我想要的MP3連結。

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

這樣子,獲取mp3請求的連結出來了,music.163.com/weapi/song/…

可以看到是個post請求,狀態碼為200,我們接著往下看fromdata是什麼資料。

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

是兩個加密了的引數,不過不怕,如果你看過我之前寫的利用python爬取網易雲音樂,並把資料存入mysql你會發現fromdata引數是一樣的,所以破解加密引數思路是一樣的,不過這次我不用fiddler了,只用開發者工具來除錯,看好了!!!我們看看這個請求的來源是什麼。

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

點進去看看,是個混淆的js,點左下角可以格式化,這樣好看點。

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

進行搜尋params,你會發現這個:

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

可以看到,加密的方式都沒有改變,還是和之前一樣,只是變數名字改變了。**window.asrsea()**有四個引數,先看看後面三個引數,因為都很相似。繼續進行搜尋定位。

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

可以看出,返回的是一個固定的內容,所以不用管了,等下可以進行除錯抓出來。再看看第一個引數。是一個json。我們可以進行斷點除錯進行獲取。

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

進行重新整理,你會看到下面這些內容。

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

可以看到**window.asrsea()**是一個d函式,定位過去看看,然後又給個斷點。

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

點選去往下一個斷點,你會看到

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

四個引數都出來了,我直接貼出來這裡吧:

d:"{"ids":"[523946593]","br":128000,"csrf_token":""}"e:"010001"f:"00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"g:"0CoJUm6Qyw8W8jud"
複製程式碼

引數都出來了,很容易就知道d引數裡面的ids對應的就是歌曲id,所以說剛才找的連結有用了。br是個固定值,對應的可能是歌曲的質量之類的,不需要管的。

下面再看看d函式是如何加密的:

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

裡面又包含了很多 **a , b ,c **的三個函式,先看看 a 函式

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

這個 a 函式是在一堆字串中隨機找出16個字串。ok,下一個。

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

b 函式採用了 aes 加密, 加密的密文是 e ,也就是引數的 a 內容,c是金鑰,第三個引數中有偏移量 d 和加密模式 **CBC **。再看看 c 函式。

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

c 函式是採用 rsa 加密,b 為加密指數, 空字串為解密引數,c 為加密係數。

好了,三個函式分析完畢,再回頭看看 d 函式。

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

可以看到params引數是經過兩次 b 函式生成的,也就是用 aes 加密兩次,encSecKey引數是通過 c 函式生成的,也就是通過 rsa 加密方式生成的。

廢話不多說,Talk is cheap, show me the code

2.程式碼部分

先把隨機生成16個字串的展示下

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

為了讓大家好看點,程式碼以後都用照片代替

接下來是aes加密的

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

這裡有一個巨坑,谷歌了也沒發現有誰遇到過,就是用python進行aes加密的時候,只能加密數字和字母,不能對中文進行加密,會報錯

Input strings must be a multiple of 16 in length

解決方方法是在cbc加密的模式下,在對字串補齊為長度為16的倍數時,長度指標不能用中文,要先把他轉為unicode編碼的長度才可以。比如上面的,下面的就是錯誤示範

pad = 16 - len(text) % 16

此坑爬過去了,接著下一個rsa加密

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

還有需要注意一下的是,在生成隨機16個字串的時候,需要保證params和encSecKey兩個引數是對應的這個隨機字串是一致的。要不然加密之後還是會出錯,獲取不了正確資訊。好了,最後一個是獲取兩個加密引數。

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

程式碼寫完了,那還等什麼,執行一下裝逼啊!

{'code': -460, 'msg': 'Cheating'}

這下好了,裝逼失敗,被網易雲認出來我是爬蟲的,那我試試加下請求頭?結果加了還是一個樣,這個也算是個巨坑吧。解決方法還是加請求頭,只需要加兩個,一個是瀏覽器識別 **user-agent **,另一個是 cookie ,想不到吧?我也想不到,居然還有在cookie上面做反爬的,但是我用了 **session **來保持cookie還是不行,需要自己複製瀏覽的cookie就行儲存才可以。

歌曲現在能下載了,可我要的是任意歌曲啊。那好,我們再去看看這個請求https://music.163.com/weapi/cloudsearch/get/web?csrf_token=,因為返回的是歌曲id。

3.尋找歌曲id

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

可以看到,引數還是和上面的那個請求的引數一樣,但是我們知道的是那個 d 函式,後三個引數是不變的,所以我們只需要找前面那個變化的引數就可以了,還是同樣的操作,斷點除錯

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

也是很容易就找到的,d 引數就是下面這個

d = '{"hlpretag":"<span class=\"s-fc7\">","hlposttag":"","s":"可能否","type":"1","offset":"0","total":"true","limit":"30","csrf_token":""}'

這個分析就可以說完畢了。

4.搜尋歌曲程式碼

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

這個是獲取歌曲 id 的程式碼,其他的沒什麼問題了。

最後

我還將程式打包了,遇到了喜歡的歌曲都可以下載下來,雖然可以直接用網易雲下載,不用那麼麻煩,但是我們學程式設計的是要幹什麼的?裝逼啊,能用程式碼絕不用其他的東西。

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)

效果圖如上,下載槓桿的,需要完整程式碼的可以後臺回覆音樂即可送給你。

ps:原創不易,寫了這篇文章可謂花費了我1024根頭髮,聽說轉發是生髮的最有效之道,所以你懂得!

用Python程式碼來下載任意指定網易雲歌曲(超詳細版)
掃面二維碼關注獲取更多有趣的python文章

相關文章