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¬ice=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¬ice=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¬ice=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