网易云音乐关键字搜索并生成下载url

一、获取搜索的歌单信息

​ 通过在网易云音乐进行关键字搜索,并通过F12检测,发现网页给网站https://music.163.com/weapi/cloudsearch/get/web?csrf_token=发送了一条post请求(经测试发现csrf_token=后的数值与登录账号有关),post的data中包含了params和encSecKey两条数据(因此无需再使用selenium来提取iframe内的数据):

​ 通过检查其preview我们可以发现,其中包含了我们所需要搜索歌曲的信息,如下所示:

​ 由于post的data参数为params及encSecKey,因此为了获取preview的json数据,需要对params及encSecKey进行解密,而解密需要获取解密的key,因此,在开发者工具中搜索encSecKey,如图所示:

​ 然后点开core开头的文件,通过阅读可以发现加密函数:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MXZ3bLOQ-1597906857705)(C:\Users\wangyu\Desktop\博客\网易云搜索5.png)]

var bVZ7S = window.asrsea(JSON.stringify(i7b), bqN2x(["流泪", "强"]), bqN2x(Wx5C.md), bqN2x(["爱心", "女孩", "惊恐", "大笑"]));

​ i7b为加密前的数据,[“流泪”, “强”]查函数上方的表可知为“010001”,Wx5C.md根据上方的表可知为Wx5C.md = [“色”, “流感”, “这边”, “弱”, “嘴唇”, “亲”, “开心”, “呲牙”, “憨笑”, “猫”, “皱眉”, “幽灵”, “蛋糕”, “发怒”, “大哭”, “兔子”, “星星”, “钟情”, “牵手”, “公鸡”, “爱意”, “禁止”, “狗”, “亲亲”, “叉”, “礼物”, “晕”, “呆”, “生病”, “钻石”, “拜”, “怒”, “示爱”, “汗”, “小鸡”, “痛苦”, “撇嘴”, “惶恐”, “口罩”, “吐舌”, “心碎”, “生气”, “可爱”, “鬼脸”, “跳舞”, “男孩”, “奸笑”, “猪”, “圈”, “便便”, “外星”, “圣诞”],查表拼接为"00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7",[“爱心”, “女孩”, “惊恐”, “大笑”]同样查表可知为“0CoJUm6Qyw8W8jud”

​ 而函数window.asrsea()根据上方function可知为d函数:

!function() {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}function e(a, b, d, e) {var f = {};return f.encText = c(a + e, b, d),f}window.asrsea = d,window.ecnonasr = e
}();

​ 因此我们可以通过在d函数处设置断点查看post发送的原始数据是什么:

​ 具体数据如下:d: “{“hlpretag”:”<span class=“s-fc7”>",“hlposttag”:"",“s”:“浅唱”,“type”:“1”,“offset”:“0”,“total”:“true”,“limit”:“30”,“csrf_token”:""}"

因此,搜索不同的信息时仅需修改“s”对应的数值即可,且整个d的数据格式为str,我们仅需将其整体打包为str即可。

二、实现加密函数

  1. function a(a):

    函数a的主要功能是为了实现从字符串b中随机采样a个不同字符,由于这里调用时默认是16位,因此可以通过以下python程序简单实现:

    def get_i():txt = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'return ''.join(random.sample(txt, 16))
    
  2. function b(a, b):

    函数b的主要功能对post的data以及加密的key进行encode,然后进行偏移量为iv的加密。

    def AES_encrypt(text, key, iv):bs = AES.block_sizepad2 = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs)encryptor = AES.new(to_16(key), AES.MODE_CBC,to_16(iv))encrypt_aes = encryptor.encrypt(str.encode(pad2(text)))encrypt_text = str(base64.encodebytes(encrypt_aes), encoding='utf-8')return encrypt_text
    
  3. function c(a, b, c):

函数c的主要功能为了生成encSecKey

def RSA_encrypt(text, pubKey, modulus):text=text[::-1]rs=int(codecs.encode(text.encode('utf-8'), 'hex_codec'), 16) ** int(pubKey, 16) % int(modulus, 16)return format(rs, 'x').zfill(256)

params参数是通过两次b函数得到。

三、生成下载url

​ 类似于获取歌单信息,首先需要找到post请求的网站地址,依然是通过F12检查,通过删选信息,可以发现这条post信息中包含了歌曲下载的url。


post所发送的data依然是params和encSecKey,post的目标网站为https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token=,同理我们可以设置断点来检查所post的加密前的data,如图:

data的数据格式:{“ids”:str([id]),“level”:“standard”,“encodeType”:“aac”, “csrf_token”: “”},其中id表示歌曲的id号,level是音乐品质,经我测试标准为standard,较高音质为higher,极高音质没测试出关键词,无损音质关键词为lossless。

