众所周知,我们打开一首音乐的播放界面,查看网络之后,会找到该歌曲的文件资源。附件
但想要自动化下载歌曲就要用到Python的爬虫功能了。我们的目的是通过搜索歌曲名字实现下载歌曲。
具体思路如下:
1.构造歌曲搜索页面。通过多次进行不同的歌曲搜索,发现qq音乐的搜索网址是“https://y.qq.com/portal/search.h ... t.yqq.top&t=song&w=(歌名)”。
2.选定搜索页面下的一首歌,获得它的songmid元素(在网络窗口下面)。
3.下面是带有songmid元素的网址,在其内容中有我们需要的purl值。
https://u.y.qq.com/cgi-bin/musics.fcg?-=getplaysongvkey773024428988422&g_tk=5381&sign=zzaqwdsqviw7n2jqca9fe6ef9bd04052e35789050f653693d&loginUin=1356794567&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0&data=%7B%22req%22%3A%7B%22module%22%3A%22CDN.SrfCdnDispatchServer%22%2C%22method%22%3A%22GetCdnDispatch%22%2C%22param%22%3A%7B%22guid%22%3A%226488443882%22%2C%22calltype%22%3A0%2C%22userip%22%3A%22%22%7D%7D%2C%22req_0%22%3A%7B%22module%22%3A%22vkey.GetVkeyServer%22%2C%22method%22%3A%22CgiGetVkey%22%2C%22param%22%3A%7B%22guid%22%3A%226488443882%22%2C%22songmid%22%3A%5B%220036dAdb3jzsE1%22%5D%2C%22songtype%22%3A%5B0%5D%2C%22uin%22%3A%222272463882%22%2C%22loginflag%22%3A1%2C%22platform%22%3A%2220%22%7D%7D%2C%22comm%22%3A%7B%22uin%22%3A2272463882%2C%22format%22%3A%22json%22%2C%22ct%22%3A24%2C%22cv%22%3A0%7D%7D
4.获得到purl值后,我们发现其歌曲资源链接是"https://isure.stream.qqmusic.qq.com/"+purl
5.最后就像下载小说一样将自己喜欢的歌曲成功下载下来了!
源码分享:
[Python] 纯文本查看 复制代码
#coding="utf-8"
import requests
import re
import os
import json
class QQmusic():
"""下载qq音乐"""
def __init__(self):
"""初始化,将headers、names和order设置为全局变量"""
self.headers={
'Accept-Encoding': 'gzip, deflate, sdch',
'Accept-Language': 'en-US,en;q=0.8',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Referer': 'http://www.baidu.com/',
'Connection': 'keep-alive',
}#请求头
self.names=[]#歌曲名列表
self.order=' '#歌曲序号
def search(self):
"""搜索、定位歌曲,构造资源链接"""
w=input("请输入歌曲名: ")
url_0="https://c.y.qq.com/soso/fcgi-bin/client_search_cp?ct=24&qqmusic_ver=1298&new_json=1&remoteplace=txt.yqq.song&searchid=61460539676714578&t=0&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p=1&n=10&w={0}&g_tk_new_20200303=5381&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0".format(w)
res_0=requests.get(url_0,headers=self.headers)#第一层,搜索页
res_0.encoding=res_0.apparent_encoding#将页面原有编码转化为备用编码
res_0=res_0.json()#返回dict形式的歌曲列表
music_list = res_0["data"]["song"]["list"]#获取歌曲列表
print("共计"+str(len(music_list))+"结果: ")
all_singers=[]#歌手列表
a=0#序号计数
for music in music_list:
singer=music["singer"][0]["title"]#歌手名
name=str(a)+" "+music["title"]#歌曲名
all_singers.append(singer)
self.names.append(name)
a=a+1
infs=dict(zip(self.names, all_singers))#构建歌曲与歌手的关系
infs=json.dumps(infs, ensure_ascii=False,indent=5)#将字典类型转换为字符串
#便于展示歌曲列表
infs=infs.replace('"',' ')
infs=infs.replace('{',' ')
infs=infs.replace('}',' ')
infs=infs.replace(':','——————')
print(infs)#输出歌曲列表
self.order=input("请输入歌曲前的序号:")
songmid=res_0['data']['song']['list'][int(self.order)]['mid']#根据序号找到对应的songmid
url_1="https://u.y.qq.com/cgi-bin/musicu.fcg?format=json&data=%7B%22req_0%22%3A%7B%22module%22%3A%22vkey.GetVkeyServer%22%2C%22method%22%3A%22CgiGetVkey%22%2C%22param%22%3A%7B%22guid%22%3A%22358840384%22%2C%22songmid%22%3A%5B%22{}%22%5D%2C%22songtype%22%3A%5B0%5D%2C%22uin%22%3A%221443481947%22%2C%22loginflag%22%3A1%2C%22platform%22%3A%2220%22%7D%7D%2C%22comm%22%3A%7B%22uin%22%3A%2218585073516%22%2C%22format%22%3A%22json%22%2C%22ct%22%3A24%2C%22cv%22%3A0%7D%7D".format(songmid)
res_1=requests.get(url_1,headers=self.headers)
res_1.encoding=res_1.apparent_encoding
res_1=res_1.json()#dict
purl=res_1['req_0']['data']['midurlinfo'][0]['purl']
url_2="https://isure.stream.qqmusic.qq.com/"+purl#资源链接
return url_2
def download(self):
"""下载"""
res_2=requests.get(self.search(),headers=self.headers).content
fir=self.names[int(self.order)]
tit=re.sub(r'\d+','',fir)#提取歌曲名
now=os.getcwd()
now=os.path.join(now,"qq音乐 ")
if not os.path.exists(now):
os.mkdir(now)#构造文件夹
os.chdir(now)#将下载的歌曲存储在该文件夹
file_name=tit+'.m4a'#文件名
with open(file_name,'wb') as f:
f.write(res_2)
print("下载成功!")
if __name__ == "__main__":
one_file=QQmusic()#实例调用
one_file.download()
|