Python3,66行代码,搞了个音乐下载器,从此听歌再也不需要花费银子了,真香!

举报
Carl_奕然 发表于 2023/07/12 12:04:26 2023/07/12
【摘要】 网友:以后还需要啥播放器, 根本不需要。

1、引言


小云:鱼哥,最近比较流行的那首歌, 咋又说费了。
小鱼:那你就冲个VIP呗。
小云:开玩笑, 我的钱又不是大风刮过来的。
小鱼:那你咋的,还想白嫖?
小云:(⊙o⊙)… 果然鱼哥了解我。
小鱼:…不行的,不行的, 咱要支持正版版权的。
小云:我也没说不支持版权啊。
小鱼:那你还想白嫖?
小云:我就想着,换一种方式,支持版权。
小鱼:我去,别骗我。
小云:真的,我想鱼哥你能想到。
小鱼:我…想不到。
小云:别闹。 还有你想不到的, 你当我是小孩子啊。
小鱼:嘿嘿。

在这里插入图片描述
小云:鱼哥,那赶紧的告诉我,咋搞嘞。
小鱼:我只告诉你一个人, 你不能外传哦。
小云:必须的。

2、代码实战


2.1 思路


因为要 生成播放器, 且需要自动播放下载的音乐。 所以:

  • 首先:电脑磁盘需要有足够的空间;
  • 其次:需要安装一些第三方库,
  • 第三:GUI实现下载音乐到指定文件夹下。
  • 第四:喝着黑桃A,听着下载的歌。

在这里插入图片描述
2.2 安装


这里需要第三方库,如下:

  • requests
  • PySimpleGUI
  • retrying


这里,我看可以逐个安装,也可以批量安装,
我只展示PySimpleGUI库的安装,

pip install PySimpleGUI



其余安装方式,可以参照这两篇:

  • 《Python3,选择Python自动安装第三方库,从此跟pip说拜拜!!》
  • 《Python3:我低调的只用一行代码,就导入Python所有库!》


安装完成,就可以进行代码编写了。

2.3 示例

# -*- coding:utf-8 -*-
# @Time   : 2023-07-06
# @Author : Carl_DJ

'''
实现功能:
    实现GUI 音乐下载器。
'''

import os
import tkinter as tk
import webbrowser
import requests
import tkinter.messagebox as ms_box
import PySimpleGUI as sg
from tkinter import  ttk
from retrying import retry


