- 仅作为个人学习使用,任何版权问题作者概不负责
- 本文的语言不会且不可能很严谨
- 博客园的编辑器有点BUG把我搞晕头了,所以本文可能有点鬼畜
前情
不知道各位有几个是对国内大厂的软件设计很满意的?
至少我是几乎受不了的。
所以我就没装过网易云的Windows端……
这段时间用着网页也受不了了。
于是我就想:既然我几乎每次用网易云都是听收藏,那能不能……
直接用系统的!?
正片
首先,我需要把我收藏的音乐拿到手。
其次,我们需要把音乐下载下来,才能让一个长得漂亮,但是不咋聪明的系统播放器播放。
探索
收藏的问题麻烦了我很久,直到有一天,我注意到了某网易云第三方客户端……
我当时就想,它能显示收藏,为嘛我不行?
于是我就赶紧看了它的GitHub,作者也很好,直接提供了一整套API的来源。
于是我就把API部署到了Vercel,它也顺利地跑了起来
我是个乐于分享的人,所以在此直接送上现成的API地址和它的GitHub:
https://netease-cloud-music-cwl0bfvmk-totowang-hhh.vercel.app/
https://github.com/Binaryify/NeteaseCloudMusicApi
获取收藏歌单
登录
看收藏歌单前,我们要登录。
登陆是啥来着?一个界面,要输入账号密码……
那就自己写!
def loginui(event=''): global up,e_usr,e_pwd,e_dir up = tk.Tk() up.title("配置") #第一行,用户名标签及输入框 tk.Label(up,text='邮箱').pack(fill=tk.X) e_usr = ttk.Entry(up) e_usr.pack(fill=tk.X) tk.Label(up,text='密码').pack(fill=tk.X) e_pwd = ttk.Entry(up,show='●') e_pwd.pack(fill=tk.X) #第三行登陆按扭,command绑定事件 ttk.Button(up,text='一键下载网易云收藏',command=login).pack(side=tk.BOTTOM,fill=tk.X) e_usr.bind('<KeyPress-Return>',lambda event:e_pwd.focus()) e_pwd.bind('<KeyPress-Return>',lambda event:login()) e_usr.focus() up.mainloop() def login(): global usr,pwd,path usr=e_usr.get() pwd=e_pwd.get() path=filebox.askdirectory(title='请选择音乐保存路径') up.destroy()
登录之后,电脑里存了啥来着?Cookie呀!
正好,我们的API也会返回Cookie。我们只需要在后面的请求中把Cookie硬塞到cookie参数里就可以了。
管他三七二十一,直接先把Cookie拿到手
res=requests.get(url="https://netease-cloud-music-cwl0bfvmk-totowang-hhh.vercel.app/login?email="+usr+"&password="+pwd) json=res.json() cookie=json['cookie']
你以为这就可以获取到收藏歌单了?不是不是,你可不知道为了获取一个收藏歌单网易云付出了多少……
众所周知,收藏的本质就是一个歌单,所以我们直接查看获取歌单所有音乐的API
说明 : 由于网易云接口限制,歌单详情只会提供 10 首歌,通过调用此接口,传入对应的歌单
id,即可获得对应的所有歌曲必选参数 :
id: 歌单 id
可以看到,我们还要把id搞到手,所以我们应该先看看用户的歌单,这就去看文档
说明 : 登录后调用此接口 , 传入用户 id, 可以获取用户歌单
必选参数 :
uid: 用户 id
这么说,我们还要用户的id(禁止套娃
那么这个id从哪来?
从“获取账号信息”来
说明 : 登录后调用此接口 ,可获取用户账号信息
接口地址 :
/user/account
所以,我们只要再反着套娃回去,然后稍加亿点数据处理的细节,就可以得到收藏音乐的列表了。
获取UID
res=requests.get(url="https://netease-cloud-music-cwl0bfvmk-totowang-hhh.vercel.app/user/account?cookie="+str(cookie)) json=res.json() uid=str(json['account']['id'])
获取用户歌单并截出收藏歌单的ID
res=requests.get(url="https://netease-cloud-music-cwl0bfvmk-totowang-hhh.vercel.app/user/playlist?limit=1&uid="+uid) json=res.json() favlstid=str(json['playlist'][0]['id'])
获取收藏歌单
res=requests.get(url="https://netease-cloud-music-cwl0bfvmk-totowang-hhh.vercel.app/playlist/track/all?id="+favlstid+"&cookie="+cookie) json=res.json()
数据整理
获得了收藏歌单之后,我们可以看看里面的信息有多全,每首歌的名字、id、专辑、封面、歌手……几乎你能在网易云里看到的信息都已经全了,我们当然不会浪费对吧,要榨干:)
for song in json['songs']: favlst.append(str(song['id'])) favnamelst.append(str(song['name'])) favallst.append(str(song['al']['name'])) favarlst.append([]) for ar in song['ar']: favarlst[json['songs'].index(song)].append(ar['name'])
然后我们就把这些信息整理到了好几个列表里面……(虽然这么做用处不大
下载
所以……怎么下载呢?
直接用外链肯定是不行的,不然我可能只能下载里面的一丢丢,这可是我无法接受的
欸,我们的收藏歌单咋来的来着?
网易云API是个好东西!
这部分思路很简单,我们只需要遍历歌单id,然后把id作为参数,对获取播放直链的API进行GET请求,再拿到音乐直链,然后直接再GET一次进行下载,就搞定了。
这样,理论上来讲,只要是你能播放的,都能下载!
不对……要实现你能播放的都能下载,那我们还得带个Cookie啊!嘿嘿我真是天才!
以下是下载部分的完整代码:
for mid in favlst: rpg('正在下载('+str(favlst.index(mid)+1)+'/'+str(len(favlst))+')',favnamelst[favlst.index(mid)],(favlst.index(mid)/len(favlst))*100) if not os.path.exists(path+'/'+favnamelst[favlst.index(mid)]+".mp3"):#避免重复下载 res=requests.get(url="https://netease-cloud-music-cwl0bfvmk-totowang-hhh.vercel.app/song/url?id="+mid+"&br=320000"+'&cookie='+cookie) json=res.json() murl=json['data'][0]['url'] res=requests.get(url=murl) m=res.content f=open(path+'/'+favnamelst[favlst.index(mid)]+".mp3",'wb') f.write(m) f.close()
界面和其他细节
虽然我们的数据处理搞完了(希望我强行拆散的这些代码跑起来没问题
但是!你不感觉等着不耐烦吗?
所以,进度条得整上!
为了避免程序员对#FF0000”这个颜色过于敏感,我在进度显示窗口里显示常见错误类型,还贴心地选用了比较淡的红“FF9090”作为背景
(不会真有人信我的这套鬼话吧
另外,为了自己顺眼,我把动画也整上了。
不过由于这部分代码过于分散