相关文章推荐
近视的橙子  ·  python ...·  2 周前    · 
腼腆的烈马  ·  [Anaconda]——Linux下cond ...·  1 周前    · 
眉毛粗的电梯  ·  python ...·  1 周前    · 
沉着的抽屉  ·  python for循环 ...·  6 天前    · 
火星上的楼梯  ·  Mysql工具类:根据python ...·  23 小时前    · 
留胡子的扁豆  ·  sql ...·  3 月前    · 
坏坏的蚂蚁  ·  Java重新加载类之Attach ...·  1 年前    · 
当python遇上付费音乐时,你会自己弄一个简单的音乐下载器嘛?

当python遇上付费音乐时,你会自己弄一个简单的音乐下载器嘛?

导语:

哈喽,哈喽~在许多音乐软件开始进行付费的模式下,大家是如何进行听歌的呢?

今天呢,小编用 python制造一个简单的音乐下载器 ,解决要下载多个音乐App和听歌需要vip的情况!

正文:

Python版本:3.7.8

相关模块:

  • PyQt5模块;
  • musicdl模块;
  • 以及一些python自带的模块。

环境搭建:

安装Python并添加到环境变量,pip安装需要的相关模块即可。

原理简介:

这里介绍一下实现原理,先给大家看一下最终的效果:(后附运行视频展示)

首先我们安装一下必要的库文件:

  pip install musicdl, pyqt5

然后初始化我们的音乐下载器界面:

'''音乐下载器GUI界面'''
class MusicdlGUI(QWidget):
    def __init__(self, parent=None):
        super(MusicdlGUI, self).__init__()
        # 初始化
        config = {'logfilepath': 'musicdl.log', 'savedir': 'downloaded', 'search_size_per_source': 2, 'proxies': {}}
        self.music_api = musicdl.musicdl(config=config)
        self.setWindowTitle('音乐下载器GUI界面')
        self.setWindowIcon(QIcon(os.path.join(os.path.dirname(__file__), 'icon.ico')))
        self.setFixedSize(900, 480)
        self.initialize()

效果是这样子的:

接下来我们需要做的就是一点点往界面上添加我们需要的组件。先添加音乐下载器的搜索源相关的组件:

self.src_names = ['QQ音乐', '酷我音乐', '咪咕音乐', '千千音乐', '酷狗音乐', '网易云音乐']
self.label_src = QLabel('搜索源:')
self.check_boxes = []
for src in self.src_names:
    cb = QCheckBox(src, self)
    cb.setCheckState(QtCore.Qt.Checked)
    self.check_boxes.append(cb)

效果如下:

然后添加搜索框:

self.label_keyword = QLabel('搜索关键字:')
self.lineedit_keyword = QLineEdit('音乐下载器GUI界面')
self.button_keyword = QPushButton('搜索')

效果如下:

接着添加进度条和搜索结果框等组件:

# 搜索结果表格
self.results_table = QTableWidget()
self.results_table.setColumnCount(7)
self.results_table.setHorizontalHeaderLabels(['序号', '歌手', '歌名', '大小', '时长', '专辑', '来源'])
self.results_table.horizontalHeader().setStyleSheet("QHeaderView::section{background:skyblue;color:black;}")
self.results_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.results_table.setSelectionBehavior(QAbstractItemView.SelectRows)
# 鼠标右键点击的菜单
self.context_menu = QMenu(self)
self.action_download = self.context_menu.addAction('下载')
# 进度条
self.bar_download = QProgressBar(self)
self.label_download = QLabel('歌曲下载进度:')

就可以得到如下结果了:

最后,我们来实现一些必要的响应函数,比如搜索按钮:

 '''搜索'''
def search(self):
    self.initialize()
    target_srcs_dict = {
        'QQ音乐': 'qqmusic', 
        '酷我音乐': 'kuwo', 
        '咪咕音乐': 'migu', 
        '千千音乐': 'qianqian', 
        '酷狗音乐': 'kugou', 
        '网易云音乐': 'netease',
    selected_src_names = []
    for cb in self.check_boxes:
        if cb.isChecked():
            selected_src_names.append(cb.text())
    target_srcs = [target_srcs_dict.get(name) for name in selected_src_names]
    keyword = self.lineedit_keyword.text()
    self.search_results = self.music_api.search(keyword, target_srcs)
    count, row = 0, 0
    for value in self.search_results.values():
        count += len(value)
    self.results_table.setRowCount(count)
    for _, (key, values) in enumerate(self.search_results.items()):
        for _, value in enumerate(values):
            for column, item in enumerate([str(row), value['singers'], value['songname'], value['filesize'], value['duration'], value['album'], value['source']]):
                self.results_table.setItem(row, column, QTableWidgetItem(item))
                self.results_table.item(row, column).setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
            self.music_records.update({str(row): value})
            row += 1
    return self.search_results

鼠标右键选中下载:

 '''鼠标右键点击事件'''
def mouseclick(self):
    self.context_menu.move(QCursor().pos())
    self.context_menu.show()

以及下载功能:

 '''下载'''
def download(self):
    self.selected_music_idx = str(self.results_table.selectedItems()[0].row())
    songinfo = self.music_records.get(self.selected_music_idx)
    headers = Downloader(songinfo).headers
    checkDir(songinfo['savedir'])
    with requests.get(songinfo['download_url'], headers=headers, stream=True, verify=False) as response:
        if response.status_code == 200:
            total_size, chunk_size, download_size = int(response.headers['content-length']), 1024, 0
            with open(os.path.join(songinfo['savedir'], songinfo['savename']+'.'+songinfo['ext']), 'wb') as fp:
                for chunk in response.iter_content(chunk_size=chunk_size):