class SetMusicUI(object):
    """
    设置音乐弹框界面
    """
    def __init__(self, weight=900, height=600):
        self.ui_weight = weight
        self.ui_height = height
        self.title = "音乐下载器_Demo"
        self.ui_root = tk.Tk(className=self.title)
        self.ui_url = tk.StringVar()
        self.ui_var = tk.IntVar()
        self.ui_var.set(1)
        self.show_result = None
        self.song_num = None
        self.response_data = None
        self.song_url = None
        self.song_name = None
        self.song_author = None

    def set_ui(self):
        """
        设置音乐下载器UI界面
        """
        # Frame空间
        frame_1 = tk.Frame(self.ui_root)
        frame_2 = tk.Frame(self.ui_root)
        frame_3 = tk.Frame(self.ui_root)
        frame_4 = tk.Frame(self.ui_root)

        # ui界面中菜单设计
        ui_menu = tk.Menu(self.ui_root)
        self.ui_root.config(menu=ui_menu)
        file_menu = tk.Menu(ui_menu, tearoff=0)
        ui_menu.add_cascade(label='菜单', menu=file_menu)
        # file_menu.add_command(label='使用说明', command=lambda: webbrowser.open('www.baidu.com'))
        # file_menu.add_command(label='关于作者', command=lambda: webbrowser.open('www.baidu.com'))
        file_menu.add_command(label='退出', command=self.ui_root.quit)

        # 控件内容设置
        choice_passageway = tk.Label(frame_1, text='你想要的音乐,这里都有:', padx=15, pady=15)
        # passageway_button_1 = tk.Radiobutton(frame_1, text='酷我', variable=self.ui_var, value=1, width=10, height=3)
        # passageway_button_2 = tk.Radiobutton(frame_1, text='网易云', variable=self.ui_var, value=2, width=10, height=3)
        # passageway_button_3 = tk.Radiobutton(frame_1, text='QQ音乐', variable=self.ui_var, value=3, width=10, height=3)
        # passageway_button_4 = tk.Radiobutton(frame_1, text='酷我', variable=self.ui_var, value=4, width=10, height=3)
        input_link = tk.Label(frame_2, text="请输入歌曲名或歌手:")
        entry_style = tk.Entry(frame_2, textvariable=self.ui_url, highlightcolor='Fuchsia', highlightthickness=1,
                               width=35)
        label2 = tk.Label(frame_2, text=" ")
        play_button = tk.Button(frame_2, text="搜索", font=('黑体', 10),  width=2, height=1,
                                command=self.get_KuWoMusic)
        label3 = tk.Label(frame_2, text=" ")
        # 表格样式
        columns = ("序号", "歌手", "歌曲", "专辑")
        self.show_result = ttk.Treeview(frame_3, height=20, show="headings", columns=columns)
        # 下载
        download_button = tk.Button(frame_4, text="下载", font=('黑体', 11),  width=6, height=1, padx=5,
                                    pady=5, command=self.download_music)

        # 控件布局
        frame_1.pack()
        frame_2.pack()
        frame_3.pack()
        frame_4.pack()
        choice_passageway.grid(row=0, column=0)
        # passageway_button_1.grid(row=0, column=1)
        # passageway_button_2.grid(row=0, column=2)
        # passageway_button_3.grid(row=0, column=3)
        # passageway_button_4.grid(row=0, column=4)
        input_link.grid(row=0, column=0)
        entry_style.grid(row=0, column=1)
        label2.grid(row=0, column=2)
        play_button.grid(row=0, column=3, ipadx=10, ipady=10)
        label3.grid(row=0, column=4)
        self.show_result.grid(row=0, column=4)
        download_button.grid(row=0, column=5)

        # 设置表头
        self.show_result.heading("序号", text="序号")
        self.show_result.heading("歌手", text="歌手")
        self.show_result.heading("歌曲", text="歌曲")
        self.show_result.heading("专辑", text="专辑")
        # 设置列
        self.show_result.column("序号", width=100, anchor='center')
        self.show_result.column("歌手", width=200, anchor='center')
        self.show_result.column("歌曲", width=200, anchor='center')
        self.show_result.column("专辑", width=300, anchor='center')

        # 鼠标点击
        self.show_result.bind('<ButtonRelease-1>', self.get_song_url)

    @retry(stop_max_attempt_number=5)
    def get_KuWoMusic(self):
        """
        获取某音乐平台的音乐

        """
        # 清空treeview表格数据
        for item in self.show_result.get_children():
            self.show_result.delete(item)
        headers = {
            'accept': 'application/json, text/plain, */*',
            'accept - encoding': 'gzip, deflate',
            'accept - language': 'zh - CN, zh;q = 0.9',
            'cache - control': 'no - cache',
            'Connection': 'keep-alive',
            'csrf': 'HH3GHIQ0RYM',
            'Referer': 'http://www.xxxx.cn',
            'User-agent': '填写自己的User-agent信息',
            'Cookie': '填写自己的cookie信息'
        }
        search_input = self.ui_url.get()
        if len(search_input) > 0:
            #输入目标地址
            search_url = 'http://www.xxx.cn'
            search_data = {
                'key': search_input,
                'pn': '1',
                'rn': '80',
                'httpsStatus': '1',
                'reqId': 'xxxxx'  #填写自己获取的requestId
            }
            try:
                self.response_data = requests.get(search_url, params=search_data, headers=headers, timeout=20).json()
                songs_data = self.response_data['data']['list']
                if int(self.response_data['data']['total']) <= 0:
                    ms_box.showerror(title='错误', message='搜索: {} 不存在.'.format(search_input))
                else:
                    for i in range(len(songs_data)):
                        self.show_result.insert('', i, values=(i + 1, songs_data[i]['artist'], songs_data[i]['name'],
                                                               songs_data[i]['album']))
            except TimeoutError:
                ms_box.showerror(title='错误', message='搜索超时,请重新输入后再搜索!')
        else:
            ms_box.showerror(title='错误', message='请输入歌曲或歌手信息,再进行搜索!')

    def get_song_url(self, event):
        """
        获取下载歌曲的地址
        """
        # treeview中的左键单击
        for item in self.show_result.selection():
            item_text = self.show_result.item(item, "values")
            # 获取
            self.song_num = int(item_text[0])
        # 获取下载歌曲的地址
        if self.song_num is not None:
            songs_data = self.response_data['data']['list']
            songs_req_id = self.response_data['reqId']
            song_rid = songs_data[self.song_num - 1]['rid']
            music_url = '路径地址'.format(song_rid, songs_req_id)
            response_data = requests.get(music_url).json()
            self.song_url = response_data['data'].get('url')
            self.song_name = songs_data[self.song_num - 1]['name']
            self.song_author = songs_data[self.song_num - 1]['artist']
        else:
            ms_box.showerror(title='错误', message='请选择要下载的歌曲')

    def download_music(self):
        """
        下载音乐
        """
        if not os.path.exists('./data/Music'):
            os.mkdir("./data/Music/")
        if self.song_num is not None:
            song_name = self.song_name + '--' + self.song_author + ".mp3"
            try:
                save_path = os.path.join('./data/Music//{}'.format(song_name)) \
                    .replace('\\', '/')
                true_path = os.path.abspath(save_path)
                resp = requests.get(self.song_url)
                with open(save_path, 'wb') as file:
                    file.write(resp.content)
                    ms_box.showinfo(title='下载成功', message='歌曲:%s,保存地址为%s' % (self.song_name, true_path))
            except Exception:
                ms_box.showerror(title='错误', message='未找到存放歌曲的文件夹')
        else:
            ms_box.showerror(title='错误', message='请先选择歌曲,再进行下载')

    def progress_bar(self, file_size):
        """
        任务加载进度条
        :return:
        """
        layout = [[sg.Text('任务完成进度')],
                  [sg.ProgressBar(file_size, orientation='h', size=(40, 20), key='progressbar')],
                  [sg.Cancel()]]

        # window只需将自定义的布局加载出来即可 第一个参数是窗口标题。
        window = sg.Window('机器人执行进度', layout)
        # 根据key值获取到进度条
        _progress_bar = window['progressbar']
        for i in range(file_size):  # 循环
            event, values = window.read(timeout=10)
            if event == 'Cancel' or event is None:
                break
            _progress_bar.UpdateBar(i + 1)

    def ui_center(self):
        """
        UI界面窗口设置:居中
        """
        ws = self.ui_root.winfo_screenwidth()
        hs = self.ui_root.winfo_screenheight()
        x = int((ws / 2) - (self.ui_weight / 2))
        y = int((hs / 2) - (self.ui_height / 2))
        self.ui_root.geometry('{}x{}+{}+{}'.format(self.ui_weight, self.ui_height, x, y))

    def User_loop(self):
        """
        函数说明:loop等待用户事件
        """
        self.ui_root.resizable(False, False)  # 禁止修改窗口大小
        self.ui_center()  # 窗口居中
        self.set_ui()
        self.ui_root.mainloop()

if __name__ == '__main__':
    RunMusicUI = SetMusicUI()
    RunMusicUI.User_loop()


运行结果:

—>我没有输入任何信息,直接点击搜索按钮,如下图。

在这里插入图片描述
3、 总结


看到这里,今天的内容差不多就该结束了。
今天主要进行了一个音乐下载器的分享。

声明:
本次代码展示一个简单的音乐下载器, 切勿商用!
如果出现任何商业行为,都与本人(小鱼)无关。

我是小鱼

  • CSDN 博客专家;
  • 阿里云 专家博主;
  • 51CTO博客专家;
  • 51认证讲师等;
  • 认证金牌面试官;
  • 职场面试及培训规划师;
  • 多个国内主流技术社区的认证专家博主;
  • 多款主流产品(阿里云等)测评一、二等奖获得者;


关注我,带你学习更多更专业更前言的Python技术。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。