参考博客:https://www.w3cschool.cn/article/14374
import requests
import os
import time
import re
import urllib
class Downloader():
id=1
def __init__(self):
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36'
}
#根据歌曲名构造完整链接来搜索需要下载的歌曲信息
self.search_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=34725291680541638&t=0&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p=1&n=20&w={}&g_tk=5381&jsonpCallback=MusicJsonCallback703296236531272&loginUin=0&hostUin=0&format=jsonp&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq&needNewCode=0'
#第一个接口返回的信息来构造完整链接来获取歌曲下载地址的部分信息
self.fcg_url = 'https://c.y.qq.com/base/fcgi-bin/fcg_music_express_mobile3.fcg?g_tk=5381&jsonpCallback=MusicJsonCallback9239412173137234&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq&needNewCode=0&cid=205361747&callback=MusicJsonCallback9239412173137234&uin=0&songmid={}&filename={}.m4a&guid=8208467632'
#歌曲下载地址,需要根据前两个接口获取的信息来构造完整链接
self.downloader_url = 'http://dl.stream.qqmusic.qq.com/{}.m4a?vkey={}&guid=8208467632&uin=0&fromtag=66'
def run(self, keyword, num=1):
# Step1
# 根据歌名搜索,获取所需的信息
print('[INFO]:正在搜索歌曲...')
res = requests.get(self.search_url.format(keyword), headers=self.headers).text
# media_mid--通过正则获取多媒体id
media_mid_temp = re.findall('"media_mid":"(.*?)"', res)
media_mid = []
for i in range(len(media_mid_temp)):
media_mid.append('C400'+media_mid_temp[i])
# songmid--通果正则获取歌曲id
songmid = re.findall('"lyric_hilight":".*?","mid":"(.*?)","mv"', res)
# singer--通过正则获取歌手信息
singer_temp = re.findall('"singer":\[.*?\]', res)
singer = []
for s in singer_temp:
singer.append(re.findall('"name":"(.*?)"', s)[0])
# songname
songname = re.findall('},"name":"(.*?)","newStatus"', res)
# Step2
# 获取下载地址
print('[INFO]:正在解析下载地址...')
urls = []
del_idex = []
songname_keep = []
singer_keep = []
for m in range(len(media_mid)):
try:
fcg_res = requests.get(self.fcg_url.format(songmid[m], media_mid[m]), headers=self.headers)
vkey = re.findall('"vkey":"(.*?)"', fcg_res.text)[0]
urls.append(self.downloader_url.format(media_mid[m], vkey))
songname_keep.append(songname[m])
singer_keep.append(singer[m])
except:
print('[Warning]:One song lost...')
time.sleep(0.5)
print("共找到%d首相关歌曲"%(len(urls)))
for i in range(1,len(urls)+1):
print("%d:%s_%s"%(i,songname_keep[i-1],singer_keep[i-1]))
id=input("请选择要下载的歌曲ID号(备注:数字只能为当期所显示的数字ID):")
while(True):
if id.isdigit():
if int(id)>len(urls):
id=input("输入的整数必须为所显示的ID中的一个:")
else:
print('[INFO]:开始下载歌曲...')
break
else:
id=input("请重新输入,ID必须为整数:")
index=int(id)-1
filepath = './results/{}'.format(songname_keep[index].replace("\\", "").replace("/", "").replace(" ", "")+'_'+singer_keep[index].replace("\\", "").replace("/", "").replace(" ", "")+'.m4a')
urllib.request.urlretrieve(urls[index], filepath)
if __name__ == '__main__':
while True:
print('[INFO]:欢迎使用QQ音乐下载器...')
print('[Author]:腾讯音乐')
keyword = input('请输入歌曲名称:')
print("正在初始化参数:")
dl = Downloader()
dl.run(keyword, songnum)