Python打造qq音乐歌曲下载器

Python打造qq音乐歌曲下载器

桌面应用程序,GUI

tkinter import TK:python自带的,简单,好入门,但较丑

另外比较美观的:

wxpython

pyqt5,它不是python独有的,其他语言中也可以用到。它的本质是基于面向对象开发的。

零基础也可以快速搭建GUI界面,

安装pyqt5:

pip3 install pyqt5 

安装pyqt5_tools:

pip3 install pyqt5-tools

在pycharm中配置pyqt5-tools工具:(可选的)

https://www.jb51.net/article/156026.htm

安装成功以后,我们打开pyqt5_tools文件夹:
在这里插入图片描述
它的目录结构如图所示:
在这里插入图片描述
我们打开 Qt文件夹 -> bin文件夹
可以看到:
在这里插入图片描述
如图,我们打开 designer.exe
可以看到:
在这里插入图片描述
这样一个界面就是我们即将使用的UI界面搭建工具。

搭建应用程序界面

1、创建主窗口:
在这里插入图片描述
2、通过拖拽组件绘制主界面
在这里插入图片描述
3、选中输入框,添加隐藏性提示文字
在这里插入图片描述
4、修改窗口标题
在这里插入图片描述
界面搭建好了以后,我们把它保存到桌面:
在这里插入图片描述
我们使用notepad++打开,可以看到它的格式是这样的:
在这里插入图片描述
这样的.ui文件是无法直接提供给python使用的。
我们需要使用pyuic5把它转换为.py文件
启动cmd命令行,输入以下命令:

pyuic5 -o demo.py untitled1.ui

demo.py是我们自定义的生成.py文件的名称。
执行完毕之后,桌面即生成了demo.py文件

运行该界面:
导入sys模块:

import sys #使窗口可以关闭
if __name__=='__main__':
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()    #装载各个组件
    ui = Ui_MainWindow()    #创建该类的实例对象
    ui.setupUi(MainWindow)  #把组件传递进来

    MainWindow.show()   #显示出来
    sys.exit(app.exec())    #绑定程序退出时,关闭窗口

执行结果:
在这里插入图片描述

实现功能,下载音乐

我们通过网页版QQ音乐,搜索一首歌曲,发现它的链接是:
https://y.qq.com/portal/search.html#page=1&searchid=1&remoteplace=txt.yqq.top&t=song&w=%E6%A1%A5%E8%BE%B9%E5%A7%91%E5%A8%98
最后一个参数w = 歌曲名称。
这样一个链接我们先保存下来,指不定待会要用到。
我们点击它搜索到的歌曲列表的第一首(我们仅仅下载第一首歌)
在这里插入图片描述
这个url是:https://y.qq.com/n/yqq/song/001zLvbN1NYMuv.html
它实际上包含了歌曲的 ID :001zLvbN1NYMuv
有了歌曲 ID,如何下载?
能不自己动手,就不自己动手。
python有很多很多的第三方的工具。
我们打开网站:QQ音乐无损接口api
我们把刚才复制的url粘贴进来,点击查询:
在这里插入图片描述
我们现在就通过这个api
我们右键检查,找到network,再次重新查询:
在这里插入图片描述
在这里插入图片描述
mid就是携带歌曲id的那个粘贴过来的url,也就是这首歌的播放链接。
Preview:
在这里插入图片描述
在这里插入图片描述
有了这个接口,我们就可以下载音乐了。
接口:http://www.douqq.com/qqmusic/qqapi.php
让这个接口来帮助我们解析。

我们请求刚刚复制的搜索的url:

url = 'https://y.qq.com/portal/search.html#page=1&searchid=1&remoteplace=txt.yqq.top&t=song&w=%E6%A1%A5%E8%BE%B9%E5%A7%91%E5%A8%98'
resp = requests.get(url)
print(resp.text)

在结果中找寻歌曲ID:
在这里插入图片描述
发现找不到我们所需要的歌曲ID。
那就意味着我们的请求链接很可能没有找对。

那我们回过头来,重新寻找。
在这里插入图片描述
这样就找到了包含歌曲ID请求链接:
在这里插入图片描述
它才是我们需要请求的地址:
https://c.y.qq.com/soso/fcgi-bin/client_search_cp?ct=24&qqmusic_ver=1298&new_json=1&remoteplace=txt.yqq.top&searchid=20195022171686391&t=0&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p=1&n=10&w=%E6%A1%A5%E8%BE%B9%E5%A7%91%E5%A8%98&g_tk_new_20200303=1805662696&g_tk=1805662696&loginUin=1543660640&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0

替换刚才的请求地址,程序打印后的结果是:
在这里插入图片描述

