网易云音乐下载器

简介: 网易云音乐下载器

全部代码

import os
import json
import requests
from tkinter import *
 
 
class couldmusic(object):
 
    def __init__(self, tk_root):
        """初始化"""
 
        self.root = tk_root
 
        self.playlist_id = StringVar()                                          # 歌单ID,可以通过网易云歌单详情页面获地址栏取
        self.song_id = StringVar()                                              # 歌曲ID,可以通过歌曲播放页面地址栏获取
        self.song_name = StringVar()                                            # 歌曲名字,用于显示下载信息
        self.song_name.set("")
        self.var = StringVar()                                                  # 下载进度值
        self.var.set("开始")
 
        self.index = 0
 
        self.song_list = {}
        self.save_path = os.path.abspath(".")                                   # 获取工作目录
        self.save_path = os.path.join(self.save_path, "网易云音乐")             # 生成网易云音乐文件夹路径
 
        # 浏览器Headers信息
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36",
            }
 
        # 绘制UI
        self.layout()
 
    def process(self):
        """下载进度条"""
 
        total_length = 260                                                      # 进度条总长度
        if len(self.song_list) > 0:                                             # 判断歌曲列表非空
            length = total_length * self.index / len(self.song_list)            # 计算下载进度长度
            self.canvas.coords(self.processbar, (0, 0, length,26))              # 创建进度条(起始X坐标,起始Y坐标, 长度,高度)
            self.var.set(f"{self.index}/{len(self.song_list)}")                 # 设定进度值
            if length == total_length:                                          # 判断是否下载完成
                self.song_name.set("下载完成")
        self.root.update()
 
    def reset(self):
        """重置"""
 
        self.song_id.set("")
        self.playlist_id.set("")
        self.song_list.clear()
        self.var.set("开始")
        self.index = 0
        self.save_path = os.path.abspath(".")
        self.save_path = os.path.join(self.save_path, "网易云音乐")
 
    def get_playlist(self, playlist_id):
 
        playlist_api = "http://music.163.com/api/playlist/detail?id="           # 歌单详情API
        playlist_url = playlist_api + playlist_id                               # 获取歌单详情地址
 
        r = requests.get(playlist_url, headers = self.headers)                  # 获取源码
        json_data = json.loads(r.text)                                          # 源码转换Json格式
         
        # 尝试提取指定信息
        try:
            song_list_name = json_data['result']['creator']['nickname']         # 提取歌单名字
            self.song_name.set(f"{song_list_name} 的歌单")
            self.save_path = os.path.join(self.save_path, song_list_name)       # 生成歌单文件路径
            if not os.path.isdir(self.save_path):                               # 判断路径是否存在
                os.mkdir(self.save_path)                                        # 创建歌单文件夹
        except:
            self.song_name.set("请输入有效的歌单ID或歌曲ID")
            return
 
        # 提取歌曲信息
        for i in json_data['result']['tracks']:
            song_name = i["name"].split("/")[0]                                 # 获取歌曲名字,并移除 "/"
            song_id = i['id']                                                   # 获取歌曲ID信息
            self.song_list[song_name] = song_id                                 # 将歌曲信息加入到字典备用
 
        return song_list_name
 
    def get_song_info(self, song_id):     
        """获取单首歌曲信息"""   
 
        song_detail_api = "http://music.163.com/api/song/detail/?id=song_id&ids=%5Bsong_id%5D"      # 歌曲信息API
        song_url = song_detail_api.replace("song_id", self.song_id.get())                           # 生成歌曲信息Url
 
        r = requests.get(song_url, headers = self.headers)                      # 获取源码
        json_data = json.loads(r.text)                                          # 源码转换Json格式
 
        # 尝试提取指定信息
        try:             
            for i in json_data['songs']:                                        # 获取Json_data中 ‘songs’内容
                self.song_list[i['name']] = self.song_id.get()                  # 将歌曲信息加入到字典备用
        except:
            self.song_name.set("请输入有效的歌单ID或歌曲ID_2")                                                   
 
    def download(self):
        """下载 "self.song_list" 中歌曲"""
 
        api = "http://music.163.com/song/media/outer/url?id=song_id.mp3"
        # api = "https://www.apicp.cn/API/wyy/api.php?id="                        # 网易云解析API, 第三方提供
        self.index = 0
         
        for item in self.song_list:                                             # 遍历歌曲列表
            self.index += 1                                                     # 歌曲次序
            song_url = api.replace("song_id", str(self.song_list[item]))             # 解析地址
            name = item + ".mp3"                                                # 歌曲名字
            split_list = ["<", ">", "/", "\\"]                                  # Windows名字机制,移除特殊字符
            for x in split_list:
                name = name.split(x)[0]                                           
            path = os.path.join(self.save_path, name)                           # 歌曲保存路径
            self.song_name.set(name)                                            # 更新UI信息
            content = requests.get(song_url, headers = self.headers).content    # 获取源码
            if content[0] != 0x49:                                              # 判断返回值是否属于音频文件
                self.song_name.set("灰色歌曲无法下载")                           # 灰色歌曲无法下载
                continue                                                        # 跳出本次循环
            if not os.path.isfile(path):                                        # 判断文件是否存在
                with open(path, "wb") as f:                                     # 保存文件
                    f.write(content)
            self.process()                                      
 
    def run(self):
        """获取输入信息, 并执行程序"""
 
        playlist_id = self.playlist_id.get()                                    # 获取页面输入歌单ID信息
        song_id = self.song_id.get()                                            # 获取页面输入歌曲ID信息
 
        if not os.path.isdir(self.save_path):                                   # 判断路径是否存在  
            os.mkdir(self.save_path)                                            # 创建文件夹
 
        # 判断输入歌单ID和歌曲ID有效
        if playlist_id == "" and song_id == "":                                 # 判断歌单/歌曲非空
            self.song_name.set("请输入有效的歌单ID或歌曲ID_1")                     
            return       
        elif playlist_id:                                                       # 歌单ID非空,执行歌单处理函数
            self.get_playlist(playlist_id)
        elif song_id:                                                           # 歌曲ID非空,执行歌曲处理函数
            self.get_song_info(song_id)
 
        self.download()                                                         # 执行歌曲下载函数
        self.reset()                                                            # 重置
 
    def layout(self):
        """绘制界面"""
 
        self.root.title("网易云下载器")                                          # 标题
        self.root.geometry("260x100+600+300")                                   # 位置
        self.root.bind("<Return>", lambda x:self.run())                         # 绑定回车键
 
        # 歌单ID
        Label(self.root, text = "歌单ID:").grid(row = 0, column = 0)
        Entry(self.root, textvariable = self.playlist_id).grid(row = 0, column =1, sticky=N+E+S+W)
         
        # 歌曲ID
        Label(self.root, text = "歌曲ID:").grid(row = 1, column =0)
        Entry(self.root, textvariable = self.song_id).grid(row = 1,column = 1, sticky=N+E+S+W)
 
        # 正在下载的歌曲信息
        Label(self.root, text = "正在下载:").grid(row = 2, column =0)
        Entry(self.root, textvariable = self.song_name).grid(row = 2,column = 1, sticky=N+E+S+W)
 
        # 进度条
        self.canvas = Canvas(self.root,height=26, bg="white")
        self.canvas.grid(row = 3,  column = 1)
        self.processbar = self.canvas.create_rectangle(0,0,0,0,width = 0,fill = "green")
 
        # 开始
        Button(self.root, textvariable = self.var, command = self.run).grid(row = 3, column = 0, sticky=N+E+S+W)
 
 
