Python3.6實現付費酷狗音樂免費下載(已用tkinter封裝GUI)

前言

      之前做的Python小工具,現在搬出來和大家分享,基於酷狗音樂免費下載付費音樂,並已封裝GUI。

    (純屬個人興趣,請大家尊重音樂版權),超喜歡JJ Lin的歌,放圖鎮文

軟件

Python 3.6

Pycharm 2018.03

效果展示

 

輸入關鍵字,按下Enter鍵或者點擊搜索鍵開始搜索

代碼實現

   進度條花費了大量精力,最後採用網頁進度條思路,即填充到90%停下,等待請求返回,收到回覆後填充至100%

import requests
import json
from tkinter import ttk,filedialog
from tkinter import *
import tkinter as tk
import os,time
from tkinter import messagebox
import threading

global song_dic
song_dic = {}
def search():
    keys = keyin.get()
    search_url = 'http://songsearch.kugou.com/song_search_v2?callback=jQuery191034642999175022426_1489023388639&keyword={}&page=1&pagesize=30&userid=-1&clientver=&platform=WebFilter&tag=em&filter=2&iscorrection=1&privilege_filter=0&_=1489023388641'
    play_url = 'http://www.kugou.com/yy/index.php?r=play/getdata&hash={}'
    search_file = requests.get(search_url.format(keys))
    search_html = search_file.content.decode().replace(')', '').replace(
        'jQuery191034642999175022426_1489023388639(', '')
    views = json.loads(search_html)
    global song_dic
    song_dic = {}
    song_list = []
    i=0

    fill_line = canvas.create_rectangle(1.5, 1.5, 0, 23, width=0, fill="green")
    canvas.coords(fill_line, (0, 0, 646, 60))


    # 清空表格
    for item in treeview.get_children():
        treeview.delete(item)

    for view in views['data']['lists']:
        root.update()
        song_name = view['SongName'].replace('<em>', '').replace('</em>', '')
        album_name = view['AlbumName'].replace('<em>', '').replace('</em>', '')
        sing_name = view['SingerName'].replace('<em>', '').replace('</em>', '')
        file_hash = view['FileHash']
        song_info = {
            '歌名': song_name,
            '演唱者': sing_name,
            '專輯': album_name if album_name else None,
            'filehash': file_hash,
            'mp3url': None
        }
        mp3_file = requests.get(play_url.format(song_info['filehash'])).content.decode()
        mp3_json = json.loads(mp3_file)
        real_url = mp3_json['data']['play_url']
        song_info['mp3url'] = real_url # 歌曲信息獲取完畢!

        song_name = str(song_info['歌名'])+str(song_info['演唱者'])+str(song_info['專輯'])
        song_list.append(song_info['演唱者'])
        song_list.append(song_info['專輯'])
        song_list.append(song_info['mp3url'])
        treeview.insert('', i, values=(song_info['歌名'], song_info['演唱者'], song_info['專輯']))
        i += 1
        song_dic[song_name] = song_list
        song_list = []

    # 清空進度條
    fill_line = canvas.create_rectangle(1.5, 1.5, 0, 23, width=0, fill="white")
    x = 300  # 未知變量,可更改
    n = 643 / x  # 643是矩形填充滿的次數

    for t in range(x):
        n = n + 643 / x
        # 以矩形的長度作爲變量值更新
        canvas.coords(fill_line, (0, 0, n, 60))
        root.update()
        time.sleep(0)  # 時間爲0,即飛速清空進度條



def musicsave():
    try:
        dirsetting = open('resource/settings/songdirsetting.ini', 'r')
        dirlast = dirsetting.read()
        dirsetting.close()
    except:
        dirlast='D:'  # 默認保存文件夾
    for item in treeview.selection():
        #item = I001
        item_text = treeview.item(item, "values")
        song_name1 = item_text[1]+' - '+item_text[0]
        songkey = item_text[0]+item_text[1]+item_text[2]
    filename = dirlast +'/'+ song_name1 + ".mp3"
    with open(filename, "wb")as fp:
        global song_dic
        real_url = song_dic[songkey][2]
        fp.write(requests.get(real_url).content)
    messagebox.showinfo('下載完成', '歌曲《'+song_name1+'》已保存至\n'+dirlast+' 文件夾!')

def musicsave2(event):
    musicsave()
def search2(event):
    two_threading()

