python 網易雲音樂
阿新 • • 發佈:2018-11-20
1. 網易雲POST需要兩個引數params,encSecKey
2. 在某一個js中可以找到這兩個引數
3. bUS2x就是一個函式window.asrsea的返回值,window.asrsea = d,最終就是d函式,傳入4個引數
4. 檢視傳入的是什麼引數,把網頁中的js儲存在本地,找到window.asrsea,在其上面寫下一下程式碼,目的是為了在網頁的Console中看到傳入的引數是什麼
5. 替換網頁中的js,在fiddler中找到包含著兩個引數的js,並把它替換為你修改完成的js,然後再重新整理的網易雲頁面,可以在Console看到如下
6. 只有第一個引數是不一樣的,加密方式
# -*- coding:utf-8 -*- import base64 import random from binascii import hexlify from Crypto.Cipher import AES import json import requests class GetMusic: def __init__(self): self.key = GetParamsAndEncSecKey() self.headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36', 'Referer': 'http://music.163.com/'} self.session = requests.Session() self.session.headers = self.headers self.conmment_url = 'https://music.163.com/weapi/v1/resource/comments/R_SO_4_{}?csrf_token=' # 評論 self.lyric_url = 'https://music.163.com/weapi/song/lyric?csrf_token=' # 歌詞 self.music_url = 'https://music.163.com/weapi/song/enhance/player/url?csrf_token=' # 歌曲 self.url = 'https://music.163.com/weapi/cloudsearch/get/web?csrf_token=' # 搜尋歌曲列表,無歌曲連結 def get_params_and_encSecKey(self, song=None): ''' 獲取什麼就返回所需要兩個引數 1. 歌曲 2. 歌詞 3. 評論 預設 4. 搜尋的歌曲列表 :param song: :return: ''' if isinstance(song, int): data = {"ids": [song], "br": 128000, "csrf_token": ""} elif isinstance(song, str) and song.isdigit(): data = {"id": song, "lv": -1, "tv": -1, "csrf_token": ""} elif song == None: data = {} else: data = {"hlpretag": "<span class=\"s-fc7\">", "hlposttag": "</span>", "s": song, "type": "1", "offset": "0", "total": "true", "limit": "30", "csrf_token": ""} song = json.dumps(data) data = self.key.get(song) return data def get_music_list_info(self, name): ''' 獲取歌曲詳情:歌名+歌曲id+作者 :param name: :return: ''' data = self.get_params_and_encSecKey(name) res = self.session.post(self.url, data=data) # 歌曲 song_info = res.json()['result']['songs'] for song in song_info: song_name = song['name'] song_id = song['id'] songer = song['ar'][0]['name'] print(song_name, '\t', song_id, '\t', songer) self.get_music_url(song_id) self.get_music_lyric(song_id) self.get_music_comment(song_id) break def get_music_url(self, id): ''' 獲取歌曲URL連結 :param id: :return: ''' data = self.get_params_and_encSecKey(id) res = self.session.post(self.music_url, data=data) song_url = res.json()['data'][0]['url'] print(song_url) def get_music_lyric(self, id_str): ''' 獲取歌詞 :param id_str: :return: ''' data = self.get_params_and_encSecKey(str(id_str)) res = self.session.post(self.lyric_url, data=data) lyric = res.json()['lrc']['lyric'] print(lyric) def get_music_comment(self, song_id): ''' 獲取歌曲評論: 評論人+內容+頭像 :param song_id: :return: ''' data = self.get_params_and_encSecKey() comment = self.session.post(self.conmment_url.format(str(song_id)), data=data) com_list = comment.json()['hotComments'] for com in com_list: content = com['content'] nickname = com['user']['nickname'] user_img = com['user']['avatarUrl'] print(nickname, '!!!!' + content + '!!!!', user_img) class GetParamsAndEncSecKey: def __init__(self): self.txt = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' self.i = ''.join(random.sample(self.txt, 16)) # 16為隨機數 # self.i = hexlify(os.urandom(16))[:16].decode('utf -8') # 16為隨機數bytes self.first_key = '0CoJUm6Qyw8W8jud' def get(self, song): ''' 獲取加密的引數 params是兩次加密的 :param song: :return: ''' res = self.get_params(song, self.first_key) params = self.get_params(res, self.i) encSecKey = self.get_encSecKey() return { 'params': params, 'encSecKey': encSecKey } def get_params(self, data, key): ''' 獲得params,加密字元長度要是16的倍數 :param data: :param key: :return: ''' iv = '0102030405060708' num = 16 - len(data) % 16 data = data + num * chr(num) # 補足 cipher = AES.new(key.encode(), AES.MODE_CBC, iv.encode()) result = cipher.encrypt(data.encode()) result_str = base64.b64encode(result).decode('utf-8') return result_str def get_encSecKey(self): ''' 獲取encSecKey,256個字串 hexlify--->轉換為btyes型別 pow--->兩個引數是冪,三個引數是先冪在取餘 format(rs, 'x').zfill(256)-->256位的16進位制 :return: ''' enc_key = '010001' modulus = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7' rs = pow(int(hexlify(self.i[::-1].encode('utf-8')), 16), int(enc_key, 16), int(modulus, 16)) return format(rs, 'x').zfill(256) if __name__ == '__main__': Msuic = GetMusic() Msuic.get_music_list_info('劉德華')