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

2023-11-11

1、引言

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

小屌丝:鱼哥,那赶紧的告诉我,咋搞嘞。
小鱼:我只告诉你一个人, 你不能外传哦。
小屌丝:必须的。

2、代码实战

2.1 思路

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

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

在这里插入图片描述

2.2 安装

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

  • requests
  • PySimpleGUI
  • retrying

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

pip install PySimpleGUI

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 使用 InlineKeyboardButton python telegram bot 发送命令

    在Python电报机器人中 是否有可能InlineKeyboardButton发送类似命令 cancel当它被按下时 例如 当用户按下取消按钮时 他们将自动发送 cancel 命令 然后由机器人处理 从这里的例子来看 https githu
  • 无法在我的 Django 项目中使用 Sphinx 生成自动文档

    我正在向我的 Django 项目添加文档 github链接 https github com augustakingfoundation queryjane app 该项目是开源的 使用sphinx 但是当尝试生成python文件的auto
  • 如何更改默认的Python版本?

    我已经在我的 Mac 上安装了 Python 3 2 我跑完之后 Applications Python 3 2 Update Shell Profile command 当我输入时 这很令人困惑Python V在终端它说Python 2
  • Keras ZeroDivisionError:整数除法或以零为模

    我正在尝试使用 Keras 和 Tensorflow 实现卷积神经网络 我有以下代码 from keras models import Sequential from keras layers import Conv2D MaxPoolin
  • 如何检索分配给 Django 中的组的所有权限

    我正在执行一项任务来检索分配给 Django 中的组的一组权限 我可以使用以下代码获取创建的组 但无法使用它来获取分配给它们的权限 from django contrib auth models import Group Permissio
  • 在 Jupyter Notebook 中设置环境变量的不同方法

    在某些情况下 我在 Windows 10 计算机上使用 Jupyter 笔记本 我想通过设置环境变量 GOOGLE APPLICATION CREDENTIALS 来向 GCP 进行身份验证 我想知道 这两种设置环境变量的方式有什么区别 当
  • 如何使用 python、openCV 计算图像中的行数

    我想数纸张 所以我正在考虑使用线条检测 我尝试过一些方法 例如Canny HoughLines and FLD 但我只得到处理过的照片 我不知道如何计算 有一些小线段就是我们想要的线 我用过len lines or len contours
  • 计算熊猫数据帧几个月的总和

    我有一个 pandas 数据框 如下所示 ID Year R1 R1 f KAR1 20201001 1 5 KAR1 20201101 2 6 KAR1 20201201 3 7 KAR1 20210101 4 8 KAR1 202102
  • 检查子字符串是否在字符串列表中?

    我之前已经找到了这个问题的一些答案 但它们对于当前的Python版本来说似乎已经过时了 或者至少它们对我不起作用 我想检查字符串列表中是否包含子字符串 我只需要布尔结果 我找到了这个解决方案 word to check or wordlis
  • 在 PhotoImage 下调整图像大小

    我需要调整图像大小 但我想避免使用 PIL 因为我无法使其在 OS X 下工作 不要问我为什么 无论如何 因为我对 gif pgm ppm 感到满意 所以 PhotoImage 类对我来说没问题 photoImg PhotoImage fi
  • Python 中 time.sleep 和多线程的问题

    我对 python 中的 time sleep 函数有疑问 我正在运行一个脚本 需要等待另一个程序生成 txt 文件 虽然 这是一台非常旧的机器 所以当我休眠 python 脚本时 我遇到了其他程序不生成文件的问题 除了使用 time sl
  • 打印一份拥有多个家庭的人员名单,每个家庭都有多个电话号码

    我有一类 Person 它可以有多个 Home 每个 Home 都有一个或多个电话号码 我已经定义了类 但现在我正在尝试创建一个视图 其中列出每个人的所有家庭以及每个家庭地址的所有电话号码 类似于 john smith 123 fake s
  • django 中的身份验证方法返回 None

    你好 我在 django 中做了一个简单的注册和登录页面 当想要登录时 登录视图中的身份验证方法不返回任何内容 我的身份验证应用程序 模型 py from django db import models from django contri
  • 错误:尝试使用 scrappy 登录时出现 raise ValueError("No element found in %s" % response)

    问题描述 我想从我大学的bbs上抓取一些信息 这是地址 http bbs byr cn http bbs byr cn下面是我的蜘蛛的代码 from lxml import etree import scrapy try from scra
  • 如何处理 Tkinter 中的窗口关闭事件?

    如何在 Python Tkinter 程序中处理窗口关闭事件 用户单击 X 按钮 Tkinter 支持一种称为协议处理程序 http web archive org web 20201111215134 http effbot org tk
  • 有没有办法拉伸整个显示图像以适应给定的分辨率?

    我最近一直在使用pygame制作游戏 遇到了一个小问题 基本上 我希望能够将屏幕上的整个图像 我已经传输到它的所有内容 拉伸到用户将窗口大小调整到的分辨率 我在 pygame 和堆栈溢出的文档中搜索了很多 但我似乎找不到答案 这可能吗 我的
  • 在 anaconda 环境下运行 qsub

    我有一个程序 通常在 Linux 的 conda 环境中运行 因为我用它来管理我的库 指令如下 source activate my environment python hello world py 我怎样才能跑你好世界 py在与 PBS
  • 在不同的 GPU 上同时训练多个 keras/tensorflow 模型

    我想在 Jupyter Notebook 中同时在多个 GPU 上训练多个模型 我正在使用 4GPU 的节点上工作 我想将一个 GPU 分配给一个模型并同时训练 4 个不同的模型 现在 我通过 例如 为一台笔记本选择 GPU import
  • 如何在 Qt 中以编程方式制作一条水平线

    我想弄清楚如何在 Qt 中制作一条水平线 这很容易在设计器中创建 但我想以编程方式创建一个 我已经做了一些谷歌搜索并查看了 ui 文件中的 xml 但无法弄清楚任何内容 ui 文件中的 xml 如下所示
  • 正则表达式 - 匹配不包含字符串的模式

    我对正则表达式很陌生 并且一直在寻找方法来做到这一点 但没有成功 给定一个字符串 我想删除以 abc 开头 以 abc 结尾且中间不包含 abc 的任何模式 如果我做 abc abc abc 它将匹配以 b 开头 以 abc 结尾并且中间包

