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

news2024/10/6 12:34:42

66行代码敲出音乐下载器

  • 1、引言
  • 2、代码实战
    • 2.1 思路
    • 2.2 安装
    • 2.3 示例
  • 3、 总结

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技术。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/723573.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第2集丨JavaScript 中原型链(prototype chain)与继承

目录 一、一些基础概念1.1 ECMAScript 标准1.2 prototype和 __proto__1.3 constructor属性1.4 函数名 二、原型链的维护2.1 内部原型链和构造器原型链2.2 从实例回溯原型链2.3 修正原型指向 三、基于原型链的继承3.1 继承属性3.2 继承“方法” 四、构造函数4.1 案例一个简单的实…

SAP S4 Hana 财务凭证存储表变化

一、统一日记账的表 1. ACDOCA里有的&#xff0c;BSEG里不一定有 以下的一些凭证行项目&#xff0c;都是只在ACDOCA表里面存在&#xff0c;而在BSEG表里不存在的&#xff08;你可以通过BKPF表的BSTAT字段的凭证状态U来识别&#xff09;&#xff1a; 资产折旧过账 特定账套&am…

VMware Workstation虚拟机如何连接usb网卡

小伙伴不知道怎么将网卡链接到VMware虚拟机系统里面&#xff0c;因此今天我们就做一个简单的教程&#xff0c;教大家如何连接虚拟机使用&#xff1a; 1.插上usb网卡&#xff0c;然后如下图所示操作&#xff1a; 2.点击连接网卡到虚拟机之后&#xff0c;查询一下网卡是否识别到…

【JAVA程序员学C++】第二节、引用与指针,类型转换,结构体

一、指针与引用 1.1 指针 先说指针&#xff0c;由于java有jvm&#xff0c;所以对于java程序员&#xff0c;对于内存这一块关注就毕竟少了。但是C不同&#xff0c;C里面所有的堆内存&#xff0c;都需要程序员自己把控&#xff0c;把控不好&#xff0c;泄露了也是常有的事情。 …

Leetcode刷题笔记--Hot11-20

1--有效的括号&#xff08;20&#xff09; 主要思路&#xff1a; 利用栈&#xff0c;遍历字符串&#xff0c;遇到左括号则入栈&#xff0c;遇到右括号则出栈&#xff0c;并判断出栈元素是否与右括号匹配&#xff1b; 当字符串有效时&#xff0c;栈为空&#xff08;所有左括号都…

python语法 数据结构-字典和集合

文章目录 1. 字典1. 1. 字典特征1. 2. 创建字典1. 3.字典常用方法1.3.1 get()1.3.2 clear()1.3.3 copy()1.3.4 copy()1.3.4 update(key value)1.3.5 keys()、 values()和items() 1. 4. 获取字典值1. 4.1 通过 Key1. 4.2 通过迭代 1. 5. 列表与运算符 2. 集合2. 1. 元组特征2. …

NSS [HNCTF 2022 WEEK2]easy_include

NSS [HNCTF 2022 WEEK2]easy_include 过滤好多&#xff0c;试试日志包含。 服务器是nginx ?file/var/log/nginx/access.log 修改UA头为<?php system(‘ls’); ?> 修改UA头为<?php system(‘ls /’); ?> 修改UA头为<?php system(tac /ffflllaaaggg); ?&g

word2vec工具实战(使用gensim)

最开始需要新建一个conda环境 conda create -n word2vec python3.8 conda activate word2vec然后安装一下所需要的库 pip install numpy pip install scipy pip install gensim pip install jieba首先下载一下数据集zhwiki-20230701-pages-articles.xml.bz2&#xff0c;为了方…

数据库如何建表

MySQL数据库建表过程 目录 创建并使用数据库 第一步&#xff1a;打开命令行 第二步&#xff1a;运行MySQL 第三步&#xff1a;建立数据库以及表数据 创建表时约束条件 约束类型 其他SQL语句 MySQL命令行导入导出数据库 创建并使用数据库 第一步&#xff1a;打开命令…

帧内帧间预测实验

帧内帧间预测实验 文章目录 帧内帧间预测实验帧间预测配置opencv 帧内预测解决jupyter notebook无法找到虚拟环境的问题 帧间预测 配置opencv .h文件是头文件&#xff0c;包含了类、函数、变量的声明&#xff0c;用于在源代码文件中引用和访问这些声明。头文件通常包含函数和…

