啦啦啦终于有时间写啦!
2020最后一天!
QQ音乐、酷狗音乐、网易云音乐的下载器!
免登录免会员。
不过只限网页可听的音乐的标准音质。至于为啥,我猜其它歌曲根本就没有放在网页端上,因此无法通过爬虫获取(大概就是为了引导客户端下载+防爬虫8)
01
QQ音乐
一、基本路径
qq音乐的歌曲详情界面url形如 :
https://y.qq.com/n/yqq/song/abcdefghijklm.html
其中下划线部分为歌曲mid
即,QQ音乐用歌曲mid唯一表示一首歌曲,后续的操作将基于这个mid进行
点击播放,然后f12搜索一下(注:qq音乐的音频格式为m4a)
欸欸欸找到了?!
点进去——没错没错能听能下载!!就是它!!
然后突然意识到不对劲……
右键-源代码
果然没有……
审查元素里有不代表源代码里有啊!!怎么可能放在源代码里嘛!!!都放源代码里了难道要一个网页一个代码嘛!!!
大概只有我这种笨比小白会犯这种错了。。。
于是,只能分析这个链接了
链接形如:
长得还挺别致的
可以看出链接的基本格式是:
酱紫~
mid我们可以直接获得(因为是输入的),剩下就是guid、vkey、uin、fromtag了
然后在network里搜索mid……
找到了这个东西↓
点开
这个purl,就是我们要找的音乐链接的后半部分(甚至不用一个一个找参数了!)
因此,我们的任务变为:根据歌曲mid,获取到这个musics.fcg,然后从中提取出purl,加到
http://isure.stream.qqmusic.qq.com/ 后面,构造歌曲链接查看headers,这个musics.fcg的地址长这样:
地址的简化来自CSDN,其简单形式为:
该地址可用mid唯一确定
ok完事儿~~
然后就是,根据用户输入的歌曲详情页链接获取mid→根据mid获取purl→构造歌曲链接→歌曲get√
二、一些细节
1.文件名中歌手、歌名的获取
musics.fcg里并没有歌手和歌名的信息,但歌曲详情页(也就是需要用户输入链接的那个页面)里有
用bs4直接提取即可
同时,在歌曲详情页获取失败时,提供自行输入歌曲名和歌手名的方式构造文件名
2.下载路径
程序运行后会检测当前目录下有没有path.txt文档,若该文档存在,则音乐会被下载到文档所写的路径中,若该文档不存在,则下载到程序所在目录中
3.其它
按照惯例,使用了log.txt文件存储异常信息,防止程序本身报错
02
酷狗音乐
一、基本路径
酷狗音乐的歌曲url形如(酷狗音乐没有音乐详情页,但其播放页链接可以唯一确定歌曲):
https://www.kugou.com/song/#hash=abcdefghijklmnopqrstuvwxyz123456&album_id=12345678a
下划线部分是音乐所对应哈希值(hash),可以唯一标识一首歌曲,后面是专辑id
同样,源代码中并没有歌曲链接的相关信息,我们需要从审查元素中提取链接自行分析、构造
歌曲链接形如:
乱七八糟……看出开头是时间,最后是hash都能看得出来,但中间那一堆乱七八糟的就没辙了
于是,只能继续在network里搜
找到了这个东西↑
点开
竟然直接就可以得到歌曲链接!这样就不用自己构造了!
然后,我们再去看这个index.php的地址
emmmm……后面那一堆参数是什么鬼!!!尤其那个callback,让我上哪找去!!!
于是我以为这里有啥加密什么的,就跟这玩意耗了一个下午加一个晚上……
然后,万能的CSDN告诉我这玩意没用,随便找一个链接然后把hash和albunm_id填进去就行……
总之…………反正是搞出来了……
和上面一样,路径是:
根据用户输入的歌曲播放页链接获取hash和albunm_id→构造index.php的地址→获取歌曲链接→歌曲get√
二、一些细节
1.歌手、歌名的获取
酷狗音乐的歌手和歌名就放在index.php中,在获取歌曲链接时可以一同获取
2.歌曲链接的提取
qq音乐的musics.fcg是字典格式,可以直接通过eval(r.text)得到字典格式,然后通过键索引(json不熟就没用)
但在酷狗音乐的index.php中,开头有callback的内容(在字典外),且字典中的值“true” t为小写,若在python中直接转换为字典,会因为它既不是保留字也不是字符串而报错,因此直接使用了正则表达式匹配获取歌曲url
(当然其实可以直接把小写true替换为True,然后通过字典获取,但我觉得这样很傻X…)
3.下载路径和log.txt的设置同上
03
网易云音乐
话说在微信提网易会被屏蔽吗???
我是先知道网易云的歌曲链接(就是前面我们要想办法构造或获取的那个),然后才开始想写代码下载的。因此,网易云的路径和另两个有较大不同(但其实实质都是一样的)。
网易云的歌曲链接形如:
https://music.163.com/song/media/outer/url?id=[].mp3
其中id是每首歌的唯一标识
因此,我们去找歌曲详情页的链接,形如:
https://music.163.com/#/song?id=1234567890
ok,有id有歌曲链接格式了,完事~
本来应该是这样的才对……
但是,在我想提取歌手名和歌曲名时,发现源代码里根!本!没!有!
于是我去network里搜歌名,发现了一个神奇的东西
它长得很像一个正常的网页,且包含了歌手和歌曲信息。
这个地址是这样的:
https://music.163.com/song?id=[]
看出来有啥不对劲了吗??
这是歌曲详情页链接:
https://music.163.com/#/song?id=[]
这是我们刚刚在资源里搜出来的地址:
https://music.163.com/song?id=[]
只差了一个【#】!
当然……我那么瞎怎么可能看得出来……
于是我以为这个没有#的就是原本的那个地址,然后疑惑为什么这里返回的代码和原本(有#)的源代码不一样,顺便吐槽为啥网页也要套娃……
然后,还是万能的CSDN,告诉我这俩其实不一样……
也就是说,网易云用带#的“假链接”,把真实链接隐藏了,而且,即使在浏览器地址栏输入不带#的“真链接”,也会自动跳转到有#的版本。
就很神奇……
这样的设置,让我们无法直接通过网页获取到真实的代码和资源,因此也无法获取到歌曲链接了。
如果不是提前就知道这个链接,可能就真的很难办了……
那这个链接哪来的???
我去查了这个歌曲链接的来源,看了一些不同人写的教程(已经失效),推测可能是在网易云使用“假链接”之前,就使用这个地址存放歌曲,链接就是在这个时候被扒出来的。后来网易云虽然开始使用“假链接”了,但歌曲链接本身没有变,所以能够一直使用。
虽然通过浏览器进入没有#的链接会自动跳转到有#的,但这并不影响爬虫,我们只要把“真链接”还原出来,然后发送请求,从response里提取歌手名和歌名就可以了
最后,下载路径和log.txt的设置和上面一样04
结语
虽然写了蛮多的,其实代码实现上很简单,只是自己用的话也就十几行的事。
但是吧……谁让我总有些奇奇怪怪的想法……
程序毕竟是给不会写程序的人用的,功能的实现只是最基础的事,使用体验才是最重要的。我总希望自己写的东西能迎合各种各样的需求,能在出现异常时给出其它的解决路径而不是单纯地停止运行(一个运行到一半就停止的程序简直是在浪费生命!!),所以会在代码中加很多很多的东西。
最终的结果就是,本来十几行就够了的东西被我加到了一百多行……
但总之,我希望我做出来的东西可以用着舒服。
唔……
仅供学习和交流使用!
icon来自https://www.iconfont.cn/ (神仙网站!!)
点击【阅读原文】转到下载链接
提取码:jt1h
另外,无聊的时候写了个b站封面提取的东西↓
链接:
https://pan.baidu.com/s/1vnB3juoQAKZJSlov6N-3BQ
提取码:v42k
正在研究用电脑下载b站视频,希望能写出来……吧?
(python 有个you-get库(好像是这个名字8)可以下载好多视频软件的东西,有需求的可以试试)
就酱!
明年见~