• Python爬虫网易云音乐,Tkinter制作音乐播放器


    目录

    一、效果展示

    二、环境

    三、实现过程

    四、源码


    一、效果展示

    页面的美化以及功能还有待升级~

    先来说一下已有功能吧:

    • 可以在搜索框中通过歌曲或歌手名称进行搜索,效果和在网易云官网搜索一样。

    • 点击开始下载,就会将搜索结果的第一条歌曲下载到指定文件夹

    • 下载完毕后,会遍历音乐目录,并将歌曲信息在窗口上刷新
    • 选中歌曲,然后点击播放,就会播放音乐

    二、环境

    使用语言:python3.7
    开发工具:PyChram
    第三方库:

    1. requests:获取网页数据
    2. execjs:执行js代码
    3. tkinter:图形用户界面
    4. tkinter.ttk:升级版的tkinter
    5. pygame:用来播放音乐

    内置库:

    1. os:用于文件操作

    三、实现过程

    1.网易云音乐爬取

    1. import requests
    2. import re
    3. # 目标网址
    4. url = 'https://music.163.com/discover/toplist'
    5. # 伪装成浏览器
    6. headers = {
    7. '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'
    8. }
    9. # get请求
    10. response = requests.get(url, headers=headers)
    11. html_data = response.text
    12. info_list = re.findall('
    13. (.*?)
    14. ', 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.播放

    四、源码

    1. import requests
    2. import execjs
    3. import os
    4. from tkinter import *
    5. from tkinter.ttk import *
    6. import pygame
    7. from tkinter import messagebox
    8. # 下载歌曲到文件夹
    9. def song_load():
    10. url = 'https://music.163.com/weapi/cloudsearch/get/web?csrf_token=887ad1857d7e9c0e9640eecb1b5a96be'
    11. headers = {
    12. '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'
    13. }
    14. js = open('music163.js', mode='r', encoding='utf-8').read()
    15. ctx = execjs.compile(js)
    16. keyword = entry1.get() # 获取单行文本框里的内容
    17. result = ctx.call('search', keyword)
    18. data = {
    19. 'params': result['encText'],
    20. 'encSecKey': result['encSecKey']
    21. }
    22. resp = requests.post(url=url, headers=headers, data=data)
    23. json_data = resp.json()
    24. songs = json_data['result']['songs']
    25. if songs:
    26. song = songs[0] # 获取第一首匹配到的歌曲
    27. music_name = song['name']
    28. music_id = song['id']
    29. music_url = 'http://music.163.com/song/media/outer/url?id=' + str(music_id)
    30. chars = ['\\', '/', ':', '*', '?', '"', '<', '>', '|']
    31. for char in chars:
    32. music_name = music_name.replace(char, '_')
    33. # 图片、音频、视频都属于二进制数据
    34. music_data = requests.get(music_url, headers=headers).content
    35. with open(f'D:/music/{music_name}.mp3', mode='wb') as f:
    36. f.write(music_data)
    37. show_files()
    38. # 将文件夹里的歌曲显示出来
    39. def show_files():
    40. folder_path = r'D:/music' # 指定文件夹路径
    41. # 获取文件夹中的所有文件名
    42. files = os.listdir(folder_path)
    43. # 清空树形菜单
    44. tree.delete(*tree.get_children())
    45. # 遍历文件名列表,将文件名添加到树形菜单中
    46. for i, file_name in enumerate(files):
    47. tree.insert("", index=END, text=i, values=(file_name))
    48. def song_play():
    49. # 初始化pygame和mixer
    50. pygame.init()
    51. pygame.mixer.init()
    52. # 检查是否选择了要播放的歌曲
    53. selected_item = tree.focus()
    54. if not selected_item:
    55. messagebox.showinfo("提示", "请先选择要播放的歌曲")
    56. return
    57. # 获取选中的歌曲文件名
    58. selected_song = tree.item(selected_item, "values")[0]
    59. song_path = f"D:/music/{selected_song}"
    60. try:
    61. # 使用播放器播放音乐文件
    62. pygame.mixer.music.load(song_path)
    63. pygame.mixer.music.play()
    64. # messagebox.showinfo("提示", "正在播放音乐")
    65. except pygame.error as e:
    66. messagebox.showinfo("错误", str(e))
    67. win = Tk()
    68. win.title('音乐听') # 设置窗口标题
    69. win.configure(bg='#F4EFE7') # 设置背景色
    70. winw=560 #窗口的宽度
    71. winh=470 #窗口的高度
    72. scrw=win.winfo_screenwidth() #屏幕的宽度
    73. scrh=win.winfo_screenheight() #屏幕的高度
    74. x=(scrw-winw)/2 #窗口的水平位置
    75. y=(scrh-winh)/2 #窗口的垂直位置
    76. win.geometry("%dx%d+%d+%d" %(winw,winh,x,y)) #设置窗口位置
    77. title_label = Label(win, text='音乐听', font=('华文行楷', 36, 'bold'), background='#F4EFE7')
    78. title_label.grid(row=0,columnspan=2)
    79. label1 = Label(win, text='输入歌曲、歌手:', font=('华文行楷', 20), background='#F4EFE7')
    80. label1.grid(row=1, column=0,padx=10,pady=10)
    81. entry1 = Entry(win, font=('隶书', 20))
    82. entry1.grid(row=1, column=1,padx=10,pady=10)
    83. var = StringVar()
    84. var.set('163')
    85. style = Style()
    86. style.configure('TRadiobutton', font=('微软雅黑', 14), background='#F4EFE7')
    87. radio1 = Radiobutton(win, text='网易云音乐', variable=var, value='163',style='TRadiobutton')
    88. radio1.grid(row=2, column=0,padx=10,pady=10)
    89. radio2 = Radiobutton(win, text='QQ音乐', variable=var, value='qq', style='TRadiobutton')
    90. radio2.grid(row=2, column=1,padx=10,pady=10)
    91. tree = Treeview(win, columns=("filename"))
    92. tree.heading("#0", text="序号")
    93. tree.heading("filename", text="文件名称")
    94. tree.grid(row=3, columnspan=2,padx=10,pady=10)
    95. # 定义按钮的样式
    96. style.configure('TButton', font=('微软雅黑', 14), background='#F4EFE7', foreground='#000000', relief=RIDGE)
    97. button1 = Button(win, text='开始下载', command=song_load, style='TButton')
    98. button1.grid(row=4, column=0, padx=60, pady=10)
    99. button2 = Button(win, text='播放', command=song_play, style='TButton')
    100. button2.grid(row=4, column=1, padx=60, pady=10)
    101. # button2 = Button(win, text='退出程序', command=win.quit)
    102. # button2.grid(row=3, columnspan=2)
    103. show_files()
    104. win.mainloop()

  • 相关阅读:
    【CTF Web】CTFShow web3 Writeup(SQL注入+PHP+UNION注入)
    OpenAI官方吴达恩《ChatGPT Prompt Engineering 提示词工程师》(4)推理/Inferring
    LeetCode-684. Redundant Connection [C++][Java]
    uni-app系列:uni.navigateTo传值跳转
    二维数组转化为普通数组
    代码随想录算法训练营第五十八天|739. 每日温度、496.下一个更大元素 I
    10 数组和指针
    springboot 使用 logback日志
    [Vue项目实战]尚品汇 -- 初始化项目以及项目的配置与分析
    性能提升400倍丨外汇掉期估值计算优化案例
  • 原文地址:https://blog.csdn.net/m0_63636799/article/details/134016611