在电脑D盘新建一个【安迪笔记】文件夹。
【安迪笔记】文件夹里新建【2.爬虫笔记】文件夹。
【2.爬虫笔记】文件夹里新建【5.vip音乐爬虫】文件夹。
【5.vip音乐爬虫】文件夹里新建【5.vip音乐下载器.py】文件。
我用vscode编辑器打开【安迪笔记】文件夹。
vscode打开的文件夹决定了相对路径,这一步要重点关注。
【备注】
我写笔记需要用到【安迪笔记】里的其他资料,为了笔记方便,我才建了这么多文件夹 。
因为有太多太多的同学找不到最终输出的文件,所以我对建文件夹和py文件做了详细说明。
如果你能掌握绝对路径的知识,能找到输出的文件,直接建py文件写即可。
【程序需要导入的所有库】
import os
import tkinter as tk
import webbrowser
import requests
import tkinter.messagebox as mes_box
import PySimpleGUI as sg
from tkinter import ttk
from retrying import retry
os是Python的内置库,不需要额外安装。
os库提供了一系列与操作系统交互的函数。
包括文件操作、进程管理、环境变量等。
通过os库,可以实现对文件、目录、进程等的操作,方便程序的编写和管理。
tkinter:图形界面。
tkinter是Python的内置库,不需要额外安装。
它是一个图形用户界面(GUI)工具包。
可以用于创建窗口、按钮、标签、文本框等各种界面元素,以及实现用户与程序的交互。
它是Python中最常用的GUI库之一,适用于开发桌面应用程序。
webbrowser:网页浏览器。
webbrowser 是Python的内置库,不需要额外安装。
webbrowser 库的作用是打开一个浏览器窗口,并在其中显示指定的URL地址。
它提供了一种简单的方法来在Python程序中打开网页、查看文档、播放视频等。
例如,可以使用 webbrowser.open()
函数来打开一个指定的URL地址,如下所示:
【代码示例】
# 1. 导入webbrowser库
import webbrowser
# 2. 定义一个url变量
url = 'https://www.baidu.com'
# 3.打开百度网页
webbrowser.open(url)
【终端输出】
True
【代码解析】
webbrowser库名。
库名和函数之间有一个英文小圆点.
。
open函数名。
url是参数,即要打开的网页。
【返回值】
True
返回True
表示打开网页成功。
【效果】
运行上面的代码,我的360浏览器会自动打开百度网站。如下图所示:
【调用模块或库中的函数语法】
调用模块或库的函数:模块名.函数名()
,如 os.mkdir()
requests 是第三方库,需要安装。
【pip安装requests库的方法】
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ requests
【安装语法解析】
关键字pip
安装命令关键字install
install[ɪnˈstɔːl]:安装。
-i
后面表示要接的是镜像源。
下面的链接是清华大学镜像源。
https://pypi.tuna.tsinghua.edu.cn/simple/
requests
。【安装第3方库可参考下面的链接】
73. python第三方库安装教程(超详细)
【备注】
因为这个库我已经安装过了,这里不做图片展示。后面有安装的库图片展示,不懂的请参考后文。
【requests库的作用】
requests库的作用是发送HTTP请求,并处理响应。
它可以发送GET、POST、PUT、DELETE等请求,支持HTTPS、Cookie、Session等功能。
还可以处理JSON、XML等格式的数据。
requests 库简化了HTTP请求的操作,使得Python程序可以更方便地与Web服务器进行交互。
PySimpleGUI 是第三方库,需要安装。
【pip安装库的代码】
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ PySimpleGUI
安装过程如下图所示:
【GUI是什么】
GUI是Graphical User Interface的缩写,中文翻译为图形用户界面。
Graphical [ˈɡrafɪk(ə)l]:图形的。
Interface [ˈɪntəfeɪs]:接口。
它是一种通过图形化方式呈现计算机操作界面的技术,使得用户可以通过鼠标、键盘等输入设备与计算机进行交互。
GUI的出现使得计算机操作更加直观、易用,用户可以通过图形化的界面进行操作,而不需要记忆复杂的命令行指令。
常见的GUI包括Windows、Mac OS、Linux等操作系统的桌面界面。
【PySimpleGUI的作用】
PySimpleGUI是一个用于创建图形用户界面的 Python 库。
它提供了一种简单易用的方式来创建跨平台的 GUI 应用程序。
它的设计目标是让 GUI 开发变得简单、快速、易于理解和易于维护。
PySimpleGUI 支持多种 GUI 工具包,包括 Tkinter、Qt、WxPython 和 Pygame。
它可以用于创建各种类型的 GUI 应用程序,包括桌面应用程序、游戏、数据可视化工具等。
retrying是第三方库,需要安装。
【pip安装库的代码】
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ retrying
【retrying库的作用】
retrying:正在重试。
retrying库的作用是提供了一种简单的方式来添加重试逻辑,可以在函数执行失败时自动重试。
它可以帮助我们处理一些不稳定的操作,比如网络请求、数据库连接等,提高程序的健壮性和可靠性。
上面的所有库都安装完成以后,就可以把下面的代码直接复制到py文件中。
然后点击运行。
import os
import tkinter as tk
import webbrowser
import requests
import tkinter.messagebox as mes_box
import PySimpleGUI as sg
from tkinter import ttk
from retrying import retry
class SetUI(object):
"""
音乐弹框界面
"""
def __init__(self, weight=1000, height=600):
self.ui_weight = weight
self.ui_height = height
self.title = "好课优选·音乐破解软件"
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界面
:return:
"""
# 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=10, pady=10)
# 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=('楷体', 11), fg='Purple', 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), fg='Purple', 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('' , self.get_song_url)
@retry(stop_max_attempt_number=5)
def get_KuWoMusic(self):
"""
获取酷我音乐
:return:
"""
# 清空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.kuwo.cn/search/list?key=%E5%91%A8%E6%9D%B0%E4%BC%A6',
'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/99.0.4844.51 Safari/537.36',
'Cookie': '_ga=GA1.2.218753071.1648798611; _gid=GA1.2.144187149.1648798611; _gat=1; '
'Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1648798611; '
'Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1648798611; kw_token=HH3GHIQ0RYM'
}
search_input = self.ui_url.get()
if len(search_input) > 0:
search_url = 'http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?'
search_data = {
'key': search_input,
'pn': '1',
'rn': '80',
'httpsStatus': '1',
'reqId': '858597c1-b18e-11ec-83e4-9d53d2ff08ff'
}
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:
mes_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:
mes_box.showerror(title='错误', message='搜索超时,请重新输入后再搜索!')
else:
mes_box.showerror(title='错误', message='未输入需查询的歌曲或歌手,请输入后搜索!')
def get_song_url(self, event):
"""
获取下载歌曲的地址
:return:
"""
# 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 = 'http://www.kuwo.cn/api/v1/www/music/playUrl?mid={}&type=convert_url3' \
'&httpsStatus=1&reqId={}' \
.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:
mes_box.showerror(title='错误', message='未选择要下载的歌曲,请选择')
def download_music(self):
"""
下载音乐
:return:
"""
if not os.path.exists('./KuWoMusic'):
os.mkdir("./KuWoMusic/")
if self.song_num is not None:
song_name = self.song_name + '--' + self.song_author + ".mp3"
try:
save_path = os.path.join('./KuWoMusic/{}'.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)
mes_box.showinfo(title='下载成功', message='歌曲:%s,保存地址为%s' % (self.song_name, true_path))
except Exception:
mes_box.showerror(title='错误', message='未找到存放歌曲的文件夹')
else:
mes_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 loop(self):
"""
函数说明:loop等待用户事件
"""
self.ui_root.resizable(False, False) # 禁止修改窗口大小
self.ui_center() # 窗口居中
self.set_ui()
self.ui_root.mainloop()
if __name__ == '__main__':
a = SetUI()
a.loop()
代码正常运行后,得到如下一个GUI:
我把它称为vip音乐下载器。
在【请输入歌曲名或歌手:】后面输入【张杰】。
点击【搜索】。
和张杰有关的所有歌曲会呈现在GUI界面上,如下图所示:
我用vscode编辑器打开的是【安迪笔记】文件夹。
运行上面的代码后【安迪笔记】文件夹里多了一个【KuWoMusic】文件夹。
下载的音乐在【KuWoMusic】文件夹里。
vscode打开的是【安迪笔记】文件夹,下载的音乐在【安迪笔记】文件夹里的【KuWoMusic】文件夹里。
所以让大家重点关注下vscode打开的文件夹。
我衷心希望大家有空没空多研究下相对路径的知识,这个问题问我回答的头疼,太浪费我的时间了。
相对路径知识可参考如下链接。
68. Python的相对路径
【导入库语法】
import+模块名
import os
import requests
import webbrowser
【代码示例】
import tkinter as tk
【代码解析】
import tkinter as tk的作用是导入tkinter模块并将简写为tk
。
import PySimpleGUI as sg的作用是导入PySimpleGUI模块并将简写为sg
。
【代码示例】
import tkinter.messagebox as mes_box
【代码解析】
这行代码的意思是将 tkinter
库中的 messagebox
模块导入,并将其重命名为 mes_box。
这样就可以使用 mes_box 来调用 messagebox 模块中的函数,例如 mes_box.showinfo() 来显示一个信息框。
【代码示例】
from tkinter import ttk
【代码解析】
这行代码的意思是从 tkinter 模块中导入 ttk 子模块。
ttk 是 tkinter 的一个扩展模块,提供了一些额外的控件和样式选项。
【代码示例】
from retrying import retry
【代码解析】
从retrying库中导入retry函数。
代码解析先写库这个部分的。
其它代码后面有时间再解析吧。
真是困到怀疑人生了,今天的笔记没有检查,如果有错误、错别字大家联系我修改。
诶,一个不认真、不负责的博主!!!
源代码的作者是【湖南好课优选教育】的三更老师。
源代码是我上直播课写完作业后的奖励。
如涉侵权,请联系删除。