Python中Tkinter案例

面向对象,使用Tkinter设计界面

import tkinter as tk
import requests, os, winreg, tkinter.messagebox, tkinter.filedialog


class Ui:  # 执行前期的ui设计

    def __init__(self, window, spider):
        self.window = window  # 接收实例化的窗口
        self.window.title("下载音乐")  # 编辑标题
        self.window.geometry("400x300")  # 设置窗口大小
        self.var1 = tk.StringVar()  # 定义变量接收选择
        self.var = tk.StringVar()  # 定义一个tk变量
        self.var2 = tk.StringVar()  # 定义一个tk变量

        def get_desktop():
            key = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
                                 r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders')  # 获得桌面路径
            return winreg.QueryValueEx(key, "Desktop")[0]

        self.path = tk.StringVar()
        self.path.set(get_desktop())  # 自定义下载路径
        self.spider = spider  # 接收实例化的爬虫
        self.main()  # 自动开启main函数

    def main(self):
        # 选择下载路径
        tk.Label(self.window, text="保存文件路径:").place(x=0, y=10)
        tk.Entry(self.window, textvariable=self.path).place(x=90, y=10)  # 默认为桌面路径
        tk.Button(self.window, text="选择路径", command=self.choice_path, width=10, height=1).place(x=240, y=5)

        # 选择下载模式
        tk.Label(self.window, text="请选择要使用哪种模式下载:", font=(9,)).place(x=70, y=40)
        tk.Radiobutton(self.window, text="歌手:下载该歌手的多首音乐!", variable=self.var1, value="singer", font=(7,)).place(x=50,
                                                                                                                y=65)
        tk.Radiobutton(self.window, text="歌名:下载要下载的音乐!", variable=self.var1,
                       value="sing", font=(7,)).place(x=50, y=95)  # 定义选择框
        # 按钮
        tk.Button(self.window, text="确定", command=self.next, width=5, height=1).place(x=80, y=135)  # 选择完毕
        tk.Button(self.window, text="取消", command=self.close, width=5, height=1).place(x=225, y=135)  # 取消按钮

    def next(self):
        if self.var1.get() == "singer":
            # 输入歌手,下载多页,启用多线程
            self.choice_singer()
        elif self.var1.get() == "sing":
            # 输入歌名,下载一首
            self.choice_song()
        else:
            # 没有选择内容
            tk.messagebox.showerror(title="Warnings", message="不可以多选哦,请做出选择!")  # 判断是否有值
            self.main()  # 如果没有选择,则继续运行main函数

    def close(self):
        self.window.destroy()  # 退出窗口

    def choice_path(self):
        self.path = tk.filedialog.askdirectory()

    def choice_singer(self):
        window_choice = tk.Toplevel(self.window)
        window_choice.title("输入")
        window_choice.geometry("200x170")
        # 选择歌手
        tk.Label(window_choice, text="请输入歌手:", font=(9,)).place(x=20, y=8)
        tk.Entry(window_choice, textvariable=self.var).place(x=20, y=38)
        # 选择要下载的页数
        tk.Label(window_choice, text="请输入要下载的页数:", font=(9,)).place(x=15, y=58)
        tk.Entry(window_choice, textvariable=self.var2).place(x=20, y=90)
        tk.Button(window_choice, text="确定",
                  command=lambda: spider.get_mid_singer(
                      f"http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key={self.var.get()}&pn={self.var2.get()}&rn=30&httpsStatus=1",
                      self.window, self.path, window_choice)).place(x=80, y=125)  # 使用匿名函数传参

    def choice_song(self):
        window_choice = tk.Toplevel(self.window)  # 新建窗口
        window_choice.title("下载音乐")
        window_choice.geometry("200x100")
        tk.Label(window_choice, text="请输入音乐名称:", font=(9,)).place(x=20, y=8)  # 接收变量名称
        tk.Entry(window_choice, show=None, textvariable=self.var).place(x=20, y=38)
        tk.Button(window_choice, text="确定",
                  command=lambda: spider.get_mid_song(
                      f"http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key={self.var.get()}&pn=1&rn=30&httpsStatus=1",
                      self.window, self.path, window_choice)).place(x=80, y=68)  # 使用匿名函数传参


