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('刘德华')