用 Python 制作音乐聚合下载器

用 Python 制作音乐聚合下载器,第1张

概述文|某某白米饭来源:Python技术「ID:pythonall」现在的音乐APP有很多,为了不下载很多的APP,所以咱用python做了一个聚合的音乐下载器,现在聚合了咪咕音乐、QQ音乐,下面是效果图安装需要安装一个辅助模块prettytable,用于美化控制台的表格输出pipinstallprettytable提取音

文 | 某某白米饭

来源:Python 技术「ID: pythonall」

现在的音乐APP有很多,为了不下载很多的APP,所以咱用python做了一个聚合的音乐下载器,现在聚合了咪咕音乐、QQ音乐,下面是效果图

安装

需要安装一个辅助模块 prettytable,用于美化控制台的表格输出

pip install prettytable
提取音乐链接搜索音乐

以下载 QQ 音乐为例,在首页(https://y.qq.com/) 上的搜索框中搜索 <<厚颜无耻>>, 打开 F12 的控制台面板,可以找到如下图的搜索链接,这个链接返回的是一个音乐列表的 Json 串

def get_request(self, url):    try:        headers = {            'User-Agent': 'Mozilla/5.0 (windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36'        }        response = requests.get(url, headers = headers)        if response.status_code == 200:            return response    except Exception as e:        print("请求出错:", e)    return Nonedef search_music(self, key):    # 20: 查询 20 条数据,key:关键字    url = 'https://c.y.qq.com/soso/fcgi-bin/clIEnt_search_cp?p=1&n=%d&w=%s' % (20, key)    resp = self.get_request(url)    resp_Json = Json.loads(resp.text[9:][:-1])    data_song_List = resp_Json['data']['song']['List']    song_List = []    for song in data_song_List:        singers = [s.get("name", "") for s in song.get("singer", "")]        song_List.append({'name': song['songname'], 'songmID': song['songmID'], 'singer': '|'.join(singers)})    return song_List

示例结果:

[{'name': '富士山下', 'songmID': '003dtkNk26WhJD', 'singer': '陈奕迅'}, {'name': '不要说话', 'songmID': '002B2EAA3brD5b', 'singer': '陈奕迅'}, ...., {'name': '最佳损友', 'songmID': '003hFxQh276Cv5', 'singer': '陈奕迅'}]
获取下载链接

把音乐列表页中的歌曲点击到播放音乐的页面,在控制面板找到多个以 m4a 结尾的音乐实际链接

它的参数部分有一个 vkey 的参数,把 vkey 当作关键字在 Network 面板中搜索,找到一个 musics.fcg 结尾的链接,vkey 的数据就在它返回的 Json 串中,另外的 purl 的值就是上面的 m4a 链接,最后将 https://ws.stream.qqmusic.qq.com 和 purl 拼凑成音乐链接,musics.fcg 链接中 guID 参数是一个随机数,songmID 参数是上面单个音乐的 songmID,uin 参数是 QQ 号

def download_url(self, song):    guID = str(random.randrange(1000000000, 10000000000))    purl_url = 'https://u.y.qq.com/cgi-bin/musicu.fcg?' \                '&data={"req":{"param":{"guID":" %s"}},' \                        '"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guID":"%s","songmID":["%s"],"uin":"%s"}},"comm":{"uin":%s}}' \                % (guID, guID, song['songmID'], 0, 0)    resp = self.get_request(purl_url)    if resp is None:        return 'N', 'None', '.m4a'    resp_Json = Json.loads(resp.text)    purl = resp_Json['req_0']['data']['mIDurlinfo'][0]['purl']    # 有些音乐在网站上不能听    if len(purl) < 1:        msg = 'N'    download_url = 'http://ws.stream.qqmusic.qq.com/' + purl    song_data = self.get_request(download_url)    if song_data:        msg = 'Y'    return msg, download_url, '.m4a'

示例结果:

只有一个域名的地址的下载链接表示这个音乐只能在客户端听,网页版听不了

到这里已经完了 QQ 音乐的搜索、抓取脚本,用同样的方式抓取咪咕音乐(http://m.music.migu.cn)做成咪咕音乐脚本,咪咕音乐更容易爬取

命令行主界面

主界面的主要功能就是以表格的方式显示搜索到的音乐和以序号的方式下载音乐

import osfrom qqMusic import QQMusicfrom miguMusic import MiGuMusicfrom prettytable import prettytableclass MusicBox(object):    def __init__(self):        pass    def download(self, data, songname, type):        save_path = 'music/' + songname + '.' + type        file = 'music'        if os.path.exists(file):            pass        else:            os.mkdir('music')        try:            print("{}下载中.....".format(songname), end='')            with open(save_path, 'wb') as f:                f.write(data)            print("已下载完成")        except Exception as err:            print("文件写入出错:", err)            return None    def main(self):        print('请输入需要下载的歌曲或者歌手:')        key = input()        print('正在查询..3[32mQQ音乐3[0m', end='')        qqMusic = QQMusic()        qq_song_List = qqMusic.main(key)        print('...3[31m咪咕音乐3[0m')        miguMusic = MiGuMusic()        migu_song_List = miguMusic.main(key)        qq_song_List.extend(migu_song_List)        song_dict = {}        for song in qq_song_List:            key = song['name'] + '\' + song['singer']            s = song_dict.get(key)            if s:                if s['msg'] != 'Y':                    song_dict[key] = song            else:                song_dict[key] = song        i = 0        table = prettytable(['序号', '歌手', '下载', '歌名'])        table.border = 0        table.align = 'l'        for song in List(song_dict.values()):            i = i + 1            table.add_row([str(i), song['singer'], song['msg'], song['name']])        print(table)        while 1:            print('\n请输入需要下载,按 q 退出:')            index = input()            if index == 'q':                return            song = List(song_dict.values())[int(index) - 1]            data = qqMusic.get_request(song['downloadUrl'])            if song['msg'] == 'Y':                self.download(data.content, song['name'], song['type'])            else:                print('该歌曲不允许下载')if __name__ == '__main__':    musicBox = MusicBox()    musicBox.main()
总结

音乐聚合下载器最重要的部分还是爬虫抓取各个音乐网站的数据,命令行的方式则省去了画 GUI 的工作。

总结

以上是内存溢出为你收集整理的用 Python 制作音乐聚合下载器全部内容,希望文章能够帮你解决用 Python 制作音乐聚合下载器所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1187955.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存