class Spider:

    def __init__(self):
        self.headers1 = {  # 传入必要请求头,反爬
            "Accept": "application/json, text/plain, */*",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "zh-CN,zh;q=0.9",
            "Connection": "keep-alive",
            "Cookie": "_ga=GA1.2.2058800930.1642474837; _gid=GA1.2.1174281146.1642474837; Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1642490265,1642490289,1642490402,1642498818; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1642499234; kw_token=YK4UZW2UPL",
            "csrf": "YK4UZW2UPL",
            "Host": "www.kuwo.cn",
            "Referer": "http://www.kuwo.cn/",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36",
        }
        self.headers2 = {  # 得到音乐下载地址的请求头
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "zh-CN,zh;q=0.9",
            "Cache-Control": "max-age=0",
            "Connection": "keep-alive",
            "Cookie": "_ga=GA1.2.2058800930.1642474837; _gid=GA1.2.1174281146.1642474837; Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1642509517,1642511738,1642514710,1642551220; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1642551237; kw_token=GR2I2YW69IE",
            "Host": "www.kuwo.cn",
            "Upgrade-Insecure-Requests": "1",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36",
        }
        self.info = None  # 接收参数

    def get_mid_song(self, url, window, path, win):  # 得到mid
        win.destroy()  # 摧毁窗口
        choice = tk.Toplevel(window)
        choice.geometry("400x300")
        choice.title("选择框")
        resp = requests.get(url=url, headers=self.headers1).json()
        tk.Label(choice, text="请选择一首音乐下载", font=(7,)).place(x=80, y=8)
        lb = tk.Listbox(choice, width=400)
        for i in resp["data"]["list"]:
            mid = i["musicrid"].split("_")[-1]
            atr = i["artist"]
            names = i["name"]
            lb.insert("end", f"编号:{mid}    歌名:{names}  歌手:{atr}")
        lb.place(x=0, y=40)

        def get_info():  # 得到mid
            try:
                self.info = lb.get(lb.curselection()).split()  # 得到鼠标点击的值
                choice.destroy()
                temp = [i.split(":")[-1] for i in self.info]
                dic = {"name": temp[1], "url": f"http://www.kuwo.cn/api/v1/www/music/playUrl?mid={temp[0]}&type=convert_url&httpsStatus=1"}
                tk.Label(window, text="正在下载,请稍等!").place(x=120, y=180)
                self.download(path, dic)  # 传入保存路径
            except Exception as e:
                tk.messagebox.showerror(message=f"{e},请做出选择!")
                judge()

        def judge():
            tk.Button(choice, text="确定选择", command=get_info, width=6, height=1).place(x=175, y=250)

        judge()

    def get_mid_singer(self, url, window, path, win):  # 得到mid
        win.destroy()  # 摧毁窗口
        resp = requests.get(url=url, headers=self.headers1).json()
        tk.Label(window, text="正在下载,请稍等!").place(x=120, y=180)
        lb = tk.Listbox(window, width=400)
        lb.place(x=0, y=210)
        content = resp["data"]["list"]
        for i in content:
            mid = i["musicrid"].split("_")[-1]
            names = i["name"]
            dic = {"name": names, "url": f"http://www.kuwo.cn/api/v1/www/music/playUrl?mid={mid}&type=convert_url&httpsStatus=1"}
            lb.insert("end", f"正在下载{names}")
            self.download(path, dic)
            lb.insert("end", f"{names}下载完成")

    def download(self, path, dic):  # 下载音乐
        resp = requests.get(url=dic["url"], headers=self.headers2).json()
        dl = resp["data"]["url"]  # 得到的歌曲url
        resp = requests.get(url=dl)
        if resp.status_code == 200:
            rp = resp.content
            if not os.path.exists(f'{path.get()}/music'):
                os.mkdir(f"{path.get()}/music")
            with open(f"{path.get()}/music/{dic['name']}.mp3", "wb") as f:
                f.write(rp)
            tk.messagebox.showinfo(title="success", message=f"{dic['name']}保存成功")


if __name__ == '__main__':
    windows = tk.Tk()  # 实例化对象
    spider = Spider()
    u = Ui(windows, spider)
    windows.mainloop()
posted @ 2022-01-21 17:32  Kenny_LZK  阅读(575)  评论(0编辑  收藏  举报