python實(shí)現(xiàn)音樂(lè)播放和下載小程序功能
(本篇部分代碼綜合整理自B站,B站有手把手說(shuō)明的教程)
1.網(wǎng)易云非付費(fèi)內(nèi)容爬取器(聲明:由于技術(shù)十分簡(jiǎn)單,未到觸犯軟件使用規(guī)則的程度)驅(qū)動(dòng)Edge瀏覽器(自己寫(xiě)驅(qū)動(dòng)會(huì)更高端)進(jìn)入界面,爬取列表中第一個(gè)音頻地址并存入相應(yīng)文件夾中。這里有一個(gè)最簡(jiǎn)單的爬蟲(chóng)程序和一個(gè)最簡(jiǎn)單的tkinter GUI編程。
注意,要先在網(wǎng)易云音樂(lè)網(wǎng)頁(yè)中將第一個(gè)對(duì)應(yīng)音頻鏈接的位置定位:

對(duì)于以上定位可通過(guò)如下方式獲得(定位器):
req = driver.find_element_by_id('m-search')
a_id = req.find_element_by_xpath('.//div[@class = "item f-cb h-flag "]/div[2]//a').get_attribute("href")
在XML語(yǔ)言中尋找鏈接路徑的方法可參見(jiàn)find_element_by_xpath
創(chuàng)建目錄參見(jiàn)makedirs
這里的GUI需要tkinter添加文本。用text控件insert(插入文本)、see(滾動(dòng))、update(更新)等方法顯示正在下載和已下載圖樣;在get_music_name函數(shù)中,首先從輸入窗口獲取名稱(chēng),然后調(diào)用Edge驅(qū)動(dòng)訪(fǎng)問(wèn)網(wǎng)易云音樂(lè)主頁(yè),通過(guò)'http://music.163.com/song/media/outer/url?id={}.mp3'.format(song_id)搜到歌曲,通過(guò)上述定位器找到歌曲地址和歌名。注意到第一個(gè)函數(shù)傳入的應(yīng)該是字典類(lèi)型(有了這種語(yǔ)句:song_id = item['song_id']),那就創(chuàng)建一個(gè)字典后在函數(shù)體內(nèi)調(diào)用song_load實(shí)現(xiàn)下載。在這之前,驅(qū)動(dòng)就完成了任務(wù),所以可以關(guān)閉驅(qū)動(dòng)。
至于Tkinter的控件內(nèi)容,應(yīng)該根據(jù)實(shí)際情況試錯(cuò)和設(shè)計(jì),界面編程相對(duì)還是比較簡(jiǎn)單的。(分別創(chuàng)建標(biāo)簽控件、輸入框、列表框、按鈕,并依次確定它們?cè)谥鹘缑嬷械奈恢茫?/p>
from tkinter import *
from selenium import webdriver
global entry
import os
from urllib.request import urlretrieve
#2.下載歌曲
def song_load(item):
song_id = item['song_id']
song_name = item['song_name']
song_url = 'http://music.163.com/song/media/outer/url?id={}.mp3'.format(song_id)
#創(chuàng)建文件夾
os.makedirs('music_netease',exist_ok=True)
path = 'music_netease\{}.mp3'.format(song_name)
#顯示數(shù)據(jù)到文本框
text.insert(END,'歌曲:{},正在下載...'.format(song_name))
#文本框滾動(dòng)
text.see(END)
#更新
text.update()
#下載
urlretrieve(song_url,path)
#顯示數(shù)據(jù)到文本框
text.insert(END,'歌曲:{},下載完畢'.format(song_name))
#文本框滾動(dòng)
text.see(END)
#更新
text.update()
#1.搜索
def get_music_name():
#獲取輸入的內(nèi)容
name = entry.get()
url = 'https://music.163.com/#/search/m/?s={}&type=1'.format(name)
#搜索頁(yè)面
option = webdriver.EdgeOptions()
option.add_argument('--headless')
#driver = webdriver.Edge(edge_options=option)
driver = webdriver.Edge('D:\\python\\msedgedriver')
driver.get(url)
driver.switch_to.frame('g_iframe')
#獲取歌曲的id
req = driver.find_element_by_id('m-search')
a_id = req.find_element_by_xpath('.//div[@class = "item f-cb h-flag "]/div[2]//a').get_attribute("href")
song_id = a_id.split('=')[-1]
print(song_id)
song_name = req.find_element_by_xpath('.//div[@class="item f-cb h-flag "]/div[2]//b').get_attribute("title")
print(song_name)
#構(gòu)造字典
item = {}
item['song_id'] = song_id
item['song_name'] = song_name
driver.quit()
#下載歌曲
song_load(item)
#get_music_name()
#形象工程
# 搭建界面
#創(chuàng)建畫(huà)板
root = Tk()
#標(biāo)題
root.title('網(wǎng)易云下載器')
#設(shè)置窗口大小
root.geometry('560x450+400+200')
#標(biāo)簽控件
label = Label(root,text = '輸入要下載的歌曲:',font = ('華文行楷',20))
#標(biāo)簽定位
label.grid()
#輸入框
entry = Entry(root,font = ('楷書(shū)',20))
#定位
entry.grid(row = 0,column = 1)
#列表框
text = Listbox(root,font = ('隸書(shū)',16),width = 50, heigh = 15)
text.grid(row = 1,columnspan = 2)
#點(diǎn)擊按鈕
button = Button(root,text = '開(kāi)始下載',font = ('楷書(shū)',15),command=get_music_name)
button.grid(row=2, column=0,sticky=W)
button1 = Button(root,text = '退出程序',font = ('楷書(shū)',15),command=root.quit)
button1.grid(row=2, column=1,sticky=E)
#顯示當(dāng)前的界面內(nèi)容
root.mainloop()
運(yùn)行效果

