Python中如何用代码下载任意指定的网易云歌曲
前两天教了大家如何在控制台上找到真实的 mp3 播放地址,但是不可以下载付费的,因为只能下载可播放的歌曲。至于怎样下载付费网易云音乐,还是开个会员吧,要知道免费是最贵的的这个道理。
有粉丝看了前两天文章想用代码来装逼,我就为了满足他,特意去折腾了两天,终于写出来了,迫不及待与大家分享一把。不得不说,这里面坑很大,遇到几个大坑在那里折腾了几个小时,分享出来让大家想装逼的少踩点坑。废话不多说,开始今天主题!
1.寻找目标请求
打开网易云主页 ,打开开发者工具,点击搜索
是不是看到很多请求,不要慌,慢慢找。找了之后你会发现下面这个链接
这个链接返回的是 json,里面包含的是歌曲的信息,但是没有 MP3 播放链接,这个或许有用,因为有歌曲的 id,先放着。
我试着点击歌曲播放,又增加了几个请求。一看,里面就有我想要的 MP3 链接。
这样子,获取 mp3 请求的链接出来了,https://music.163.com/weapi/song/enhance/player/url?csrf_token=
可以看到是个 post 请求,状态码为 200,我们接着往下看 fromdata 是什么数据。
是两个加密了的参数,不过不怕,如果你看过我之前写的利用 python 爬取网易云音乐,并把数据存入 mysql你会发现 fromdata 参数是一样的,所以破解加密参数思路是一样的,不过这次我不用 fiddler 了,只用开发者工具来调试,看好了!!!我们看看这个请求的来源是什么。
点进去看看,是个混淆的 js,点左下角可以格式化,这样好看点。
进行搜索params,你会发现这个:
可以看到,加密的方式都没有改变,还是和之前一样,只是变量名字改变了。**window.asrsea()**有四个参数,先看看后面三个参数,因为都很相似。继续进行搜索定位。
可以看出,返回的是一个固定的内容,所以不用管了,等下可以进行调试抓出来。再看看第一个参数。是一个 json。我们可以进行断点调试进行获取。
进行刷新,你会看到下面这些内容。
可以看到**window.asrsea()**是一个 d 函数,定位过去看看,然后又给个断点。
点击去往下一个断点,你会看到
四个参数都出来了,我直接贴出来这里吧:
d:"{"ids":"[523946593]","br":128000,"csrf_token":""}"e:"010001"f:"00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"g:"0CoJUm6Qyw8W8jud"
参数都出来了,很容易就知道 d 参数里面的 ids 对应的就是歌曲 id,所以说刚才找的链接有用了。br 是个固定值,对应的可能是歌曲的质量之类的,不需要管的。
下面再看看 d 函数是如何加密的:
里面又包含了很多 **a , b ,c **的三个函数,先看看 a 函数
这个 a 函数是在一堆字符串中随机找出 16 个字符串。ok,下一个。
b 函数采用了 aes 加密, 加密的密文是 e ,也就是参数的 a 内容,c是密钥,第三个参数中有偏移量 d 和加密模式 **CBC **。再看看 c 函数。
c 函数是采用 rsa 加密,b 为加密指数, 空字符串为解密参数,c 为加密系数。
好了,三个函数分析完毕,再回头看看 d 函数。
可以看到 params 参数是经过两次 b 函数生成的,也就是用 aes 加密两次,encSecKey 参数是通过 c 函数生成的,也就是通过 rsa 加密方式生成的。
废话不多说,Talk is cheap, show me the code
2.代码部分
先把随机生成 16 个字符串的展示下
为了让大家好看点,代码以后都用照片代替
接下来是 aes 加密的
这里有一个巨坑,谷歌了也没发现有谁遇到过,就是用 python 进行 aes 加密的时候,只能加密数字和字母,不能对中文进行加密,会报错
Input strings must be a multiple of 16 in length
解决方方法是在cbc加密的模式下,在对字符串补齐为长度为 16 的倍数时,长度指标不能用中文,要先把他转为 unicode 编码的长度才可以。比如上面的,下面的就是错误示范
pad = 16 - len(text) % 16
此坑爬过去了,接着下一个 rsa 加密
还有需要注意一下的是,在生成随机 16 个字符串的时候,需要保证 params 和 encSecKey 两个参数是对应的这个随机字符串是一致的。要不然加密之后还是会出错,获取不了正确信息。好了,最后一个是获取两个加密参数。
代码写完了,那还等什么,运行一下装逼啊!
{'code': -460, 'msg': 'Cheating'}
这下好了,装逼失败,被网易云认出来我是爬虫的,那我试试加下请求头?结果加了还是一个样,这个也算是个巨坑吧。解决方法还是加请求头,只需要加两个,一个是浏览器识别 **user-agent **,另一个是 cookie ,想不到吧?我也想不到,居然还有在cookie上面做反爬的,但是我用了 **session **来保持 cookie 还是不行,需要自己复制浏览的 cookie 就行保存才可以。
歌曲现在能下载了,可我要的是任意歌曲啊。那好,我们再去看看这个请求 https://music.163.com/weapi/cloudsearch/get/web?csrf_token=,因为返回的是歌曲 id。
3.寻找歌曲 id
可以看到,参数还是和上面的那个请求的参数一样,但是我们知道的是那个 d 函数,后三个参数是不变的,所以我们只需要找前面那个变化的参数就可以了,还是同样的操作,断点调试。
也是很容易就找到的,d 参数就是下面这个
d = '{"hlpretag":"<span class=\"s-fc7\">","hlposttag":"","s":"可能否","type":"1","offset":"0","total":"true","limit":"30","csrf_token":""}'
这个分析就可以说完毕了。
4.搜索歌曲代码
这个是获取歌曲 id 的代码,其他的没什么问题了。
最后
我还将程序打包了,遇到了喜欢的歌曲都可以下载下来,虽然可以直接用网易云下载,不用那么麻烦,但是我们学编程的是要干什么的?装逼啊,能用代码绝不用其他的东西。
效果图如上,下载杠杆的,需要完整代码的可以后台回复音乐即可送给你。
ps:原创不易,写了这篇文章可谓花费了我 1024 根头发,听说转发是生发的最有效之道,所以你懂得!
扫面二维码关注获取更多有趣的 python 文章
Python中如何用代码下载任意指定的网易云歌曲
同志开下门,查下七月的水表!
我来给你一个直接能用的方案。核心是使用requests库模拟请求,配合selenium获取加密参数。
import requests
import json
import subprocess
import re
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def download_netease_music(song_id, save_path='./'):
"""
下载指定ID的网易云音乐
Args:
song_id: 歌曲ID(从歌曲URL中获取)
save_path: 保存路径
"""
# 1. 使用selenium获取加密参数
print("正在获取加密参数...")
options = webdriver.ChromeOptions()
options.add_argument('--headless') # 无头模式
driver = webdriver.Chrome(options=options)
try:
# 访问歌曲页面
url = f'https://music.163.com/#/song?id={song_id}'
driver.get(url)
# 切换到iframe
driver.switch_to.frame('g_iframe')
# 等待页面加载
wait = WebDriverWait(driver, 10)
wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'm-playbar')))
# 获取页面源码
page_source = driver.page_source
# 提取加密参数(这里简化处理,实际需要更复杂的解析)
# 通常需要从页面中提取加密的music url
pattern = r'"url":"(http[^"]+\.mp3[^"]*)"'
match = re.search(pattern, page_source)
if not match:
print("未找到音乐URL,尝试其他方法...")
# 备用方案:使用API
api_url = f'http://music.163.com/api/song/enhance/player/url?id={song_id}&ids=%5B{song_id}%5D&br=3200000'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
response = requests.get(api_url, headers=headers)
data = response.json()
if data['code'] == 200 and data['data'][0]['url']:
music_url = data['data'][0]['url']
else:
print("获取音乐URL失败")
return
else:
music_url = match.group(1).replace('\\', '')
finally:
driver.quit()
# 2. 下载音乐文件
print(f"正在下载: {music_url}")
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Referer': 'https://music.163.com/'
}
response = requests.get(music_url, headers=headers, stream=True)
if response.status_code == 200:
# 从URL中提取文件名
filename = f'song_{song_id}.mp3'
if '?=' in music_url:
filename = music_url.split('?=')[-1]
filepath = f'{save_path}/{filename}'
with open(filepath, 'wb') as f:
for chunk in response.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
print(f"下载完成: {filepath}")
return filepath
else:
print(f"下载失败,状态码: {response.status_code}")
return None
# 使用示例
if __name__ == "__main__":
# 示例:周杰伦-晴天,歌曲ID: 186016
song_id = "186016" # 替换为你要下载的歌曲ID
download_netease_music(song_id)
使用步骤:
- 安装依赖:
pip install requests selenium - 下载对应浏览器驱动(如ChromeDriver)
- 找到要下载歌曲的ID(从网易云网页URL中获取,如
song?id=186016) - 调用
download_netease_music(song_id)函数
关键点说明:
- 网易云对音乐链接进行了加密和反爬处理
- 需要模拟浏览器行为获取真实的音乐URL
- 某些高质量音源可能需要VIP权限
- 歌曲ID可以从分享链接或网页URL中获取
更稳定的方案:
如果需要更稳定的下载,建议使用现成的第三方库,比如NeteaseCloudMusicApi的Python版本,或者musicdl这样的专门工具。
总结:核心是绕过加密获取真实音乐链接。
同志开下门,有你快递!
同志开下门, 我是美团外卖!
律师函警告
这个加密函数也太容易被定位了,没啥意义啊
下载的是高音质的吗
网易的 api 和加密 GitHub 一堆分析
chrome 声海盗插件了解下
律师函警告
能把思路写出了,非常感谢。
不知道是不是我见识短浅,自从乌云到了之后这种性质或者之上的实战文章越来越少。
你再这样小心我叫小春和你聊聊
这么恐怖的吗
我在考虑要不要删除了…被大家吓到了。
同志,记得把声明信息补上,仅用于技术学习云云
虽然不会 看着爽啊
多谢提醒,真的被吓到了,只是分享下知识。。
弱弱问下,付费音乐也能下载么
不能的,还是付费下载吧。
点赞
点赞
为了省 8 块钱,真是费心了
干货,点赞👍
喜欢这种干货~
感觉可以写一个脚本 [滑稽]
[musicbox]( https://github.com/darknessomi/musicbox)
尽管前人做过了,但是楼主写出了思路过程。
https://github.com/lzuntalented/music-fetch
另一种获取播放地址的方式
是不是高音质的?
如果不是高音质的,那和 F12 开发者工具里面的 Network-Elements 有什么区别…那个还简单
教解密技术是挺好的,但是可以的话,解个别的吧,毕竟音乐人也不容易.
牛逼,挖个坑改日再填
偷偷自己用就好了啊😨发出来不就……
这里没有破解 vip,只是下载个音乐而已。
问题来了 如果对每个网站都要这么分析一波 甚至人家上 WebAssembly 就更加复杂了
有没有啥通用的自动化逆向代码生成爬取代码呢,如果使用 chrome-headless 效率太低
兄弟想多了
nb,小心网易发来律师含哈哈哈
个人觉得,既然图片这么多了,何不做成视频更易阅读,干货点赞
出视频的话可能你就看不到了
楼主我按着你的教程,请求来源 js 那里,跳出来 n 个 js,随便点了一个,然后接着调试,然而发现调试的 d 参数没有歌曲的 id,感觉是点的 js 跟你不一样导致的。
首先要找对 js 文件,然后因为网易云很多接口的参数都是用的这个 js,所以得调试到相应的响应链接,多点几下下一个断点就好,最好欢迎到公众号交流。
连思路也有了,赞