随机推荐

  • AMD的CPU装androidstudio,以及联想拯救者r7000配置虚拟化无法使用解决

    第一步就是下载安装了 基操不提了 进入androidstudio会让你选择sdk下载 选择下载这都很快 毕竟没墙 但是在你导入项目或创建项目时 需要下载对应版本的gradle 这个时候你会发现下的贼慢还去时不时的断掉 一旦断了 就要重新下
  • jmeter模拟多用户并发

    一 100个真实的用户 1 一个账号模拟100虚拟用户同时登录和100账号同时登录 区别 1 1个账号100个人用 同时登录 2 100个人100个账号 同时登录 相同 1 两个都是100人同时登录 具体看项目需求 2 账号来源 1 利用
  • 最新Intellij Idea2020.01使用JDBC连接数据库

    最新Intellij Idea2020 01创建一个普通的Java工程并用JDBC连接数据库 详尽图文 Intellij Idea作为一款编程工具 自从尝到它的强大功能带来的甜头后 就再也不想用Eclipse来进行开发了 下面用它来演示一下
  • 异常处理使代码更稳健的案例

    package Java project 1 import java util Scanner public class Test public static void main String args Scanner sc new Sca
  • ubuntu 18.04 搭建 fisco bcos 联盟链2.8版本(一)

    安装centos依赖 sudo apt install y openssl curl 创建操作目录 下载安装脚本 可将下载脚本和更改权限分开执行 创建操作目录 cd mkdir p fisco cd fisco 下载脚本 curl LO h
  • 玩转科技

    目录 前言 特性 编辑 为什么需要 ChatBox ChatGPT Plus 平替 下载 支持系统 功能图 使用教程 感受 展示 前言 今天小编又来了 推荐给大家一款开源的OpenAI API桌面客户端ChatBox 它支持 Windows
  • guava之Immutable(不可变)集合

    一 概述 guava是google的一个库 弥补了java语言的很多方面的不足 很多在java8中已有实现 暂时不展开 Collections是jdk提供的一个工具类 Guava中不可变对象和Collections工具类的unmodifia
  • ng+php架构下websocket监听实例

    系统架构 nginx服务器 应用服务器 数据库 通过websocket监听应用服务器的8090端口 前端js发送websocket请求到ng服务器 ng服务器转发请求到应用服务器的8090端口 1 php后端设置websocket监听 ip
  • Python基础集(3)条件语句&循环

    日更 的 Born 与c语言不同 Python中的包含关系有缩进决定 4个缩进为一个单位 一 条件语句 因为if条件语句的逻辑性与我们的思维相似 所以这里就不再赘述了 下面我们直接来看条件语句的代码格式 注意点 if 条件 elif 条件
  • CSS超链接样式,去除下划线等

    控制超链接样式 链接的四种状态 a link 普通的 未被访问的链接 a visited 用户已访问的链接 a hover 鼠标指针位于链接的上方 a active 链接被点击的时刻 去除CSS超链接下划线 a link text deco
  • Django: TypeError topic() got an unexpected keyword argument 'topics_id'

    urls py coding utf 8 定义learning logs的URL模式 from django conf urls import url from import views urlpatterns 主页 url r views
  • 在浏览器中输入一个地址,回车后发生了什么?

    步骤 1 输入地址 2 缓存解析 3 DNS域名解析 4 TCP链接 三次握手 5 服务器收到请求 处理后返回请求 6 浏览器渲染 7 断开TCP链接 四次挥手 一 输入网址 在浏览器中输入要访问的url地址 回车发起请求 二 缓存解析 浏
  • C语言-有一对兔子。从出生后第三个月起每个月都生一对兔子,小兔子长到三个月后又生一对小兔子,假如兔子都不死,问每个月的兔子总数为多少。

    int i n unsigned int month 1 2 出生第一个月的兔子数量 unsigned int month 2 0 出生第二个月的兔子数量 unsigned int month 3 0 可以生娃的兔子的数量 一个月后的兔子数
  • python中使用try exception时,打印完整出错代码追踪

    使用python程序时 不使用try exception时 虽然能打印完整的出错代码追踪 但是会发生异常崩溃导致程序卡死 启用try exception后 一般也只能打印异常类型和异常信息 无法直接获取到出错代码行和代码追踪信息 找到的解决
  • Vue组件的基本概念与使用

    在Vue中 组件是构建用户界面的基本单元之一 它允许开发者将界面拆分为独立 可重用的模块 使代码更加结构化 易于维护 本文将从简单到复杂 全面介绍Vue组件的各种用法 优点 缺点以及注意事项 公众号 Code程序人生 个人网站 https
  • C++读取txt文件里每行的数据

    include
  • 画PCB步骤

    画PCB步骤 1 导入原理图器件 2 画PCB边界 板子画圆弧 首先在机械层 mechanical 画一个边界 如矩形 然后在四个角画上圆弧 最后再复制到阻焊层 keep out Layer 复制到阻焊层方法 shift s单层显示 最后分
  • 【论文笔记】ResNet 精读笔记

    Deep Residual Learning for Image Recognition ResNet论文精读视频讲解 0 Tips 图像卷积中的维度是指通道数 过拟合问题 训练集误差低 但验证集误差高 退化问题 随着网络深度的增加 训练集
  • 长连接的watch机制实现

    前言 对于于HTTP协议来说 服务端给一次响应后整个请求就结束了 这是HTTP请求最大的特点 也是由于这个特点 HTTP请求无法做到的是服务端向客户端主动推送数据 但由于HTTP协议的广泛应用 很多时候确实又想使用HTTP协议去实现实时的数
  • Python3,66行代码,搞了个音乐下载器,从此听歌再也不需要花费银子了,真香!

    66行代码敲出音乐下载器 1 引言 2 代码实战 2 1 思路 2 2 安装 2 3 示例 3 总结 1 引言 小屌丝 鱼哥 最近比较流行的那首歌 咋又说费了 小鱼 那你就冲个VIP呗 小屌丝 开玩笑 我的钱又不是大风刮过来的 小鱼 那你咋