目標需求
一.需求 1.實作一個歌曲的下載功能,并且可以下載一些VIP歌曲 2.擁有一個相對有好的GUI界面,便于與用戶互動, 二 實作方法 1.獲取音樂, 方案一:通過VIP實作音樂抓包實作下載功能, 方案二:建立自己的音樂庫 方案三:通過VIP決議網站實作音樂下載(此方法最簡單) 2.用戶互動界面 1.通過pyqt開發一個炫酷的界面(難度較高) 2.通過tkinter自帶庫開發一個界面較為簡陋(最簡單) 三 綜合比較: 使用1.方案三和2.2實作功能
很多人學習python,不知道從何學起,
很多人學習python,掌握了基本語法過后,不知道在哪里尋找案例上手,
很多已經做案例的人,卻不知道如何去學習更加高深的知識,
那么針對這三類人,我給大家提供一個好的學習平臺,免費領取視頻教程,電子書籍,以及課程的源代碼!??¤
QQ群:623406465
軟體效果預覽
天氣獲取
這個沒什么好說的很簡單,至于代碼講解可以去參考我寫的
import urllib.request
import re
import tkinter.messagebox
import tkinter
'''這段代碼來自于遠古時代懶得去優化了'''
def get_weather():
try:
html = urllib.request.urlopen(r'http://www.weather.com.cn/weather/101240701.shtml')
urllib.request.urlcleanup()
read = html.read().decode('utf-8')
def get_way(path,string):
path_way=path
path_get=re.compile(path_way)
ture_key=path_get.findall(string,re.M)
return str(ture_key)
path_html='<input type="hidden" id="hidden_title" value="https://www.cnblogs.com/sn8888/p/.*"'
see_html=get_way(path_html,read)
path_see='v.*°C'
see_weather=get_way(path_see,see_html)
day=get_way('.*日',see_weather).strip('[\"\']')
weather=get_way('周.*°C',see_weather).strip('[\']')
# print(weather)
return weather
except Exception as e:
tkinter.messagebox.showinfo('tips', e)
# if __name__=="__main__":
# weather=get_weather()
# print(weather)
音樂獲取
這個就是我們軟體所涉及到的比較重要的功能,這里我選擇了一個音樂決議網站
抓包分析
打開開發者工具搜索歌曲我們可以看到服務器主要發送了三個請求如圖;
注意第一個箭頭這是我們的第一個發送的請求網址,注意headers我們可以發現這是關于歌曲的一些資訊,說明我們要先向其發送歌曲資訊,
再注意一下其內容我們可以發現它回傳的是一個json資料包含歌曲鏈接
之后我們觀察一下下面的網址,我們發現其是類似其他的來源的鏈接,
當然我們偷個懶只要第一個,
之后思路就簡單了,發送歌曲通過data資料獲取,之后獲取歌曲鏈接之后訪問禁止默認跳轉302 之后獲取音樂決議后的網址下載,
竟然如此下面上代碼,
import requests import os import tkinter.messagebox import tkinter from urllib import request class Music_get: '''可獲取下載收費歌曲(網易云VIP)僅供學習和參考''' def __init__(self): self.session = requests.session() self.get_id='http://www.ciding.fun/' self.headers_id={ 'Accept': 'application/json, text/javascript, */*; q=0.01', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Connection': 'eep-alive', 'Content-Length': '65', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'Host': 'www.ciding.fun', 'Origin': 'http://www.ciding.fun', 'Referer': 'http://www.ciding.fun/?name=%E5%80%92%E5%B8%A6&type=netease', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0', 'X-Requested-With': 'XMLHttpRequest' #首先不需要cookies只需要設定referer引數為構造后的網址 #其次再data內設定input引數即可, #最后獲取音樂的id再一次類推去訪問決議服務器獲取決議后的音樂的網址之后普下載 } self.headers_music={ 'Accept': '*/*', 'Accept-Encoding': 'identity;q=1, *;q=0', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Connection': 'keep-alive', 'Host': 'antiserver.kuwo.cn', 'Range': 'bytes=0-', 'Referer': 'http://www.ciding.fun/', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36' } def get_song_name(self,name): self.name=name data = {'input': self.name, 'filter': 'name', 'type': 'kuwo', 'page': '1'} return data def get_url_song(self,name): try: self.data=self.get_song_name(name) self.frist_reason=self.session.post(url=self.get_id,headers=self.headers_id,data=https://www.cnblogs.com/sn8888/p/self.data) self.music_root_web=self.frist_reason.json()['data'][0]['url'] self.pic=self.frist_reason.json()['data'][0]['pic'] self.title=self.frist_reason.json()['data'][0]['title'] self.author=self.frist_reason.json()['data'][0]['author'] # print(self.pic) # print(self.music_root_web) html_in=self.session.get(url=self.music_root_web,headers=self.headers_music,allow_redirects=False) self.music_url=html_in.headers['Location'] # print(self.music_url) self.url_list=[] self.url_list.append(self.music_url) self.url_list.append(self.pic) self.url_list.append(self.title) self.url_list.append(self.author) # print(self.url_list) return self.url_list except Exception as e: tkinter.messagebox.showinfo('tips',e) def down_load(self,name,path): '''給出音樂的名稱,已及mp3檔案的下載地址需要給定后綴''' url=self.get_url_song(name)[0] self.file_path=path # music = requests.get(url=url) # # with open(self.file_path, 'wb') as f: # f.write(music.content) # f.close() request.urlretrieve(url,self.file_path) return self.file_path def play_music(self,path): if os.path.exists(path): os.system(path) else: print("輸入的路徑有誤請重新檢查") if __name__=='__main__': get_music=Music_get() # music_name='十年' # path='十年.mp3' x=get_music.get_url_song('Wolves') print(x)
界面撰寫,
這個就沒什么好說的了這里先說一下一些坑關于tkinter的
首先是tkinter的按鈕系結再類中的函式,首先再一個類里面的一個函式比如
def explme(self):
pass
其中函式中的self是作為一個引數的所以為了符合語法需求我們必須使用lambda函式構造一個方法
lambda a:explme()
并且再按鈕中的command和bind中是不一樣的,
self.play_Button=tkinter.Button(self.win,image=self.image_play,compound = 'center',font=('宋體', 14),relief='groove',command=lambda :Root.function_load()) self.play_Button.place(x=420,y=250,width=150, height=140) # self.play_Button.configure(image=img, compound="center") self.tips=tkinter.StringVar() self.tips.set('輸入歌曲名稱例如:十年') self.Entry=tkinter.Entry(self.win,font=('宋體', 14),textvariable=self.tips,fg='gray') self.Entry.place(x=10,y=52,width=400, height=30) self.Entry.bind('<ButtonRelease-1>',func=lambda a:Root.click()) #lambda中的a變數沒有實際作用目的是為了是語法合乎規范 #TypeError: <lambda>() takes 0 positional arguments but 1 was given #由于在類中self是屬于一個引數,所以為了接受只能使用a來接受
下面是完整代碼;
'''創建一個霸氣的UI界面,負責整個程式的架構''' import os import tkinter.filedialog import tkinter import requests from PIL import Image,ImageTk from weather import get_weather import tkinter.messagebox from Analyze_music import Music_get class Root: def __init__(self): self.win = tkinter.Tk() self.win.geometry('600x475') self.win.title('VIP音樂下載器v0.55(測驗版)') self.win.attributes('-toolwindow', True) self.win.resizable(width=False, height=False) self.path_b='inico\ground2.gif' self.image_b=tkinter.PhotoImage(file=self.path_b) self.canves = tkinter.Canvas(self.win,width=600,height=475) self.canves.create_image(0,100,image=self.image_b) self.canves.pack() self.exit='inico\exit' self.path_p=r'inico\download.gif' self.image_play=tkinter.PhotoImage(file=self.path_p) #要加載圖示設個全域變數函式里面呼叫除外,在代碼主體中需要設定全域 self.path_go=r'inico\go.gif' self.image_go=tkinter.PhotoImage(file=self.path_go) self.path_s=r'inico\search.gif' self.image_s=tkinter.PhotoImage(file=self.path_s) def function_play(self): self.path_exit = 'inico\exit.txt' if not os.path.exists(self.path_exit): tkinter.messagebox.showinfo('tips','音樂還沒有被下載呦') elif os.path.exists(self.path_exit): f=open('inico\exit.txt','r') self.filename=f.read() f.close() tkinter.messagebox.showinfo('tips', '播放時將會在電腦上的播放器中播放\n若想回傳軟體請先退出播放軟體') os.remove(self.path_exit) os.system(self.filename) def function_load(self): fun=Music_get() self.filename = tkinter.filedialog.askdirectory() self.filename = self.filename+'/'+self.music_name+".mp3" # print(self.filename) fun.down_load(self.music_name,self.filename) self.path_exit='inico\exit.txt' f=open(self.path_exit,'w') f.write(self.filename) f.close() tkinter.messagebox.showinfo('tips', '下載完成') def function_search(self): #搜索功能的方法 #在函式里面的self.x只有在函式被執行后才可以在別的函式中使用 self.view_picture = Image.open(r'inico\ground.jpg') self.img1 = ImageTk.PhotoImage(self.view_picture) self.info_view.configure(image=self.img1, compound="center", text='') self.info_view.update() self.info_view.configure(font=('宋體', 15), text='搜索中......\n部分歌曲可能搜索不到請諒解') self.info_view.update() self.music_name=self.Entry.get() need_s='輸入歌曲名稱例如:十年' if self.music_name==need_s: self.music_name='十年' get_list=Music_get() info=get_list.get_url_song(self.music_name) pic_view=get_list.get_url_song(self.music_name)[1] self.view_pic=r'inico\view.jpg' try: picture=requests.get(pic_view) with open(self.view_pic, 'wb') as f: f.write(picture.content) f.close() self.view_picture=Image.open(self.view_pic) self.img1 = ImageTk.PhotoImage(self.view_picture) self.info_view.configure(image=self.img1, compound="center", text='') self.info_view.update() except Image.UnidentifiedImageError: str_tips=info[2]+'\n'+info[3] print(str_tips) self.info_view.config(text=str_tips,font=('宋體', 14)) self.info_view.update() def frame_parts(self): #天氣顯示框 weather=get_weather() self.weather_label=tkinter.Label(self.win,text=weather,font=('宋體', 14)) self.weather_label.place(x=0,y=0,width=600, height=40) #輸入框 self.tips=tkinter.StringVar() self.tips.set('輸入歌曲名稱例如:十年') self.Entry=tkinter.Entry(self.win,font=('宋體', 14),textvariable=self.tips,fg='gray') self.Entry.place(x=10,y=52,width=400, height=30) self.Entry.bind('<ButtonRelease-1>',func=lambda a:Root.click()) #lambda中的a變數沒有實際作用目的是為了是語法合乎規范 #TypeError: <lambda>() takes 0 positional arguments but 1 was given #由于在類中self是屬于一個引數,所以為了接受只能使用a來接受 #搜索按鈕 self.search=tkinter.Button(self.win,image=self.image_s,compound = 'center',font=('宋體', 14),relief='groove',command=lambda :Root.function_search()) self.search.place(x=420,y=52,width=150, height=35) #歌曲資訊預覽 self.info_view=tkinter.Label(self.win,font=('宋體', 10),relief='groove') self.info_view.place(x=10,y=86,width=400, height=328) #聯系作者 self.link_ant=tkinter.Button(self.win,text='作者詳情',font=('宋體', 13),relief='groove',command=lambda :Root.link_command()) self.link_ant.place(x=447 ,y=417,width=150,height=50) #播放按鈕 self.play_Button=tkinter.Button(self.win,image=self.image_go,compound = 'center',font=('宋體', 14),relief='groove',command=lambda :Root.function_play()) self.play_Button.place(x=420,y=150,width=135, height=43) #下載按鈕 self.play_Button=tkinter.Button(self.win,image=self.image_play,compound = 'center',font=('宋體', 14),relief='groove',command=lambda :Root.function_load()) self.play_Button.place(x=420,y=250,width=150, height=140) # self.play_Button.configure(image=img, compound="center") def link_command(self): tkinter.messagebox.showinfo('tips', '該軟體僅供學習和交流請勿用作商務\n若產生糾紛與作者無關!!!') def click(self): self.tips.set('') self.Entry.config(fg='black',textvariable=self.tips) def mainloop(self): self.win.mainloop() if __name__=="__main__": Root=Root() Root.frame_parts() Root.mainloop()
資源檔案
整個專案中是有一些資源檔案的比如那些按鈕中的貼圖,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/180397.html
標籤:Python