现在我们需要从中提取出歌曲的ID
这时候我们就需要用到一个工具:jsonpath

import jsonpath
url = 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp?ct=24&qqmusic_ver=1298&new_json=1&remoteplace=txt.yqq.top&searchid=20195022171686391&t=0&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p=1&n=10&w=%E6%A1%A5%E8%BE%B9%E5%A7%91%E5%A8%98&g_tk_new_20200303=1805662696&g_tk=1805662696&loginUin=1543660640&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0'
resp = requests.get(url)
# 数据类型转换:转换为json
html_doc = resp.json() #它是自带的方法
# 解析:利用jsonpath找到根节点$下的,任何路径下的mid
mids = jsonpath.jsonpath(html_doc,"$..mid")
print(mids)

打印结果是搜索关键字后得到的一个一个的歌曲ID:
在这里插入图片描述
有了歌曲ID,我们通过字符串拼接,即可得出完成的歌曲播放地址。
我们先把请求头转换为字典格式:
在这里插入图片描述
源匹配:

(.*): (.*)$

替换匹配:

"$1": "$2",

请求接口:

# 接口地址
link = 'http://www.douqq.com/qqmusic/qqapi.php'
# 请求这个接口的时候是需要携带参数的,参数就是拼接好的歌曲链接,请求方式为post
data = {'mid':'https://y.qq.com/n/yqq/song/001zLvbN1NYMuv.html'}
# 请求头
headers = {
    "Accept": "application/json, text/javascript, */*; q=0.01",
    "Accept-Encoding": "gzip, deflate",
    "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
    "Connection": "keep-alive",
    "Content-Length": "65",
    "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
    "Host": "www.douqq.com",
    "Origin": "http://www.douqq.com",
    "Referer": "http://www.douqq.com/qqmusic/",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36",
    "X-Requested-With": "XMLHttpRequest",
    }
req = requests.post(link,data=data,headers=headers)
print(req.text)

得到的结果为:
在这里插入图片描述
它里面包含了我们要下载的歌曲链接。

http:\\\/\\\/aqqmusic.tc.qq.com\\\/amobile.music.tc.qq.com\\\/C400001zLvbN1NYMuv.m4a

但是我们可以看到这个链接格式有点问题。
复制这个链接是打不开的。
我们需要使用正则表达式来进行字符串的处理。
由于它是一个json格式的内容,我们首先需要进行一个数据类型转换。

import json
req = requests.post(link,data=data,headers=headers)
# 将响应结果转换为字符串
reqText = req.text
print(reqText)
# 将字符串转换为json格式
reqJson = json.loads(reqText)
reqJson = reqJson.replace('\/','/')
print(reqJson)

可以看到:
在这里插入图片描述
链接已经变为正常的格式。

可以选择m4a格式,mp3普通品质的,mp3高品质的等等。
我们仅仅只下载它的m4a格式的,
找到m4a格式的:
在这里插入图片描述
然后需要使用正则表达式提取我们需要的内容:

import re
# regex
res = re.compile('"m4a":"(.*?)",')
result = re.findall(res,reqJson)
print(result)

结果:
在这里插入图片描述
然后我们就导入一个模块,进行下载:

from urllib.request import urlretrieve
music = result[0]
urlretrieve(music,'桥边姑娘.mp3')

然后我们就得到了这样的一首歌:
在这里插入图片描述
我们发现尽管我们选择的是m4a格式进行的下载,保存成mp3格式也是好使的。


然后我们把爬虫代码封装为一个函数,方便与界面进行整合。
改变请求地址中url的歌曲名称部分,它是w参数的内容,改变其为可变内容。
在这里插入图片描述
获取我们输入的歌曲名称:

musicName = self.lineEdit.text()

格式化字符串可变的部分:

url = 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp?ct=24&qqmusic_ver=1298&new_json=1&remoteplace=txt.yqq.top&searchid=20195022171686391&t=0&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p=1&n=10&w={}&g_tk_new_20200303=1805662696&g_tk=1805662696&loginUin=1543660640&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0'.format(musicName)
data = {'mid': 'https://y.qq.com/n/yqq/song/{}.html'.format(mids[0])}
urlretrieve(music, musicName+'.mp3')

接下来我们为“下载”按钮绑定单击事件:
需要在函数setupUi()的末尾绑定单击事件.

   #绑定按钮的单击事件
   self.pushButton.clicked.connect(self.download_music)

注意这里调用的download_music一定不要加括号!!!

到此为止我们的程序就全部写完了。
当然这仅仅是一个小案例,可以扩展的地方还有很多。

案例源码,提取码 x91z
打包后的exe文件,提取码 t9ex

猜你喜欢

转载自blog.csdn.net/qq_43598138/article/details/106156032