演示6:python音乐下载器
生活随笔
收集整理的這篇文章主要介紹了
演示6:python音乐下载器
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
演示6:python音樂下載器
- python音樂下載器-申明
- 原理
- 運(yùn)行效果
- 搜索列表界面效果
- 下載列表界面效果
- 源碼
python音樂下載器-申明
請(qǐng)支持正版音樂!本代碼只是教學(xué)使用,不可用作商業(yè)用途,否則后果自負(fù)。
原理
使用的是爬蟲原理。實(shí)際上就是對(duì)url進(jìn)行請(qǐng)求,然后對(duì)返回的數(shù)據(jù)進(jìn)行分析和提取。
本示例并只使用字符串的剪切功能對(duì)數(shù)據(jù)進(jìn)行提取,并未使用正則表達(dá)。
運(yùn)行效果
搜索列表界面效果
下載列表界面效果
源碼
''' 窗口的創(chuàng)建 tkinter 窗口庫(kù) urllib.request 訪問請(qǐng)求庫(kù) urllib.parse 鏈接編碼庫(kù) _thread 線程庫(kù) 此處需理解 ''' import tkinter,urllib.request,urllib.parse,_thread,os tk=tkinter.Tk()#創(chuàng)建窗口 tk.minsize(800,500)#設(shè)置窗口的最小尺寸 tk.maxsize(800,500)#設(shè)置窗口的最大尺寸 tk.title('音樂下載器')#設(shè)置窗口上面顯示的名字 ''' 數(shù)據(jù)存儲(chǔ) 此處需理解 ''' datasearchgequ=[]#用來(lái)存放查詢結(jié)果中的歌曲名 datasearchgeshou=[]#用來(lái)存放查詢結(jié)果中的歌手名 datasearchurl=[]#用來(lái)存放查詢結(jié)果中的下載鏈接,實(shí)際上存的是音樂播放頁(yè)面的鏈接 datasearchclick=[]#記錄當(dāng)前搜索的結(jié)果中已經(jīng)點(diǎn)擊下載的那一列,保證已經(jīng)被點(diǎn)擊下載的不能再次點(diǎn)擊 datalist1=[]#用來(lái)記錄下載列表的歌曲名 datalist2=[]#用來(lái)記錄下載列表的歌手名 dataupdown1=[]#用來(lái)記錄正在下載的歌曲名 dataupdown2=[]#用來(lái)記錄正在下載的歌手名 urlsearch='https://baidu.9ku.com/suggestions/?kw='#搜索請(qǐng)求的鏈接-URL tabletwofirst=0#用來(lái)記錄下載列表的第一個(gè)顯示的歌曲編號(hào) ''' 窗口控件-部分 此處需理解 ''' tkinter.Label(tk,text='歌曲、歌手名').place(x=10,y=8)#標(biāo)簽的顯示與設(shè)置,用來(lái)提示搜索的內(nèi)容范圍該是歌曲或歌手 musicname=tkinter.Entry(tk,width=30,textvariable=tkinter.StringVar())#輸入框的設(shè)置,并關(guān)聯(lián)上變量-musicname,textvariable=tkinter.StringVar() 為設(shè)置輸入框允許獲取 musicname.place(x=110,y=10)#設(shè)置輸入框的位置 ''' 點(diǎn)擊搜索按鈕時(shí)觸發(fā)的函數(shù) 實(shí)現(xiàn)搜索歌曲或歌手,并將數(shù)據(jù)存入列表中 此處需理解 ''' def clicksearch():str=urlsearch+urllib.parse.quote(musicname.get())#將請(qǐng)求連接-URL進(jìn)行編碼,防止包含中文導(dǎo)致訪問失敗str1=urllib.request.urlopen(str)#對(duì)編碼后的鏈接進(jìn)行訪問data=str1.read().decode('UTF-8')#對(duì)獲取的數(shù)據(jù)進(jìn)行解碼,以便方便對(duì)中文或其他語(yǔ)言進(jìn)行閱讀data=data[data.find('<dt>歌曲</dt>'):data.find('<dt>歌手</dt>')]#截取搜索結(jié)果中歌曲部分datasearchgequ.clear()#清空搜索結(jié)果的歌曲列表datasearchurl.clear()#清空搜索結(jié)果的下載列表datasearchgeshou.clear()#清空搜索結(jié)果的歌手列表datasearchclick.clear()#清空點(diǎn)擊下載的記錄,防止新搜索的結(jié)果無(wú)法點(diǎn)擊下載while True:#循環(huán),實(shí)現(xiàn)獲取搜索結(jié)果中的所有歌曲信息datasearchgequ.append(data[data.find('songName')+10:data.find('</span>')])#截取歌曲名,并存入列表datasearchgeshou.append(data[data.find('singerName')+20:data.find('</span></a>')])#截取歌手名,并存入列表datasearchurl.append(data[data.find('href=')+6:data.find('\'><span')])#截取下載鏈接,并存入列表if data.find('href=')<0:#判斷是否將所有歌曲獲取完updatatableone()#刷新搜索結(jié)果的表格-畫布break#結(jié)束循環(huán)data = data[data.find('</a></dd>') + 4:]#獲取完一首歌后,將被獲取的歌那部分信息刪除 ''' 窗口控件-部分 此處需理解 ''' musicsearch=tkinter.Button(tk,width=8,text="搜索",font=("黑體",9),command=clicksearch)#設(shè)置搜索按鈕,并關(guān)聯(lián)變量 musicsearch.place(x=390,y=9)#設(shè)置搜索按鈕的位置 tableone=tkinter.Canvas(tk,width=780,height=450,bg='#ffffff')#設(shè)置搜索結(jié)果的表格畫布,并關(guān)聯(lián)變量 tableone.create_rectangle((2,2,780,450))#設(shè)置搜索結(jié)果的表格畫布邊框 tableone.place(x=10,y=40)#設(shè)置搜索結(jié)果的表格畫布位置 tabletwo=tkinter.Canvas(tk,width=780,height=450,bg='#ffffff')#設(shè)置下載列表的表格畫布,并關(guān)聯(lián)變量 tabletwo.create_rectangle((2,2,780,450))#設(shè)置下載列表的表格畫布邊框 tabletwo.pack_forget()#設(shè)置下載列表的表格不顯示 ''' 搜索列表的表格繪制與刷新 此處需理解 ''' def updatatableone():tableone.create_rectangle((2,2,780,30),fill='#888888')#繪制表頭的背景顏色tableone.create_rectangle((2,31,780,450),fill='#ffffff')#繪制表身的背景顏色,為了防止之前搜索的結(jié)果不會(huì)消失tableone.create_text((250,15),text='歌曲')#繪制 歌曲 文字到表頭tableone.create_text((600, 15), text='歌手')#繪制 歌手 文字到表頭tableone.create_text((740, 15), text='操作')#繪制 操作 文字到表頭tableone.create_line((0,30,780,30))#繪制表頭與表身之間的分割線tableone.create_line((500,0,500,30))#繪制 歌曲 與 歌手 之間的分割線tableone.create_line((700,0,700,30))#繪制 歌手 與 操作 之間的分割線for i in range(0,len(datasearchgequ)-1):#循環(huán),實(shí)現(xiàn)繪制搜索結(jié)果的歌曲名、歌手名和操作按鈕tableone.create_text((250,40+i*20),text=datasearchgequ[i])#繪制歌曲名tableone.create_text((600,40+i*20),text=datasearchgeshou[i])#繪制歌手名if i in datasearchclick:#判斷是否該歌曲已經(jīng)點(diǎn)擊了下載tableone.create_rectangle((720, 33 + i * 20, 760, 48 + i * 20), fill='#ffffff')#繪制白色背景的按鈕-不可再次點(diǎn)擊下載else:tableone.create_rectangle((720,33+i*20,760,48+i*20),fill='#aaaaaa')#繪制灰色背景的按鈕-可點(diǎn)擊下載tableone.create_text((740,42+i*20),text="下載",font=('黑體',7))#繪制操作按鈕中的文字tableone.create_line((0,50+i*20,780,50+i*20))#繪制每一條信息之間的分割線 updatatableone()#調(diào)用上面的函數(shù) ''' 下載列表的表格繪制與刷新 此處需理解 ''' def updatatabletwo():tabletwo.create_rectangle((2,2,780,30),fill='#888888')#繪制表頭的背景顏色tabletwo.create_rectangle((2,31,780,450),fill='#ffffff')#繪制表身的背景顏色,為了防止之前下載列表的結(jié)果不會(huì)消失tabletwo.create_text((250,15),text='歌曲')#繪制 歌曲 文字到表頭tabletwo.create_text((600, 15), text='歌手')#繪制 歌手 文字到表頭tabletwo.create_text((740, 15), text='狀態(tài)')#繪制 狀態(tài) 文字到表頭tabletwo.create_line((0,30,780,30))#繪制表頭與表身之間的分割線tabletwo.create_line((500,0,500,30))#繪制 歌曲 與 歌手 之間的分割線tabletwo.create_line((700,0,700,30))#繪制 歌手 與 狀態(tài) 之間的分割線for i in range(tabletwofirst,len(datalist1)):#循環(huán),實(shí)現(xiàn)繪制下載列表的歌曲名、歌手名和操作按鈕tabletwo.create_text((250,40+(i-tabletwofirst)*20),text=datalist1[i])#繪制歌曲名tabletwo.create_text((600,40+(i-tabletwofirst)*20),text=datalist2[i])#繪制歌手名if datalist1[i] in dataupdown1 and datalist2[i] in dataupdown2:#判斷下載列表中的歌曲狀態(tài)tabletwo.create_text((740,42+(i-tabletwofirst)*20),text="正在下載",font=('黑體',7))#繪制正在下載文字else:tabletwo.create_text((740, 42 +(i-tabletwofirst)* 20), text="下載完成", font=('黑體', 7))#繪制下載完成文字tabletwo.create_line((0,50+(i-tabletwofirst)*20,780,50+(i-tabletwofirst)*20))#繪制每一條信息之間的分割線 updatatabletwo()#調(diào)用上面的函數(shù) ''' 在搜索結(jié)果按鈕中點(diǎn)擊下載時(shí)調(diào)用的函數(shù),必要攜帶的一個(gè)參數(shù) e (當(dāng)然這個(gè)可以自定義名稱) 此處可做了解 ''' def onclicktableone(e):x=e.x#獲取鼠標(biāo)點(diǎn)擊的位置的x坐標(biāo)y=int((e.y-30)/20)#獲取鼠標(biāo)點(diǎn)擊的位置的y坐標(biāo),并將該坐標(biāo)裝換成編號(hào),以便得知點(diǎn)擊的是哪首歌的下載if x>720 and x<760:#判斷是否點(diǎn)擊的下載按鈕范圍內(nèi),防止點(diǎn)擊其他位置也可以下載if y not in datasearchclick:#判斷該歌曲是否已經(jīng)點(diǎn)擊datasearchclick.append(y)#將該歌曲的搜索結(jié)果中的編號(hào)保存updownmusic(y)#調(diào)用下載歌曲的函數(shù)updatatableone()#刷新搜索結(jié)果的表格-畫布 ''' 下載列表滑動(dòng)滾輪時(shí)調(diào)用得到函數(shù),必要攜帶的一個(gè)參數(shù) e (當(dāng)然這個(gè)可以自定義名稱) 此處可做了解 ''' def tabletwohuadong(e):global tabletwofirst#設(shè)置該函數(shù)調(diào)用的這個(gè)變量是全局變量if e.delta>0:#判斷滾輪的滾動(dòng)方向tabletwofirst=tabletwofirst-1#滾輪向上滾動(dòng),將這個(gè)下載列表的第一條顯示的編號(hào)減1if tabletwofirst<0:#判斷這個(gè)變量數(shù)值是否小于0tabletwofirst=0#小于0,將它設(shè)置成0,防止出現(xiàn)錯(cuò)誤else:tabletwofirst=tabletwofirst+1#滾輪向下滾動(dòng),將這個(gè)下載列表的第一條顯示的編號(hào)加1if tabletwofirst>len(datalist1)-21:#判斷這個(gè)變量數(shù)值是否超過(guò)下載的歌曲數(shù)量tabletwofirst=tabletwofirst-1#超過(guò)了,則設(shè)置成沒有超過(guò),防止出現(xiàn)bugupdatatabletwo()#刷新下載列表的表格-畫布 ''' 設(shè)置表格-畫布 的鼠標(biāo)監(jiān)聽 此處可做了解 ''' tableone.bind('<Button-1>',onclicktableone)#如果搜索結(jié)果的表格被點(diǎn)擊了,就調(diào)用對(duì)應(yīng)的函數(shù) tabletwo.bind('<MouseWheel>',tabletwohuadong)#如果下載列表的表格中鼠標(biāo)滾輪滾動(dòng)了,就調(diào)用對(duì)應(yīng)的函數(shù) ''' 將播放音樂的頁(yè)面鏈接轉(zhuǎn)換成音樂文件鏈接的函數(shù),num為點(diǎn)擊下載的歌曲編號(hào) 此處可做了解 ''' def updownmusic(num):datalist1.append(datasearchgequ[num])#獲取點(diǎn)中的歌曲名,并存入列表datalist2.append(datasearchgeshou[num])#獲取點(diǎn)中的歌手名,并存入列表a=datasearchurl[num]#獲取點(diǎn)中的各州播放頁(yè)面鏈接str2 = "https:"+a[:a.find('/play')]+'/down'+a[a.find('play')+4:]#將鏈接中的 play 單詞改成 down str3 = urllib.request.urlopen(str2)#請(qǐng)求連接data=str3.read().decode('UTF-8')#將求情結(jié)果解碼data=data[data.find('點(diǎn)擊下載歌曲</a>')+10:]#找到音樂的真實(shí)下載鏈接data=data[data.find('href')+6:data.find('\" style')]#提取真實(shí)的下載鏈接_thread.start_new_thread(writefile,(num,data))#使用線程調(diào)用文件保存函數(shù),使用線程的原因是防止在保存時(shí)軟件無(wú)法使用 ''' 文件的保存函數(shù),num 為點(diǎn)擊下載的歌曲編號(hào),url 為歌曲的真實(shí)下載鏈接 此處可做了解 ''' def writefile(num,url):mname=datasearchgequ[num]#獲取歌曲名mgeshou=datasearchgeshou[num]#獲取歌手名dataupdown1.append(mname)#將該歌曲存入列表dataupdown2.append(mgeshou)#將該歌手存入列表updatatabletwo()#刷新下載列表name=datasearchgequ[num]+"-"+datasearchgeshou[num]#設(shè)置保存的歌曲文件名str5 = urllib.request.urlopen(url)#請(qǐng)求真實(shí)的下載鏈接data=str5.read()#將服務(wù)器返回的結(jié)果讀取出來(lái),無(wú)需解碼a=url[url.find('com'):]#獲取該歌曲的后綴,因?yàn)楦枨暮缶Y有mp3、wma、midi等de=os.path.join(os.path.expanduser("~"),'Desktop').replace('\\', '/', 5)#獲取桌面路徑fi=open(de+'/'+name+a[a.find('.'):],'wb')#設(shè)置文件保存的路徑與文件名fi.write(data)#寫文件fi.close()#關(guān)閉寫dataupdown1.remove(mname)#將該歌曲名從正在下載的列表中刪除dataupdown2.remove(mgeshou)#將該歌手名從正在下載的列表中刪除updatatabletwo()#刷新下載列表的表格-畫布 ''' 點(diǎn)擊所搜列表按鈕和下載列表按鈕時(shí)觸發(fā)的函數(shù) 此處需理解 ''' def clicktablefun1():#點(diǎn)擊搜索列表按鈕時(shí)觸發(fā)的函數(shù)tableone.place(x=10,y=40)#將搜索結(jié)果表格-畫布 移到窗口可見位置tabletwo.place(x=10,y=800)#將下載列表表格-畫布 移到窗口不可見位置 def clicktablefun2():#點(diǎn)擊下載列表按鈕時(shí)觸發(fā)的函數(shù)tabletwo.place(x=10,y=40)#將下載列表表格-畫布 移到窗口可見位置tableone.place(x=10,y=800)#將搜索結(jié)果表格-畫布 移到窗口不可見位置 ''' 窗口控件-部分 此處需理解 ''' tablesearch=tkinter.Button(tk,text='搜索列表',width=16,font=("黑體",9),command=clicktablefun1)#設(shè)置搜索列表按鈕 tablesearch.place(x=500,y=9)#設(shè)置搜索列表按鈕位置 tableupdown=tkinter.Button(tk,text='下載列表',width=16,font=("黑體",9),command=clicktablefun2)#設(shè)置下載列表按鈕 tableupdown.place(x=653,y=9)#設(shè)置下載列表按鈕位置 tk.mainloop()#使窗口顯示 ''' 作業(yè):實(shí)現(xiàn)一個(gè)簡(jiǎn)易的計(jì)算器,能實(shí)現(xiàn)數(shù)字不大的運(yùn)算,可參照win系統(tǒng)帶的計(jì)算器 '''總結(jié)
以上是生活随笔為你收集整理的演示6:python音乐下载器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Vue之引用DOM的ref属性
- 下一篇: gnome硬盘分析_解决八种Linux硬