Python爬蟲之js加密破解,抓取網易雲音樂評論生成詞雲
js破解歷程
- 前言
- 技能點
- 介面概況
- 靜態網頁動態網頁
- 頁面解析
- step1: 找引數step2:分析js函式step3:分析引數step4: 校驗step5:轉為python程式碼
- 編寫爬蟲
很多人學習python,不知道從何學起。
很多人學習python,掌握了基本語法過後,不知道在哪裡尋找案例上手。
很多已經做案例的人,卻不知道如何去學習更加高深的知識。
那麼針對這三類人,我給大家提供一個好的學習平臺,免費領取視訊教程,電子書籍,以及課程的原始碼!??¤
QQ群:623406465
前言
網路爬蟲的大障礙,就是各種加密。這其中包過登入的驗證碼以及加密。js混淆、js引數加密等等。其實以前也就瞭解過js加密。但是沒有深入研究,藉著這次實踐研究了一下網易雲音樂的加密方式。
博主通過網易雲音樂評論加密的例項來做個學習過程的分析和分享。
如果有問題或者不懂的地方可以關注我的微信公眾號(bigsai),聯絡我。
技能點
- 前端:js知識(比較重要)、谷歌瀏覽器debug、抓包、打斷點除錯能力(必須)。以及js各種加密函式(瞭解).
- python:基礎的請求requests。Crypto.Cipher加密解密模組。
- 其他:postman(模擬請求使用),良好的思維能力和分析能力。(加密演算法有些亂),還有一點就是js加密轉python的程式碼實現。
介面概況
靜態網頁
對於一般的url隨著頁面的變化而變化的頁面,網易雲還是有的,你只需要抓取網頁進行分析即可。
動態網頁
但隨著前後端分離的流行,以及資料分離好處明顯。越來越多的資料採用ajax渲染。而網易雲的評論即使如此。
在前後端分離剛火,那時很多網站對藉口並沒有太大的防護措施。就使得很多網站輕鬆獲取結果。至今也有很多這樣的藉口存在,這種網站爬去就是傻瓜式爬取。
然而隨著前段技術的發展,介面也變的越來越棘手。就拿網易雲的評論來說:它的引數就讓人很懵逼。
這一串串數字到底是啥。很多人見到這樣的資料就會選擇放棄。那麼讓我為你解開它什麼的面紗。
頁面解析
step1: 找引數
你可以看的到,它的引數有兩個,一個是params,一個是encSecKey並且都是經過加密的,我們就要分析它的源頭。F12開啟source搜尋encSckey.
'在查詢這個js內部的encSecKey,發現原來在這裡,經過斷點除錯發現這裡就是最終引數的結果。
step2:分析js函式
這個js有4w多行,如何能在4w多行js中找到有用的資訊,然後理清楚這裡的思路呢?
這就需要你的抽象和逆向思維了。來,我們麼開始分析。
var bYc7V = window.asrsea(JSON.stringify(i3x), bkY2x(["流淚", "強"]), bkY2x(VM8E.md), bkY2x(["愛心", "女孩", "驚恐", "大笑"]));
e3x.data = k4o.cz4D({
params: bYc7V.encText,
encSecKey: bYc7V.encSecKey
})
上面這段程式碼中就是來源,我們先不管這個JSON.stringify(i3x)這些引數是啥,先搞清楚window.asrsea是什麼。在上面不遠處你會發現:
這個就是d函式才是所有資料,方法的根源,d、e、f、g四個引數就是我們剛剛說的不要管的引數。
從這個函式就是分析:encText是經過兩次b()函式,encSecKey是經過c()函式,執行的一個引數。注意其中i引數來源是a(16).網上看看這些函式。
function a(a) {
var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";
for (d = 0; a > d; d = 1)
e = Math.random() * b.length,
e = Math.floor(e),
c = b.charAt(e);
return c
}
function b(a, b) {
var c = CryptoJS.enc.Utf8.parse(b)
, d = CryptoJS.enc.Utf8.parse("0102030405060708")
, e = CryptoJS.enc.Utf8.parse(a)
, f = CryptoJS.AES.encrypt(e, c, {
iv: d,
mode: CryptoJS.mode.CBC
});
return f.toString()
}
function c(a, b, c) {
var d, e;
return setMaxDigits(131),
d = new RSAKeyPair(b,"",c),
e = encryptedString(d, a)
}
function d(d, e, f, g) {
var h = {}
, i = a(16);
return h.encText = b(d, g),
h.encText = b(h.encText, i),
h.encSecKey = c(i, e, f),
h
}
可以發現a(16)就是一個隨機生成的數,所以我們不需要管他。而b目前來看是AES的cbc模式加密。那麼這個encText生成的規則我們就很清楚了。兩次AES的cbc加密。其中偏移量為0102030405060708固定不變。兩次的key不同。而函式c就是三個引數進行RSA加密。整個演算法大體流程差不多稍微瞭解。
到這裡先停一下,不要在分析函式了,我們在分析分析資料。
step3:分析引數
再回到var bYc7V = window.asrsea(JSON.stringify(i3x), bkY2x(["流淚", "強"]), bkY2x(VM8E.md), bkY2x(["愛心", "女孩", "驚恐", "大笑"]))這個函式。憑直覺能夠感覺得到有些資料一定跟我們的核心引數無關,最多跟時間戳有關。
查詢bky2x源頭,
再找的話其實沒必要,這類函式你找找。可以複製到vscode溯源找到根源。分析,在這裡就不繁瑣介紹。直接打斷點分析吧!看看他是怎麼執行的。
其實多次抓你會發現後三個引數是固定不變的(非互動型資料)。
然而最想要的是第一個引數
你心心年年的引數原來長這個樣,那麼和預想差不多,僅僅第一個引數和我們的引數有關。offset就是頁面*20,R_SO_4_ songid就是當前這首歌的id.其實到這個時候,你的i和encSecKey可以一起儲存了。因為上面分析說過,這個i是隨機生成,而encSecKey也和我們核心引數無關,但是和i相關,所以要記錄一組。用作ESA加密的引數和post請求的引數。
現在的你是不是很激動,因為真想即將浮出水面。
step4: 校驗
這步驟也是很重要的一環,因為你在它的js中會發現。
網易是否會動手腳呢?下載原始的js進行測試。發現哈哈,結果一致。那麼就不需要更改再仔細檢視那段加密演算法的程式碼了。
架構圖為
step5:轉為python程式碼
需要將AES的cbc模式的程式碼用Python克隆。達到加密的效果,測試一下。發現結果一致nice
編寫爬蟲
下面就開始編寫爬蟲。先用postman測試需要那些引數。
沒問題,編寫爬蟲。根據你喜歡的哥。把id輸進去,生成你愛的詞雲!一首光輝歲月送給大家!
import requests
import urllib.parse
import base64
from wordcloud import WordCloud
import jieba.analyse
import matplotlib.pyplot as plt
from bs4 import BeautifulSoup
from Crypto.Cipher import AES
header={'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36',
#'Postman-Token':'4cbfd1e6-63bf-4136-a041-e2678695b419',
"origin":'https://music.163.com',
#'referer':'https://music.163.com/song?id=1372035522',
#'accept-encoding':'gzip,deflate,br',
'Accept':'*/*',
'Host':'music.163.com',
'content-lenth':'472',
'Cache-Control':'no-cache',
'content-type': 'application/x-www-form-urlencoded',
'Connection':'keep-alive',
#'Cookie':'iuqxldmzr_=32; _ntes_nnid=a6f29f40998c88c693bc910331bd6bea,1558011234325; _ntes_nuid=a6f29f40998c88c693bc910331bd6bea; _ga=GA1.2.2120707788.1559308501; WM_TID=pV2C%2BjTrRwBBAAERUVJojniTwk8%2B8Zta; JSESSIONID-WYYY=nvf%2BggodQRfcT%2BTvBRmANqMrsDeQCxRvqwFsxDr3eJvNNWhGYFhfCXKFkfAfOdbHhpCsMzT39mAeJ7ZamBQZbiwwtnSZD%5CPWRqKxD9t6dGKD3bTVjomjgB39DB07RNIWI32bYKa2H4fg1qQgqI%2FR%2B%2Br%2BZXJvgFg1Vh%2FA2XRj9S4p0EMu%3A1560927288799; WM_NI=DthwcEQf5Ew2NbTIZmSNhSnm%2F8VWsg5RxhkYogvs2luEwZ6m5UhdzbHYPIr654ZBWKV4o22%2BEwb9BvdLS%2BFOmOAEUG%2B8xd8az4CX%2FiAL%2BZkz3syA0onCPkhQwCtL4pkUcjg%3D; WM_NIKE=9ca17ae2e6ffcda170e2e6eed2d650989c9cd1dc4bb6b88eb2c84e979f9aaff773afb6fb83d950bcb19ecce92af0fea7c3b92a88aca898e24f93bafba6f63a8ebe9caad9679192a8b4ed67ede89ab8f26df78eb889ea53adb9ba94b168b79bb9bbb567f78ba885f96a8c87a0aaf13ef7ec96a3d64196eca1d3b12187a9aedac17ea8949dccc545af918fa6d84de9e8b885bb6bbaec8db9ae638394e5bbea72f1adb7a2b365ae9da08ceb5bb59dbcadb77ca98bad8be637e2a3'
}
def pkcs7padding(text):
"""
明文使用PKCS7填充
最終呼叫AES加密方法時,傳入的是一個byte陣列,要求是16的整數倍,因此需要對明文進行處理
:param text: 待加密內容(明文)
:return:
"""
bs = AES.block_size # 16
length = len(text)
bytes_length = len(bytes(text, encoding='utf-8'))
# tips:utf-8編碼時,英文佔1個byte,而中文佔3個byte
padding_size = length if(bytes_length == length) else bytes_length
padding = bs - padding_size % bs
# tips:chr(padding)看與其它語言的約定,有的會使用'\0'
padding_text = chr(padding) * padding
return text + padding_text
def encrypt(key, content):
"""
AES加密
key,iv使用同一個
模式cbc
填充pkcs7
:param key: 金鑰
:param content: 加密內容
:return:
"""
key_bytes = bytes(key, encoding='utf-8')
iv = bytes('0102030405060708', encoding='utf-8')
cipher = AES.new(key_bytes, AES.MODE_CBC, iv)
# 處理明文
content_padding = pkcs7padding(content)
# 加密
encrypt_bytes = cipher.encrypt(bytes(content_padding, encoding='utf-8'))
# 重新編碼
result = str(base64.b64encode(encrypt_bytes), encoding='utf-8')
return result
def getcomment(songid,page):
url="https://music.163.com/weapi/v1/resource/comments/R_SO_4_"+songid+"?csrf_token="
print(url)
formdata = {
"params": "",
"encSecKey": "c81160c64a08feb6cfed91c1619d5bffd05dd278b685c94a748689edf035ee0436b66aa7019927ce0fedd26aee9a22cdc6743e58a120f9db0126ebb2e61dae3f7ee21088eb747f829bceed9a5bbb9ee7a2eecf1a358feac431acaab17c95b8491a6a955f7c17a02a3e7886390c2cb3b981f4ccbd5163a566d27ace95db073401",
}
aes_key = '0CoJUm6Qyw8W8jud'## 不變的
print('aes_key:' + aes_key)
# 對英文加密
source_en = '{"rid":"R_SO_4_'+songid+'","offset":"'+str(page*20)+'","total":"false","limit":"20","csrf_token":""}'
#offset自己該
print(source_en)
encrypt_en = encrypt(aes_key, source_en)#第一次加密
print(encrypt_en)
aes_key='3Unu7SzdXGctW1vA'
encrypt_en = encrypt(aes_key, str(encrypt_en)) # 第二次加密
print(encrypt_en)
formdata['params']=encrypt_en
print(formdata['params'])
formdata = urllib.parse.urlencode(formdata).encode('utf-8')
print(formdata)
req = requests.post(url=url, data=formdata, headers=header)
return req.json()
if __name__ == '__main__':
songid='346576'
page=0
text=''
for page in range(10):
comment=getcomment(songid,page)
comment=comment['comments']
for va in comment:
print (va['content'])
text+=va['content']
ags = jieba.analyse.extract_tags(text, topK=50) # jieba分詞關鍵詞提取,40個
print(ags)
text = " ".join(ags)
backgroud_Image = plt.imread('tt.jpg') # 如果需要個性化詞雲
wc = WordCloud(background_color="white",
width=1200, height=900,
mask=backgroud_Image, # 設定背景圖片
#min_font_size=50,
font_path="simhei.ttf",
max_font_size=200, # 設定字型最大值
random_state=50, # 設定有多少種隨機生成狀態,即有多少種配色方案
) # 字型這裡有個坑,一定要設這個引數。否則會顯示一堆小方框wc.font_path="simhei.ttf" # 黑體
# wc.font_path="simhei.ttf"
my_wordcloud = wc.generate(text)
plt.imshow(my_wordcloud)
plt.axis("off")
plt.show() # 如果展示的話需要一個個點
file = 'image/' + str("aita") + '.png'
wc.to_file(file)
相關文章
- 利用Python網路爬蟲抓取網易雲音樂歌詞Python爬蟲
- python爬蟲:瞭解JS加密爬取網易雲音樂Python爬蟲JS加密
- Hyperf抓取網易雲音樂評論
- python爬蟲之JS逆向某易雲音樂Python爬蟲JS
- 網易雲音樂評論爬蟲(2):歌曲的全部評論爬蟲
- Python 爬蟲獲取網易雲音樂歌手歌詞Python爬蟲
- Python爬蟲:逆向分析網易雲音樂加密引數Python爬蟲加密
- Python爬蟲實踐-網易雲音樂Python爬蟲
- Python爬蟲實踐--爬取網易雲音樂Python爬蟲
- 網易雲音樂評論爬蟲(1):全部熱門歌曲及其 id 號爬蟲
- 如何用Python網路爬蟲爬取網易雲音樂歌曲Python爬蟲
- Python 爬蟲獲取網易雲音樂歌手資訊Python爬蟲
- 網易雲音樂的一個評論
- Python逆向爬蟲入門教程: 網易雲音樂加密引數 params & encSecKey 逆向解析Python爬蟲加密
- Python爬取網易雲音樂歌單歌曲Python
- 第一彈:puppeteer爬蟲小demo —— 網易雲音樂爬蟲
- 爬蟲實踐之獲取網易雲評論資料資訊爬蟲
- 2022年網易雲音樂樂評報告
- Python爬蟲:爬取instagram,破解js加密引數Python爬蟲JS加密
- Python爬蟲,抓取淘寶商品評論內容!Python爬蟲
- 手把手教你寫網路爬蟲(1):網易雲音樂歌單爬蟲
- python3.x爬取網易雲音樂,超詳細版Python
- Python 爬取網易雲音樂 自動安裝所需模組Python
- Python爬蟲如何去抓取qq音樂的歌手資料?Python爬蟲
- 【Python爬蟲實戰】使用Selenium爬取QQ音樂歌曲及評論資訊Python爬蟲
- python3.基礎爬取網易雲音樂【超詳細版】Python
- python爬蟲學習:爬蟲QQ說說並生成詞雲圖,回憶滿滿Python爬蟲
- 網易雲歌詞爬取(java)Java
- Python爬蟲入門教程 21-100 網易雲課堂課程資料抓取Python爬蟲
- 仿網易雲音樂webAppWebAPP
- 仿網易雲音樂播放介面
- 網易雲音樂歌曲資訊
- 雲音樂評論內容理解技術
- AI音樂,騰訊音樂、網易雲音樂的新版圖?AI
- LRC歌詞原理和實現高仿Android網易雲音樂Android
- python爬蟲之快速對js內容進行破解Python爬蟲JS
- Python從網易雲音樂、QQ 音樂、酷狗音樂等搜尋和下載歌曲Python
- Vue 實現網易雲音樂 WebAppVueWebAPP