目录
一、效果展示
二、环境
三、实现过程
四、源码
一、效果展示
页面的美化以及功能还有待升级~
先来说一下已有功能吧:
- 可以在搜索框中通过歌曲或歌手名称进行搜索,效果和在网易云官网搜索一样。
- 点击开始下载,就会将搜索结果的第一条歌曲下载到指定文件夹
- 下载完毕后,会遍历音乐目录,并将歌曲信息在窗口上刷新
- 选中歌曲,然后点击播放,就会播放音乐
二、环境
使用语言:python3.7
开发工具:PyChram
第三方库:
- requests:获取网页数据
- execjs:执行js代码
- tkinter:图形用户界面
- tkinter.ttk:升级版的tkinter
- pygame:用来播放音乐
内置库:
- os:用于文件操作
三、实现过程
1.网易云音乐爬取
import requests
import re
# 目标网址
url = 'https://music.163.com/discover/toplist'
# 伪装成浏览器
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
}
# get请求
response = requests.get(url, headers=headers)
html_data = response.text
info_list = re.findall('<li><a href="/song\?id=(.*?)">(.*?)</a></li>', html_data)
for info in info_list:
music_id = info[0]
music_name = info[1]
music_url = 'http://music.163.com/song/media/outer/url?id=' + music_id
chars = ['\\','/',':','*','?','"','<','>','|']
for char in chars:
music_name = music_name.replace(char, '_')
# 图片、音频、视频都属于二进制数据
music_data = requests.get(music_url, headers=headers).content
with open(f'C:/Users\Administrator\Desktop\音乐播放器/{music_name}.mp3', mode='wb') as f:
f.write(music_data)
我们先来看一下,歌曲是如何从网页上爬取出来的,
我们先来爬取飙升榜前Top100首歌曲
2.网易云搜索音乐
3.下载
4.遍历文件夹到窗口
5.播放
四、源码
import requests
import execjs
import os
from tkinter import *
from tkinter.ttk import *
import pygame
from tkinter import messagebox
# 下载歌曲到文件夹
def song_load():
url = 'https://music.163.com/weapi/cloudsearch/get/web?csrf_token=887ad1857d7e9c0e9640eecb1b5a96be'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
}
js = open('music163.js', mode='r', encoding='utf-8').read()
ctx = execjs.compile(js)
keyword = entry1.get() # 获取单行文本框里的内容
result = ctx.call('search', keyword)
data = {
'params': result['encText'],
'encSecKey': result['encSecKey']
}
resp = requests.post(url=url, headers=headers, data=data)
json_data = resp.json()
songs = json_data['result']['songs']
if songs:
song = songs[0] # 获取第一首匹配到的歌曲
music_name = song['name']
music_id = song['id']
music_url = 'http://music.163.com/song/media/outer/url?id=' + str(music_id)
chars = ['\\', '/', ':', '*', '?', '"', '<', '>', '|']
for char in chars:
music_name = music_name.replace(char, '_')
# 图片、音频、视频都属于二进制数据
music_data = requests.get(music_url, headers=headers).content
with open(f'D:/music/{music_name}.mp3', mode='wb') as f:
f.write(music_data)
show_files()
# 将文件夹里的歌曲显示出来
def show_files():
folder_path = r'D:/music' # 指定文件夹路径
# 获取文件夹中的所有文件名
files = os.listdir(folder_path)
# 清空树形菜单
tree.delete(*tree.get_children())
# 遍历文件名列表,将文件名添加到树形菜单中
for i, file_name in enumerate(files):
tree.insert("", index=END, text=i, values=(file_name))
def song_play():
# 初始化pygame和mixer
pygame.init()
pygame.mixer.init()
# 检查是否选择了要播放的歌曲
selected_item = tree.focus()
if not selected_item:
messagebox.showinfo("提示", "请先选择要播放的歌曲")
return
# 获取选中的歌曲文件名
selected_song = tree.item(selected_item, "values")[0]
song_path = f"D:/music/{selected_song}"
try:
# 使用播放器播放音乐文件
pygame.mixer.music.load(song_path)
pygame.mixer.music.play()
# messagebox.showinfo("提示", "正在播放音乐")
except pygame.error as e:
messagebox.showinfo("错误", str(e))
win = Tk()
win.title('音乐听') # 设置窗口标题
win.configure(bg='#F4EFE7') # 设置背景色
winw=560 #窗口的宽度
winh=470 #窗口的高度
scrw=win.winfo_screenwidth() #屏幕的宽度
scrh=win.winfo_screenheight() #屏幕的高度
x=(scrw-winw)/2 #窗口的水平位置
y=(scrh-winh)/2 #窗口的垂直位置
win.geometry("%dx%d+%d+%d" %(winw,winh,x,y)) #设置窗口位置
title_label = Label(win, text='音乐听', font=('华文行楷', 36, 'bold'), background='#F4EFE7')
title_label.grid(row=0,columnspan=2)
label1 = Label(win, text='输入歌曲、歌手:', font=('华文行楷', 20), background='#F4EFE7')
label1.grid(row=1, column=0,padx=10,pady=10)
entry1 = Entry(win, font=('隶书', 20))
entry1.grid(row=1, column=1,padx=10,pady=10)
var = StringVar()
var.set('163')
style = Style()
style.configure('TRadiobutton', font=('微软雅黑', 14), background='#F4EFE7')
radio1 = Radiobutton(win, text='网易云音乐', variable=var, value='163',style='TRadiobutton')
radio1.grid(row=2, column=0,padx=10,pady=10)
radio2 = Radiobutton(win, text='QQ音乐', variable=var, value='qq', style='TRadiobutton')
radio2.grid(row=2, column=1,padx=10,pady=10)
tree = Treeview(win, columns=("filename"))
tree.heading("#0", text="序号")
tree.heading("filename", text="文件名称")
tree.grid(row=3, columnspan=2,padx=10,pady=10)
# 定义按钮的样式
style.configure('TButton', font=('微软雅黑', 14), background='#F4EFE7', foreground='#000000', relief=RIDGE)
button1 = Button(win, text='开始下载', command=song_load, style='TButton')
button1.grid(row=4, column=0, padx=60, pady=10)
button2 = Button(win, text='播放', command=song_play, style='TButton')
button2.grid(row=4, column=1, padx=60, pady=10)
# button2 = Button(win, text='退出程序', command=win.quit)
# button2.grid(row=3, columnspan=2)
show_files()
win.mainloop()