PyQT5+爬虫实现简单音乐下载器
- Qt-Designer界面设计music.ui:
music.py代码实现:
采用PyUIC将music.ui转为music.py,代码如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'music.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(724, 328)
self.label = QtWidgets.QLabel(Form)
self.label.setGeometry(QtCore.QRect(80, 100, 101, 16))
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(Form)
self.label_2.setGeometry(QtCore.QRect(80, 130, 101, 16))
self.label_2.setObjectName("label_2")
self.label_3 = QtWidgets.QLabel(Form)
self.label_3.setGeometry(QtCore.QRect(80, 160, 101, 16))
self.label_3.setObjectName("label_3")
self.lineEdit = QtWidgets.QLineEdit(Form)
self.lineEdit.setGeometry(QtCore.QRect(190, 100, 201, 20))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit_2 = QtWidgets.QLineEdit(Form)
self.lineEdit_2.setGeometry(QtCore.QRect(190, 130, 201, 20))
self.lineEdit_2.setObjectName("lineEdit_2")
self.lineEdit_3 = QtWidgets.QLineEdit(Form)
self.lineEdit_3.setGeometry(QtCore.QRect(190, 160, 201, 20))
self.lineEdit_3.setObjectName("lineEdit_3")
self.label_4 = QtWidgets.QLabel(Form)
self.label_4.setGeometry(QtCore.QRect(140, 30, 151, 20))
font = QtGui.QFont()
font.setFamily("幼圆")
font.setPointSize(14)
self.label_4.setFont(font)
self.label_4.setObjectName("label_4")
self.label_5 = QtWidgets.QLabel(Form)
self.label_5.setGeometry(QtCore.QRect(240, 70, 101, 16))
self.label_5.setObjectName("label_5")
self.pushButton = QtWidgets.QPushButton(Form)
self.pushButton.setGeometry(QtCore.QRect(90, 290, 81, 23))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(Form)
self.pushButton_2.setGeometry(QtCore.QRect(234, 290, 81, 23))
self.pushButton_2.setObjectName("pushButton_2")
self.textEdit = QtWidgets.QTextEdit(Form)
self.textEdit.setGeometry(QtCore.QRect(60, 190, 361, 91))
self.textEdit.setObjectName("textEdit")
self.label_6 = QtWidgets.QLabel(Form)
self.label_6.setGeometry(QtCore.QRect(470, 70, 200, 200))
self.label_6.setText("")
self.label_6.setObjectName("label_6")
self.pushButton_3 = QtWidgets.QPushButton(Form)
self.pushButton_3.setGeometry(QtCore.QRect(530, 290, 111, 23))
self.pushButton_3.setObjectName("pushButton_3")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.label.setText(_translate("Form", "请输入歌手/歌名:"))
self.label_2.setText(_translate("Form", "下载页数:"))
self.label_3.setText(_translate("Form", "歌曲数量:"))
self.label_4.setText(_translate("Form", "音乐下载器"))
self.label_5.setText(_translate("Form", "作者:Nirvana"))
self.pushButton.setText(_translate("Form", "确定"))
self.pushButton_2.setText(_translate("Form", "关闭"))
self.pushButton_3.setText(_translate("Form", "关注,请扫二维码"))
2.主要功能实现
- 获取音乐信息get_music_info
从界面获取歌手/歌名、下载页数和下载歌曲数 - 获取音乐地址get_purl
爬取音乐文件真实的地址 - 保存音乐save_music_mp3
点击确定键,将下载的歌曲保存在当前目录下
main.py代码实现:
# -*- coding: utf-8 -*-
import json
import os
import requests
import sys
from PyQt5.QtGui import QIcon ,QPixmap, QTextCursor
from PyQt5 import QtWidgets
from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QDesktopServices
from music import Ui_Form # 界面
headers = {
'Origin': 'https://y.qq.com',
'Referer': 'https://y.qq.com/portal/search.html',
'Sec-Fetch-Mode': 'cors',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36'
}
class Pyqt5_Music(QtWidgets.QWidget, Ui_Form):
def __init__(self):
super(Pyqt5_Music, self).__init__()
self.setupUi(self)
self.init()
self.setWindowTitle("音乐下载器")
self.setWindowIcon(QIcon('音乐_填充.svg'))
self.lineEdit.setText("")
self.lineEdit_2.setText("")
self.lineEdit_3.setText("")
pix = QPixmap('Nirvana_qrcode.png')
self.label_6.setPixmap(pix)
self.label_6.setScaledContents(True)
def init(self):
self.pushButton.clicked.connect(self.song_ok)
self.pushButton_2.clicked.connect(self.main_exit)
self.pushButton_3.clicked.connect(self.show_child)
def song_ok(self):
music_info_list = self.get_music_info()
music_data = self.get_purl(music_info_list)
self.save_music_mp3(music_data)
def main_exit(self):
sys.exit(self)
def show_child(self):
QDesktopServices.openUrl(QUrl("https://blog.csdn.net/weixin_45355387"))
def get_music_info(self):
music_info_list = []
name = self.lineEdit.text()
page = self.lineEdit_2.text()
num = self.lineEdit_3.text()
# name = input('请输入歌手或歌曲:') # input函数 输入 做用户交互 使用的
# page = input('请输入页码:')
# num = input('请输入当前页码需要返回的数据条数:')
url = f'https://c.y.qq.com/soso/fcgi-bin/client_search_cp?p={
page}&n={
num}&w={
name}'
response = requests.get(url).text # 获取到的是字符串
# 将response切分成json格式 类似字典 但是现在还是字符串
music_json = response[9:-1]
# json转字典
music_data = json.loads(music_json) # 转换成 字典
# print(music_data)
music_list = music_data['data']['song']['list']
for music in music_list:
music_name = music['songname'] # 歌曲的名字
singer_name = music['singer'][0]['name'] # 歌手的名字
songmid = music['songmid']
media_mid = music['media_mid']
music_info_list.append((music_name, singer_name, songmid, media_mid))
return music_info_list
# 获取vkey
def get_purl(self, a):
music_data = []
for music in a:
music_name = music[0]
singer_name = music[1]
songmid = music[2]
url = 'https://u.y.qq.com/cgi-bin/musicu.fcg?data={"req":{"module":"CDN.SrfCdnDispatchServer","method":"GetCdnDispatch","param":{"guid":"8846039534","calltype":0,"userip":""}},"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"8846039534","songmid":["%s"],"songtype":[0],"uin":"1152921504784213523","loginflag":1,"platform":"20"}},"comm":{"uin":"1152921504784213523","format":"json","ct":24,"cv":0}}' % songmid
response = requests.get(url).json() # 如果你获取的数据 是 {} .json() 他会直接帮我们转换成字典
purl = response['req_0']['data']['midurlinfo'][0]['purl']
full_media_url = 'http://dl.stream.qqmusic.qq.com/' + purl
music_data.append(
{
'music_name': music_name,
'singer_name': singer_name,
'full_media_url': full_media_url
}
)
return music_data
def save_music_mp3(self, b):
if not os.path.exists('歌曲下载'): # 判断是否有歌曲下载文件夹
os.mkdir('歌曲下载') # 如果没有创建 歌曲下载文件夹
for music in b:
music_name = music['music_name']
singer_name = music['singer_name']
full_url = music['full_media_url']
music_response = requests.get(full_url, headers=headers).content
with open('歌曲下载/%s-%s.mp3' % (music_name, singer_name), 'wb')as fp:
fp.write(music_response)
print("[%s]保存成功!" % music_name)
self.textEdit.append("[%s-%s.mp3]保存成功!" % (music_name, singer_name))
cursor = self.textEdit.textCursor()
cursor.movePosition(QTextCursor.End) # 还可以有别的位置
self.textEdit.setTextCursor(cursor)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
my_show = Pyqt5_Music()
my_show.show()
sys.exit(app.exec_())