另外还发现一个有趣的事情:


对vip歌曲,普通用户是无法发送post请求,因此需要使用vip账号的cookies登录才可以下载vip歌曲。所以说还是支持正版吧。

四、完整代码

import urllib.request,os,json
import requests,random
import base64,codecs
from Crypto.Cipher import AES
import pickledef to_16(key):while len(key) % 16 != 0:key += '\0'return str.encode(key)def AES_encrypt(text, key, iv):bs = AES.block_sizepad2 = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs)encryptor = AES.new(to_16(key), AES.MODE_CBC,to_16(iv))encrypt_aes = encryptor.encrypt(str.encode(pad2(text)))encrypt_text = str(base64.encodebytes(encrypt_aes), encoding='utf-8')return encrypt_textdef RSA_encrypt(text, pubKey, modulus):text=text[::-1]rs=int(codecs.encode(text.encode('utf-8'), 'hex_codec'), 16) ** int(pubKey, 16) % int(modulus, 16)return format(rs, 'x').zfill(256)#获取i值的函数,即随机生成长度为16的字符串
def get_i():txt = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'return ''.join(random.sample(txt, 16))def set_user_agent():USER_AGENTS = ["Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)","Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)","Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)","Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)","Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6","Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1","Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0","Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5"]user_agent = random.choice(USER_AGENTS)return user_agentclass WanYiYun():def __init__(self):self.url_search='https://music.163.com/weapi/cloudsearch/get/web?csrf_token=' #post地址self.song_url='https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token='self.g = '0CoJUm6Qyw8W8jud'#buU9L(["爱心", "女孩", "惊恐", "大笑"])的值self.b = "010001"#buU9L(["流泪", "强"])的值# buU9L(Rg4k.md)的值self.c = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'self.i = get_i()#随机生成长度为16的字符串self.iv = "0102030405060708"  # 偏移量if not os.path.exists("d:/music"):os.mkdir('d:/music')self.headers={  'User-Agent':set_user_agent(),'Referer':'https://music.163.com/','Content-Type':'application/x-www-form-urlencoded'}def get_params(self,id):#获取加密后的paramsif isinstance(id, int):#标准 standard 较高  higher  无损losslessencText = {"ids":str([id]),"level":"higher","encodeType":"aac", "csrf_token": ""}elif id == None:encText = {}else:encText = {"hlpretag": "<span class=\"s-fc7\">", "hlposttag": "</span>", "s": id, "type": "1", "offset": "0","total": "true", "limit": "30", "csrf_token": ""}encText = json.dumps(encText)return AES_encrypt(AES_encrypt(encText,self.g, self.iv), self.i, self.iv)def get_encSecKey(self):#获取加密后的encSeckeyreturn RSA_encrypt(self.i, self.b, self.c)def get_search(self, str):formdata = {'params': self.get_params(str),'encSecKey': self.get_encSecKey()}res = requests.post(self.url_search, data=formdata)# 获取歌曲列表的json数据song_info = res.json()['result']['songs']return song_infodef get_download_url(self, name):music_list = self.get_search(name)cookie = pickle.load(open("wyy_cookie.pkl", "rb"))cookies = {}for c in cookie:cookies[c['name']] = c['value']cnt = 0words = '网易云:\n'for music in music_list:if cnt == 3:breakcnt = cnt + 1music_id = music['id']# print(type(music_id))music_name = music['name']music_author = music['ar'][0]['name']music_album = music['al']['name']words = words + '歌名:' + music_name + '\n'words = words + '歌手:' + music_author + '\n'words = words + '专辑名:' + music_album + '\n'formdata = {'params':self.get_params(music_id),'encSecKey':self.get_encSecKey()}response = requests.post(self.song_url, headers=self.headers, data=formdata, cookies = cookies)download_url = json.loads(response.content)["data"][0]["url"]if download_url:words = words + '下载链接:' + download_url + '\n'else:words = words + '下载链接:' + '无' + '\n'print(words)if __name__ == '__main__':wanyiyun=WanYiYun()# name = input("网易云搜索关键词:")wanyiyun.get_download_url('许嵩')

