1.目标
实现输入歌曲名下载歌曲的功能。
2.前期工作
mid=0014WVQT3nDVyz
purl=C4000001xPPq0vaUFU.m4a?guid=6488443882&vkey=9500AB02A1928CBD8BAE5DEE9B7ADB5521EFA232A0E9B941F77BE86B41CAC6726ECE081E248DBEB573CAAD591577B6D1A2F6D24F4476CA8F&uin=0&fromtag=66
3.观察网址
https://isure.stream.qqmusic.qq.com/C4000001xPPq0vaUFU.m4a?guid=6488443882&vkey=9500AB02A1928CBD8BAE5DEE9B7ADB5521EFA232A0E9B941F77BE86B41CAC6726ECE081E248DBEB573CAAD591577B6D1A2F6D24F4476CA8F&uin=0&fromtag=66
不难发现,最终资源的地址是 https://isure.stream.qqmusic.qq.com/加上purl的值。
所以我们的目标变成了获取purl的值。
网址是https://u.y.qq.com/cgi-bin/musics.fcg?-=getplaysongvkey0033131399886299207&g_tk=5381&sign=zzab5dqwy5ttl2c79ca80fa0e018633d46cf549245b83&loginUin=2893403981&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%22001IOmP80alVEv%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
在这里通过对比后发现songmid的取值是可变的,它也就是标识符。这里是qq音乐进行了MD5加密,不用管,只需要知道它是获取purl的前提。
那么songmid的获取与其一样,要知道上一级的mid,就需要知道其文件的网址。
https://c.y.qq.com/soso/fcgi-bin/client_search_cp?ct=24&qqmusic_ver=1298&new_json=1&remoteplace=txt.yqq.song&searchid=70631360004412645&t=0&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p=1&n=10&w=%E9%9D%9E%E9%B1%BC&g_tk_new_20200303=5381&g_tk=5381&loginUin=2272463882&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0
通过归纳可以知道n代表搜索到的歌曲显示数目,w是搜索的关键字,同样用了MD5加密。
4.思路
做好前期工作后,来梳理下思路:通过构造搜索网址传入关键字进行搜索,将要下载的歌曲的mid获取到,以mid构造播放的网址,从而获得purl,最后,构造资源链接进行下载。
话不多说,直接上代码:
#coding="utf-8"
import requests
import re
import os
import json
import time as tclass QQmusic():"""下载qq音乐"""def __init__(self):"""初始化"""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_encodingres_0=res_0.json()#dictmusic_list = res_0["data"]["song"]["list"]print("共计"+str(len(music_list))+"结果: ")all_singers=[]a=0for 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=4, separators=(',', ':'))infs=infs.replace('"',' ')infs=infs.replace(':','——————')print(infs)self.order=input("请输入歌曲前的序号:")songmid=res_0['data']['song']['list'][int(self.order)]['mid']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_encodingres_1=res_1.json()#dictpurl=res_1['req_0']['data']['midurlinfo'][0]['purl']url_2="https://isure.stream.qqmusic.qq.com/"+purlreturn url_2def download(self):"""下载"""res_2=requests.get(self.search(),headers=self.headers).contentfir=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)one_file=QQmusic()
one_file.download()