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ù)中,首先從輸入窗口獲取名稱,然后調(diào)用Edge驅(qū)動(dò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)該是字典類型(有了這種語(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 webdriverglobal entryimport osfrom 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:pythonmsedgedriver’) 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)單的線程控制等。
import osimport tkinterimport tkinter.filedialogimport timeimport threadingimport pygame#第一步 搭建界面root = tkinter.Tk()root.title(’音樂(lè)播放器’)#窗口大小和位置root.geometry(’460x600+500+100’)#不能拉伸root.resizable(False,False)folder = ’’#文件路徑res = []num = 0now_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)建線程,主線程接受用戶操作 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)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. 輕松學(xué)習(xí)XML教程2. jsp實(shí)現(xiàn)登錄驗(yàn)證的過(guò)濾器3. css代碼優(yōu)化的12個(gè)技巧4. jsp+servlet簡(jiǎn)單實(shí)現(xiàn)上傳文件功能(保存目錄改進(jìn))5. 利用FastReport傳遞圖片參數(shù)在報(bào)表上展示簽名信息的實(shí)現(xiàn)方法6. xpath簡(jiǎn)介_(kāi)動(dòng)力節(jié)點(diǎn)Java學(xué)院整理7. msxml3.dll 錯(cuò)誤 800c0019 系統(tǒng)錯(cuò)誤:-2146697191解決方法8. jsp EL表達(dá)式詳解9. 解析原生JS getComputedStyle10. jsp cookie+session實(shí)現(xiàn)簡(jiǎn)易自動(dòng)登錄