def chosedir(): # 選擇保存文件夾
    def chose():
        default_dir = r"C:\Users\lenovo\Desktop"  # 設置默認打開目錄
        dname = filedialog.askdirectory(title=u"選擇文件夾",
                                        initialdir=(os.path.expanduser(default_dir)))
        dirsetting = open('resource/settings/songdirsetting.ini', 'w')
        dirsetting.write(dname)
        dirsetting.close()
        dirname.set(dname)
    chosebox = tk.Toplevel()
    chosebox.iconbitmap(r'resource/EC.ico')  # 窗口圖標設置
    chosebox.title("設置")
    chosebox.geometry(('320x100+720+200'))  # 寬度x 高度+橫向偏移量(距左邊)+縱向偏移量(距上邊)
    chosebox.resizable(0, 0)
    tk.Label(chosebox, text="文件保存至: ", bd=1, width=10).place(x=7, y=30)
    dirname = tk.StringVar()  # 文件絕對地址
    try:
        dirsetting = open('resource/settings/songdirsetting.ini', 'r')
        dirlast = dirsetting.read()
        dirname.set(dirlast)
        dirsetting.close()
    except:
        dirname.set('D:')  # 默認保存文件夾
    showdir = tk.Entry(chosebox, textvariable=dirname, width=26)
    showdir.place(x=74, y=30)
    ttk.Button(chosebox, text='瀏覽', compound='center', width=5, command=chose).place(x=262, y=27)

# 顯示下載進度
def progress():
    # 填充進度條
    fill_line = canvas.create_rectangle(1.5, 1.5, 0, 23, width=0, fill="green")
    x = 300  # 未知變量,可更改
    n = 643 / x  # 643是矩形填充滿的次數
    for i in range(x):
        n = n + 643 / x
        canvas.coords(fill_line, (0, 0, n, 60))
        root.update()
        time.sleep(0.02)  # 控制進度條流動的速度
        if n>600:
            break
    canvas.coords(fill_line, (0, 0, 600, 60)) # 90%時停止進度條,等待請求返回
    root.update()


def two_threading():
    threads = [] #定義線程池
    t1 = threading.Thread(target=search)
    threads.append(t1)
    t2 = threading.Thread(target=progress)
    threads.append(t2)

    for t in threads:
        t.setDaemon(True) # 設置爲守護線程
        t.start()


root = tk.Tk()
root.title('歡迎使用本工具')
root.geometry(('700x480+200+100'))  # 寬度x 高度+橫向偏移量(距左邊)+縱向偏移量(距上邊)

menuBar = tk.Menu(root)
root.config(menu=menuBar)

setMenu = tk.Menu(menuBar, tearoff=0)
setMenu.add_command(label="保存文件夾", command = chosedir)
menuBar.add_cascade(label="設置", menu=setMenu)

title = Label(root, text='付費音樂破解助手', font=("宋體", 18))  # 設置標題
title.place(x=260, y=10)

keywords = Label(root, text='關鍵詞:', width=6, height=1, bd=2,
                font=('微軟雅黑',12))
keywords.place(x=150, y=56)

keyshow = StringVar()
keyin = Entry(root, textvariable=keyshow, width=35,bg="#c7edcc",font=('微軟雅黑',10))  # 關鍵詞輸入框
keyin.place(x=220, y=60)
keyin.bind("<Return>", search2) # 綁定回車鍵搜索

btphoto = tk.PhotoImage(file='resource/image/bt.png')
bt3 = tk.Button(root, image = btphoto,bd =0, command=two_threading)
bt3.place(x=500, y=58)

# 設置下載進度條
canvas = tk.Canvas(root, width=643, height=5, bg="white")
canvas.place(x=28, y=88)

#bt4 = ttk.Button(root, text='下載',width=5, command=musicsave)
#bt4.place(x=630, y=57)

columns = ("歌名", "演唱者","專輯")
treeview = ttk.Treeview(root, height=16, show="headings", columns=columns)  # 表格

treeview.column("歌名", width=200, anchor='center')  # 表示列,不顯示
treeview.column("演唱者", width=200, anchor='center')
treeview.column("專輯", width=240, anchor='center')

treeview.heading("歌名", text="歌名")  # 顯示錶頭
treeview.heading("演唱者", text="演唱者")
treeview.heading("專輯", text="專輯")

treeview.place(x=30,y=96)
def treeview_sort_column(tv, col, reverse):  # Treeview、列名、排列方式
    l = [(tv.set(k, col), k) for k in tv.get_children('')]
    l.sort(reverse=reverse)  # 排序方式
    # rearrange items in sorted positions
    for index, (val, k) in enumerate(l):  # 根據排序後索引移動
        tv.move(k, '', index)
    tv.heading(col, command=lambda: treeview_sort_column(tv, col, not reverse))  # 重寫標題,使之成爲再點倒序的標題
for col in columns:  # 綁定函數,使表頭可排序
    treeview.heading(col, text=col, command=lambda _col=col: treeview_sort_column(treeview, _col, False))

menu = Menu(treeview, tearoff=0)
menu.add_command(label="下載", command=musicsave)
def popupmenu(event):
    menu.post(event.x_root, event.y_root)
treeview.bind("<Button-3>", popupmenu)
treeview.bind('<Double-1>', musicsave2)
tk.Label(root, text="左鍵雙擊或右鍵下載歌曲", width=19).place(x=30,y=450)
root.iconbitmap(r'resource/EC.ico')  # 窗口圖標設置
root.mainloop()



相關文件下載(包括ico圖片、無需Python也可直接運行的exe文件)

百度網盤鏈接:點擊這裏

參考鏈接:

https://blog.csdn.net/knidly/article/details/80109155

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章