网易云音乐下载软件(下)


前面实现了一个网易云音乐下载器,我们继续进行改进

一. 面向对象设计与多线程

这里增加了一个输入框,与前面方法类似,不做过多阐述,下面是前端展示图:
在这里插入图片描述
如果不加多线程,额外增加的输入框以及其他组件,会使界面运行卡死、无响应。所以增加多线程,保证界面运行不卡顿。

类的设计使程序看起来更简洁明了,调用起来也方便。

多线程的知识 和 面向对象程序设计思想 这里不做过多讲解。
代码如下:
mutithread_music.py

# -*- coding:utf-8 -*-
import tkinter as tk
import threading

import os
from urllib.request import urlretrieve
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

import time
# https://music.163.com/#/search/m/?s=绿色&type=1


class Application(tk.Tk):
    def __init__(self):
        super().__init__()
        self.createUI()

    # 构建浏览器静默模式
    def share_browser(self):
        chrome_options = Options()
        chrome_options.add_argument('--headless')
        chrome_options.add_argument('--disable-gpu')

        # 本机google浏览器路径
        path = r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
        chrome_options.binary_location = path
        driver_path = r'D:\PyCharm 2018\3WebSpiders\网易云音乐下载\chromedriver.exe'
        browser = webdriver.Chrome(chrome_options=chrome_options, executable_path=driver_path)
        return browser

    def song_load(self, item):
        song_id = item['song_id']
        song_name = item['song_name']
        singer_name = item['singer_name']

        song_url = 'http://music.163.com/song/media/outer/url?id={}.mp3'.format(song_id)
        # 歌曲路径
        os.makedirs('music', exist_ok=True)  # 如果文件夹存在,不会报错,不会继续创建
        path = 'music/{}-{}.mp3'.format(song_name, singer_name)

        # 下载提示文本
        self.text.insert(tk.END, '歌曲:{},正在下载.......'.format(song_name))
        # 文本框滚动
        self.text.see(tk.END)
        # 更新
        self.text.update()

        # 计时start
        start = time.clock()
        # 下载
        urlretrieve(song_url, path)
        # 计时end
        end = time.clock()
        # 结果
        cost = end - start

        # 下载完毕
        # 完毕提示文本
        self.text.insert(tk.END, '下载信息:歌曲:{},演唱:{}'.format(song_name, singer_name))
        self.text.insert(tk.END, '下载完毕!共花费{:.2f}s!'.format(cost))
        # 文本框滚动
        self.text.see(tk.END)
        # 更新
        self.text.update()

    def get_music_name(self):
        s_name = self.entry1.get()
        s_singer = self.entry2.get()
        url = 'https://music.163.com/#/search/m/?s={}%20{}&type=1'.format(s_name, s_singer)
        "https://music.163.com/#/search/m/?s=%E7%BB%BF%E8%89%B2%20%E6%A2%A6%E9%80%B8%E9%A3%9E&type=1"

        # path = r'D:\PyCharm 2018\3WebSpiders\网易云音乐下载\chromedriver.exe'
        # driver = webdriver.Chrome(executable_path=path)

        driver = self.share_browser()
        driver.get(url=url)

        driver.switch_to.frame('g_iframe')

        # 获取歌曲id
        req = driver.find_element_by_id('m-search')
        m_id = req.find_element_by_xpath(
            './/div[starts-with(@class,"item f-cb h-flag  ")]//div[2]//a').get_attribute('href')
        singer_name = req.find_element_by_xpath('.//div[starts-with(@class,"item f-cb h-flag  ")]//div[4]//a').text

        song_id = m_id.split('=')[1]
        song_name = req.find_element_by_xpath('.//div[@class="item f-cb h-flag  "]//div[2]//b').get_attribute(
            'title')

        item = {}
        item["song_id"] = song_id
        item["song_name"] = song_name
        item["singer_name"] = singer_name

        self.song_load(item=item)

    # 生成界面
    def createUI(self):
        self.title('网易云下载器')
        self.geometry('620x450')
        self.label = tk.Label(self, text='请输入下载歌曲:', font=('华文行楷', 20))
        self.label.grid(row=0, column=0)

        self.label = tk.Label(self, text='请输入歌手名:', font=('华文行楷', 20))
        self.label.grid(row=1, column=0)

        self.entry1 = tk.Entry(self, font=('隶书', 20), width=22)
        self.entry1.grid(row=0, column=1, sticky=tk.W)

        self.entry2 = tk.Entry(self, font=('隶书', 20), width=22)
        self.entry2.grid(row=1, column=1, sticky=tk.W)

        self.text = tk.Listbox(self, font=('楷书', 20), width=44, height=12)
        self.text.grid(row=2, columnspan=2)

        self.button1 = tk.Button(self, text='下载歌曲', font=('隶书', 15), command=lambda: self.thread_it(self.get_music_name))
        self.button1.grid(row=3, column=0, sticky=tk.W)

        self.button2 = tk.Button(self, text='退出歌曲', font=('隶书', 15), command=lambda: self.thread_it(self.quit))
        self.button2.grid(row=3, column=1, sticky=tk.E)

    @staticmethod
    def thread_it(func, *args):
        t = threading.Thread(target=func, args=args)
        t.setDaemon(True)  # 守护--就算主界面关闭,线程也会留守后台运行(不对!)
        t.start()  # 启动
        # t.join()          # 阻塞--会卡死界面!


app = Application()
app.mainloop()

# pyinstaller -F -w(去除命令行窗口) -i 图片路径 py文件

二. 打包为exe文件

将.py文件打包成.exe文件,可方便的随时运行、下载音乐

下载pyinstaller:
先下载专用打包.py文件到.exe文件的程序

pip install pyinstaller

打开管理员控制台,进入.py文件所在的页面:

pyinstaller -F -w -i [图片名] [py文件名]

我这里是:

pyinstaller -F -w -i mus.ico mutithread_music.py

在这里插入图片描述
图标:
注意这里的图标以.ico结尾,至于图标怎么来的,这里分享一个专用图标网站,可以获取有限的、可以使用的图标:图标下载 (忽略警告)

生成文件:
最后在网易云音乐下载文件夹下,生成3个文件,其中一个.spec文件,其余2个为文件夹,点开dict文件夹,里面的.exe文件即可使用

网易云音乐下载 -
              |

			build - mutithread_music
			  |
			dict - mutithread_music.exe
			  |
			mutithread_music.spec

三. 效果图

在这里插入图片描述

到此就结束了,对于文中的细节部分,如线程、进程与协程,面向对象高级设计,外链的概念与运用,pyinstaller基本使用及其高级使用,tkinter的使用,对于除tkinter更高级的Qt的使用,xpath语法、selenium的使用等等,会在后续更新发表文章。

参考链接:
tkinter界面卡死的解决办法
python tkinter界面卡死的解决办法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值