發(fā)現(xiàn)music_netease文件夾中相關(guān)文件赫然在列。

簡(jiǎn)易音樂(lè)播放器:
這個(gè)控件在界面上仍然使用Tkinter,只不過(guò)沒(méi)有通過(guò)編程,而是利用pygame庫(kù)中的音頻模塊,在邏輯上增加了上一曲、下一曲(讀取上一個(gè)文件、下一個(gè)文件)、音量控制、簡(jiǎn)單的線(xiàn)程控制等。
import os
import tkinter
import tkinter.filedialog
import time
import threading
import pygame
#第一步 搭建界面
root = tkinter.Tk()
root.title('音樂(lè)播放器')
#窗口大小和位置
root.geometry('460x600+500+100')
#不能拉伸
root.resizable(False,False)
folder = ''#文件路徑
res = []
num = 0
now_music = ''
#第二步 功能實(shí)現(xiàn)
def buttonChooseClik():
'''添加文件函數(shù)'''
global folder
global res
if not folder:
folder = tkinter.filedialog.askdirectory()#選擇目錄
musics = [folder + '\\' + music
for music in os.listdir(folder) if music.endswith(('.mp3','ogg'))]
ret = []
for i in musics:
ret.append(i.split('\\')[1:])
res.append(i.replace('\\','/'))
var2 = tkinter.StringVar()
var2.set(ret)
#放入列表框
lb = tkinter.Listbox(root,listvariable =var2)
lb.place(x=50,y=100,width=260,height=300)
if not folder:
return
global playing
playing = True
# 根據(jù)情況禁用和啟用相應(yīng)的按鈕
buttonPlay['state'] = 'normal'
buttonStop['state'] = 'normal'
pause_resume.set('播放')
def play():
'''播放音樂(lè)的函數(shù)'''
#初始化混音器設(shè)備
if len(res):
pygame.mixer.init()
global num
while playing:
if not pygame.mixer.music.get_busy():
#隨機(jī)播放一首歌曲
nextMusic =res[num]
print(nextMusic)
print(num)
pygame.mixer.music.load(nextMusic.encode())
#播放一次
pygame.mixer.music.play(1)
#print(len(res)-1)
if len(res) -1==num:
num=0
else:
num = num+1
nextMusic = nextMusic.split('\\')[1:]
musicName.set('playing....'+''.join(nextMusic))
else:
time.sleep(0.1)
def bottonPlayClik():
'''點(diǎn)擊播放'''
buttonNext['state'] = 'normal'
buttonPrev['state'] = 'normal'
if pause_resume.get() == '播放':
pause_resume.set('暫停')
global folder
if not folder:
#選擇目錄,返回目錄名
folder = tkinter.filedialog.askdirectory()
if not folder:
return
global playing
playing = True
#創(chuàng)建線(xiàn)程,主線(xiàn)程接受用戶(hù)操作
t = threading.Thread(target=play)
t.start()
elif pause_resume.get() == '暫停':
pygame.mixer.music.pause()
pause_resume.set('繼續(xù)')
elif pause_resume.get() == '繼續(xù)':
pygame.mixer.music.unpause()
pause_resume.set('暫停')
def bottonStopClik():
'''停止播放'''
global playing
playing = False
pygame.mixer.music.stop()
def bottonNextClik():
'''播放下一首'''
global playing
playing = False
pygame.mixer.music.stop()
global num
if len(res)== num:
num = 0
playing = True
t = threading.Thread(target=play)
t.start()
def bottonPrevClik():
'''播放上一首'''
global playing
playing = True
pygame.mixer.music.stop()
global num
if num == 0:
num = len(res)-2
elif num == len(res) - 1:
num -= 2
else:
num -=2
print(num)
playing = True
t = threading.Thread(target = play)
t.start()
def closeWindow():
'''關(guān)閉窗口'''
global playing
playing = False
time.sleep(0.3)
try:
pygame.mixer.music.stop()
pygame.mixer.quit()
except:
pass
root.destroy()
def control_voice(value = 0.5):
pygame.mixer.music.set_volume(float(value))
#關(guān)閉窗口
root.protocol('WM_DELETE_WINDOW',closeWindow)
#添加按鈕
buttonChoose = tkinter.Button(root,text='添加',command=buttonChooseClik)
#布局
buttonChoose.place(x=50,y=10,width=50,height=20)
#播放按鈕 跟蹤變量值的變化
pause_resume = tkinter.StringVar(root,value='播放')
buttonPlay= tkinter.Button(root,textvariable=pause_resume,command=bottonPlayClik)
buttonPlay.place(x=190,y=10,width=50,height=20)
buttonPlay['state'] = 'disabled'
#停止播放
buttonStop = tkinter.Button(root,text = '停止',command=bottonStopClik)
#布局
buttonStop.place(x=120,y=10,width=50,height=20)
#狀態(tài)
buttonStop['state'] = 'disabled'
# 下一首
buttonNext = tkinter.Button(root,text='下一首',command =bottonNextClik)
buttonNext.place(x=260,y=10,width=50,height=20)
buttonNext['state'] = 'disabled'
#上一首
buttonPrev = tkinter.Button(root,text='上一首',command =bottonPrevClik)
buttonPrev.place(x = 330,y=10,width=50,height=20)
buttonPrev['state'] = 'disabled'
musicName = tkinter.StringVar(root,value='暫時(shí)沒(méi)有播放音樂(lè)')
labelName = tkinter.Label(root,textvariable=musicName)
labelName.place(x=10,y=30,width=260,height=20)
#添加控件
s = tkinter.Scale(root,label='音量',from_=0,to=1,orient=tkinter.HORIZONTAL,
length=240,showvalue=0,tickinterval=2,resolution=0.1,command=control_voice)
s.place(x=50,y=50,width=200)
#啟動(dòng)消息循環(huán)
root.mainloop()
運(yùn)行效果:

到此這篇關(guān)于python實(shí)現(xiàn)音樂(lè)播放和下載小程序功能的文章就介紹到這了,更多相關(guān)python--音樂(lè)播放和下載小程序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python基于爬蟲(chóng)實(shí)現(xiàn)全網(wǎng)搜索并下載音樂(lè)
- python實(shí)現(xiàn)可下載音樂(lè)的音樂(lè)播放器
- 如何基于Python批量下載音樂(lè)
- python爬取網(wǎng)易云音樂(lè)熱歌榜實(shí)例代碼
- python打開(kāi)音樂(lè)文件的實(shí)例方法
- python給視頻添加背景音樂(lè)并改變音量的具體方法
- python中加背景音樂(lè)如何操作
- 基于python實(shí)現(xiàn)音樂(lè)播放器代碼實(shí)例
- Python如何爬取qq音樂(lè)歌詞到本地
- 如何用Python一次性下載抖音上音樂(lè)
- Python音樂(lè)爬蟲(chóng)完美繞過(guò)反爬
相關(guān)文章
對(duì)pandas的行列名更改與數(shù)據(jù)選擇詳解
今天小編就為大家分享一篇對(duì)pandas的行列名更改與數(shù)據(jù)選擇詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-11-11
使用numpy和PIL進(jìn)行簡(jiǎn)單的圖像處理方法
今天小編就為大家分享一篇使用numpy和PIL進(jìn)行簡(jiǎn)單的圖像處理方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
keras 實(shí)現(xiàn)輕量級(jí)網(wǎng)絡(luò)ShuffleNet教程
這篇文章主要介紹了keras 實(shí)現(xiàn)輕量級(jí)網(wǎng)絡(luò)ShuffleNet教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06
Python學(xué)習(xí)筆記之字符串和字符串方法實(shí)例詳解
這篇文章主要介紹了Python學(xué)習(xí)筆記之字符串和字符串方法,結(jié)合實(shí)例形式詳細(xì)分析了Python字符串相關(guān)操作函數(shù)與使用技巧,需要的朋友可以參考下2019-08-08
Python學(xué)習(xí)筆記之Django創(chuàng)建第一個(gè)數(shù)據(jù)庫(kù)模型的方法
今天小編就為大家分享一篇Python學(xué)習(xí)筆記之Django創(chuàng)建第一個(gè)數(shù)據(jù)庫(kù)模型的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-08-08
Python實(shí)現(xiàn)網(wǎng)絡(luò)自動(dòng)化eNSP
這篇文章主要介紹了Python實(shí)現(xiàn)網(wǎng)絡(luò)自動(dòng)化eNSP,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
keras.utils.to_categorical和one hot格式解析
這篇文章主要介紹了keras.utils.to_categorical和one hot格式解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07