if __name__ == "__main__":
    root = Tk()
    couldmusic(root)
    root.mainloop()
相关文章
|
搜索推荐 JavaScript 前端开发
Gmail邮箱API发送邮件的方法有什么
使用Gmail API发送邮件,需先获取API访问权限,包括在Google Cloud Platform上创建项目,启用Gmail API,生成API密钥或OAuth 2.0凭据。然后,用Python等编程语言设置API请求,指定邮件详情。发送简单邮件涉及创建Base64编码的消息体,而带附件的邮件需编码为multipart格式。可添加邮件头信息,并处理发送结果以确保成功。Gmail API使应用能集成自动化、个性化的邮件发送功能,提升效率和体验。
|
存储 区块链 CDN
推荐几个免费好用的图床
图床一直以来都是很多人的刚性需求,无论是站长,还是平时逛论坛、写博客的用户,再或者是做外贸生意都可能需要用到图床。好用的图床提供了长期稳定存储且高访问能力的图片托管能力,这也是大家选择图床的核心因素。所以在这里我推荐几款免费且超好用的图床。
1152 0
|
存储 Web App开发 缓存
CleanMyMac X安全吗?及优缺点测评简述
如果Mac 电脑经常卡机、死机、速度很慢,跳出“存储过满”等问题,那么就需要用到世界上最受欢迎的电脑清理软件之一CleanMyMac X,它提供免费试用版,会告诉您可以释放多少磁盘空间,使用更多功能的完整版更能优化和保护 Mac 计算机,让速度大大提升。网上对CleanMyMac X的评论有的超级正面,有的超级负面,甚至有的“专家”说它是流氓软件,然后我们从实际出发,在测评这款清理软件之后,我们100% 支持它,因为它真的效果好,确实比市面上任何Mac 清理软件好用,价格不是最便宜的,但值得拥有,它在清理文件、改善隐私、删除垃圾或恶意软件以及提高设备的使用寿命和保持性能方面创造了奇迹。
2476 0
|
存储 人工智能 弹性计算
从“云+原神”到“云上星穹”,阿里云支持米哈游新游全球首发
近日,阿里云支持米哈游新作《崩坏:星穹铁道》正式上线,首发当天全网下载量突破2000万,当日登上iOS免费榜与畅销榜的总榜第一及其他多国榜首。
|
安全 网络安全 网络架构
【揭秘】大佬如何玩转内网与外联单位互访?SNAT+DNAT实战揭秘,让你的网络畅通无阻!
【8月更文挑战第19天】内网与外联单位间的访问是企业网络的关键需求。通过SNAT和DNAT技术可巧妙解决此问题。SNAT修改源IP地址,隐藏内网真实身份;DNAT改变目的IP地址,实现外部对内网服务器的访问。
362 0
零撸游戏广告变现模式系统开发部署源码搭建
零撸游戏广告变现模式系统开发部署源码搭建
网易云/opt/netease/netease-cloud-music/netease-cloud-music: symbol lookup error: /lib/x86_64-linux-gnu/
网易云/opt/netease/netease-cloud-music/netease-cloud-music: symbol lookup error: /lib/x86_64-linux-gnu/
248 0
|
存储 Web App开发 缓存
PWA 实践/应用(Google Workbox)
PWA(Progressive Web App – 渐进式网页应用)是一种理念,由 Google Chrome 在 2015 年提出。PWA 它不是特指某一项技术,而是应用多项技术来改善用户体验的 Web App,其核心技术包括 Web App Manifest、Service Worker、Web Push 等,用户体验才是 PWA 的核心。
3479 1
PWA 实践/应用(Google Workbox)
|
JavaScript 开发工具 git
将vue项目打包成电脑端应用.exe
将vue项目打包成电脑端应用.exe
将vue项目打包成电脑端应用.exe