【OpenCV • c++】图像几何变换 | 图像坐标映射

&#x1f680; 个人简介&#xff1a;CSDN「博客新星」TOP 10 &#xff0c; C/C 领域新星创作者&#x1f49f; 作 者&#xff1a;锡兰_CC ❣️&#x1f4dd; 专 栏&#xff1a;【OpenCV • c】计算机视觉&#x1f308; 若有帮助&#xff0c;还请关注➕点赞➕收藏&#xff…

基于PyQt5的桌面图像调试仿真平台开发(12)图像灰度显示

系列文章目录 基于PyQt5的桌面图像调试仿真平台开发(1)环境搭建 基于PyQt5的桌面图像调试仿真平台开发(2)UI设计和控件绑定 基于PyQt5的桌面图像调试仿真平台开发(3)黑电平处理 基于PyQt5的桌面图像调试仿真平台开发(4)白平衡处理 基于PyQt5的桌面图像调试仿真平台开发(5)…

BUU [网鼎杯 2020 青龙组]AreUSerialz

BUU [网鼎杯 2020 青龙组]AreUSerialz 先看题目&#xff0c;是个php反序列化。源码如下。 <?phpinclude("flag.php");highlight_file(__FILE__);class FileHandler {protected $op;protected $filename; protected $content;function __construct(…

Ceph:关于 Ceph 中 BlueStore 架构以及 OSD 创建的一些笔记

写在前面 准备考试&#xff0c;整理ceph 相关笔记内容涉及&#xff1a;Blue Store OSD 存储引擎介绍&#xff0c;对应 OSD 的不同创建方式理解不足小伙伴帮忙指正 对每个人而言&#xff0c;真正的职责只有一个&#xff1a;找到自我。然后在心中坚守其一生&#xff0c;全心全意&…

FreeCAD 3D绘图教程

推荐&#xff1a;将 NSDT场景编辑器 加入你的3D开发工具链 构建现实世界 FreeCAD主要用于为现实世界设计对象。您在FreeCAD中所做的一切都使用现实世界的单位&#xff0c;无论是微米&#xff0c;公里&#xff0c;英寸还是英尺&#xff0c;甚至是单位的任意组合。FreeCAD提供了…

FreeRTOS实时操作系统(十)信号量

系列文章目录 文章目录 系列文章目录信号量二值信号量二值信号量API函数创建二值信号量函数释放二值信号量函数获取二值信号量函数 实验测试 计数型信号量计数型信号量API函数动态创建函数信号量计数值获取函数 实验测试 优先级反翻转实验测试 互斥信号量API函数实验测试 信号量…

深兰科技与韩国EVERYBOT集团签署服务机器人出口订单

7月4日&#xff0c;在深兰科技集团上海总部&#xff0c;韩国EVERYBOT Inc.集团与深兰科技智胜(上海)科技有限公司签署了服务机器人出口订单及韩国市场战略合作协议。根据协议&#xff0c;EVERYBOT将从深兰科技订购首批服务机器人&#xff0c;同时成为深兰科技各类服务机器人产品…

Layui如何给lay-data插入按钮呢?如何通过按钮获取Id值呢?

&#x1f607;作者介绍&#xff1a;一个有梦想、有理想、有目标的&#xff0c;且渴望能够学有所成的追梦人。 &#x1f386;学习格言&#xff1a;不读书的人,思想就会停止。——狄德罗 ⛪️个人主页&#xff1a;进入博主主页 &#x1f5fc;推荐系列&#xff1a;点击进入 &#…

机器学习实战:Python基于NN神经网络进行分类(十一)

文章目录 1 前言1.1 神经网络的介绍1.2 神经网络的应用 2. Tensorflow实战演示2.1 导入函数2.2 导入数据2.3 数据预处理2.4 建立神经网络2.5 训练模型2.6 评估模型2.7 预测 3. 讨论 1 前言 神经网络&#xff08;Neural network&#xff0c;NN&#xff09;机器学习是一种基于人…

【动态规划算法】第五题:62.不同路径

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树 &#x1f389;作者宣言&#xff1a;认真写好每一篇博客 &#x1f38a;作者gitee:gitee &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法 如 果 你 喜 欢 作 者 的 文 章 &#xff0c;就 给 作…