网易云音乐关键字搜索并生成下载url相关推荐

  1. QQ音乐关键字搜索并生成下载url

    QQ音乐关键字搜索并生成下载url 1. 获取搜索的歌单信息 ​ 通过在QQ音乐进行关键字搜索,并通过F12检测,发现网页给网站https://c.y.qq.com/soso/fcgi-bin/cli ...

  2. 酷狗音乐关键字搜索并生成下载url

    酷狗音乐关键字搜索并生成下载url 1. 获取搜索的歌单信息 ​ 通过在酷狗音乐进行关键字搜索,并通过F12检测,发现网页给网站发送了get请求. https://complexsearch.kugo ...

  3. 在网易云音乐网页版上加下载按键进行下载歌曲

    源由 原理 代码解决 思路 Ajax 请求函数 获取 id 和歌名 点击下载 利用 a 标签 利用 audio 标签 更改歌曲名 a 标签的 download 属性 利用 Ajax 请求歌曲内容 利用 ...

  4. 代理网易云音乐,免费听歌与下载

    代理网易云音乐,实现网易云音乐免费下载听歌 相信很多朋友听歌都在用网易云音乐吧!对于在线听歌也要收费这个功能也是非常不喜欢吧!没用的时候我也不知道,现在把解决办法告诉大家: 该进入正题了: 首先需要实 ...

  5. python3GUI--仿做一个网易云音乐By:PyQt5(附下载地址)

    文章目录 一.前言 二.展示 2.1主界面 1.主界面 2.歌单 3.播客 3.最新音乐 4.综合展示(动图) 5.专属定制-音乐雷达 6.专属定制-音乐雷达(动图) 7.专属定制-音乐歌单推荐 2. ...

  6. 抓取网易云音乐歌曲热门评论生成词云(转)

    非原创作品,转载自:http://blog.csdn.net/marksinoberg/article/details/70809830 前言 网易云音乐一直是我向往的"神坛",听 ...

  7. ubuntu20.04运行网易云音乐出现无法播放、下载的情况

    Ubuntu网易云音乐不能播放下载 最近在为了学习和开发,在主机上安装了ubuntu20.04,在成功的摒弃了很多windows上的习惯之后,慢慢的开始习惯这种类unix系统的操作和使用.但是出现了一 ...

  8. 网易云音乐热评在线生成

    网易云热评图片怎么生成? 一个工具帮你搞定! 工具入口:点击进入 先看效果图: 点击对话框可编辑内容 IOS用户还可以直接长按评论复制分享链接一键生成热评对话框 点击复制链接 直接粘贴到第一个输入框点 ...

  9. 网易云音乐params和encSecKey生成原理

    1.首先来个整体的解析 params:经过两次AES加密后的数据(128位,CBC,pkcs5padding) 第一加密:要加密的是真正要发送的明文数据(数据的具体格式,下面会讲),密钥固定为0CoJ ...

最新文章

  1. SpringBoot2.0.3之quartz集成,不是你想的那样哦!
  2. a卡显存测试软件_官方游戏性能堪比RTX 3080 苏姿丰:RX 6000 Big Navi是史上最强A卡...
  3. Linux下Verilog仿真过程(二)
  4. Springboot-data-jpa
  5. 在 VirtualBox 中 CentOS 网络设置
  6. cssbefore图片大小_我可以在CSS:before /:after伪元素中更改图像的高度吗?
  7. aix oracle 10.2.0.1 升级 10.2.0.4,install oracle 10r2 for aix
  8. django http 收发_如何从一个django服务器发送请求到另一个服务器
  9. Spring中的bean是否是线程安全的
  10. Windows任务栏实现动态自动隐藏并透明
  11. pscc2018教程photoshop软件全套入门到精通分享
  12. ap启动失败 ensp_eNSP模拟WLAN——上线华为真实AP的方法及配置
  13. envi 监督分类超详细过程
  14. nginx.pid-nginx: [error] open() /var/run/nginx.pid failed (2: No such file or direc
  15. 【五一创作】使用Scala二次开发Spark3.3.0实现对MySQL的upsert操作
  16. 【Router】PC连接到路由LAN,但是无法获取到IP地址问题分析及解决方案
  17. 什么是超融合数据中心?超融合数据中心的价值是什么?
  18. 关于U盘的镜像经营模式
  19. 关于浏览器输入一个网址后页面经历的过程总结
  20. 我玩过的微信小程_已迁移

热门文章

  1. WinForm—控件TabIndex的作用和设置
  2. “转行做程序员”很难?这里有4个建议
  3. tf.estimator.train_and_evaluate 详解
  4. visualSVN server库迁移
  5. 【C数据类型】基本数据类型
  6. 苹果 APNs 介绍
  7. Android客户端之“微服私访”App的系统学习(一) 本地服务端环境的搭建和部署
  8. python中将数据写入excel
  9. RK3399 Android7.1在uboot中设置GPIO的电平无效
  10. zemax模拟ld_使用ZEMAX序列模式模拟激光二极管光源