利用python下载酷狗音乐
# -*- coding: utf-8 -*-import string
import time
import re
import random
import requests
import pprint
'''
==========================================酷狗音乐解析主要API=============================================
1.get_rank_list() 获取音乐榜单列表 返回形式:(榜单名,榜单地址)
2.get_rank_info(url)url为榜单地址 返回歌曲的信息[{}]
3.get_search_musicData(search_txt,dis_num) search_txt:搜索内容,dis_num:总共加载几首歌曲,返回歌曲的信息[{}]
=========================================内部函数=========================================================
4.get_musicInfo(hash,id)通过传入的hash、id 返回歌名、播放地址、图片、歌词 字典形式
返回形式:music_info_dic={'audio_name':XXXX,'play_url':XXXX,'lyrics':XXX,'img':XXX}
5.klcTolrc(self,lyrics)通过传入获取的krc歌词 变成lrc形式的歌词
========================================================================================================
可以用主函数测试
'''
class kuGouMusic ():
def __init__(self):
self.headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36', }
def __get_response(self, url, headers):
res = requests.get (url, headers)
return res
# 获取酷狗音乐榜单
def get_rank_list(self):
rank_url = 'https://www.kugou.com/yy/html/rank.html'
res = self.__get_response (rank_url, self.headers)
res.encoding = res.apparent_encoding
rank_list_urls = re.findall (r'<a title="(.*?)" .*? hidefocus="true" href="(.*?)"', res.text)
return rank_list_urls
# 获取榜单的Hash、id
def get_rank_info(self, url):
res = self.__get_response (url, self.headers)
res.encoding = res.apparent_encoding
Hash_list = re.findall ('"Hash":"(.*?)"', res.text)
album_id_list = re.findall ('"album_id":(.*?),', res.text)
play_list = []
num=0
for Hash, album_id in zip (Hash_list, album_id_list):
print (f'\r正在加歌单歌曲列表,....当前进度:{int ((num + 1) / len (Hash_list) * 100)}%', end='')
play_list.append (self.__get_musicInfo (Hash, album_id))
num=num+1
return play_list
# ======================以下是搜索部分=============#
def get_search_musicData(self,word='任贤齐',page_mum=1):
url = 'http://mobilecdn.kugou.com/api/v3/search/song'
data_list=[]
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36'
}
parameter={
'keyword': word,
'page': page_mum,
'pagesize': '30',
}
res = requests.get(url, headers=headers,params=parameter).json()
info_list=res['data']['info']
num=0
for info in info_list:
print (f'\r正在加载搜索歌曲列表,....当前进度:{int ((num + 1) / len (info_list) * 100)}%', end='')
data_list.append(self.__get_musicInfo(info['hash'],info['album_id']))
num=num+1
return data_list
# ======================通过Hash,id获取到歌曲地址、LRC、封面、歌曲名共用部分=============#
# 获取歌曲信息 hash 为字符串 id为整型数据
def __get_musicInfo(self, hash, id):
music_url = 'https://wwwapi.kugou.com/yy/index.php'
parameter = {
'r': 'play/getdata',
'hash': hash,
'dfid': self.__get_dfid (23),
'mid': self.__get_mid (23),
'album_id': id,
'_': str (round (time.time () * 1000))# 时间戳
}
json_data = requests.get (music_url, headers=self.headers, params=parameter).json ()
music_info_dic = {
'audio_name': json_data['data']['audio_name'],
'play_url': json_data['data']['play_url'],
'lyrics': self.__klcTolrc(json_data['data']['lyrics']),
'img_conntent': json_data['data']['img']
}
return music_info_dic
# 获取a-z A-Z 0-9组成的随机23位数列
def __get_dfid(self, num):
random_str = ''.join (random.sample ((string.ascii_letters + string.digits), num))
return random_str
# 获取a-z0-9组成的随机23位数列
def __get_mid(self, num):
random_str = ''.join (random.sample ((string.ascii_letters[:26] + string.digits), num))
return random_str
# krc转成lrc
def __klcTolrc(self, lyrics):
index = lyrics.find ('[00:00')
lyrics = lyrics
return lyrics
if __name__ == '__main__':
d = kuGouMusic ()
# url='https://www.kugou.com/yy/rank/home/1-8888.html?from=rank'
# lis=d.get_rank_info(url)
# pprint.pprint(lis)
lis2=d.get_search_musicData()
print(lis2)
本帖最后由 LeonSmith153 于 2023-11-15 01:04 编辑
感觉蛮好的,改进了一下代码,可以将搜索到的歌曲进行分行列出,用户可以根据需要选择要保存的歌词文件。
# -*- coding: utf-8 -*-
import string
import time
import re
import random
import requests
import pprint
'''
==========================================酷狗音乐解析主要API=============================================
1.get_rank_list() 获取音乐榜单列表 返回形式:(榜单名,榜单地址)
2.get_rank_info(url)url为榜单地址 返回歌曲的信息[{}]
3.get_search_musicData(search_txt,dis_num) search_txt:搜索内容,dis_num:总共加载几首歌曲,返回歌曲的信息[{}]
=========================================内部函数=========================================================
4.get_musicInfo(hash,id)通过传入的hash、id 返回歌名、播放地址、图片、歌词 字典形式
返回形式:music_info_dic={'audio_name':XXXX,'play_url':XXXX,'lyrics':XXX,'img':XXX}
5.klcTolrc(self,lyrics)通过传入获取的krc歌词 变成lrc形式的歌词
========================================================================================================
可以用主函数测试
'''
class kuGouMusic ():
def __init__(self):
self.headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36', }
def __get_response(self, url, headers):
res = requests.get (url, headers)
return res
# 获取酷狗音乐榜单
def get_rank_list(self):
rank_url = 'https://www.kugou.com/yy/html/rank.html'
res = self.__get_response (rank_url, self.headers)
res.encoding = res.apparent_encoding
rank_list_urls = re.findall (r'<a title="(.*?)" .*? hidefocus="true" href="(.*?)"', res.text)
return rank_list_urls
# 获取榜单的Hash、id
def get_rank_info(self, url):
res = self.__get_response (url, self.headers)
res.encoding = res.apparent_encoding
Hash_list = re.findall ('"Hash":"(.*?)"', res.text)
album_id_list = re.findall ('"album_id":(.*?),', res.text)
play_list = []
num=0
for Hash, album_id in zip (Hash_list, album_id_list):
print (f'\r正在加歌单歌曲列表,....当前进度:{int ((num + 1) / len (Hash_list) * 100)}%', end='')
play_list.append (self.__get_musicInfo (Hash, album_id))
num=num+1
return play_list
# ======================以下是搜索部分=============#
def get_search_musicData(self,word='任贤齐',page_mum=1):
url = 'http://mobilecdn.kugou.com/api/v3/search/song'
data_list=[]
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36'
}
parameter={
'keyword': word,
'page': page_mum,
'pagesize': '30',
}
res = requests.get(url, headers=headers,params=parameter).json()
info_list=res['data']['info']
num=0
for info in info_list:
print (f'\r正在加载搜索歌曲列表,....当前进度:{int ((num + 1) / len (info_list) * 100)}%', end='')
data_list.append(self.__get_musicInfo(info['hash'],info['album_id']))
num=num+1
return data_list
# ======================通过Hash,id获取到歌曲地址、LRC、封面、歌曲名共用部分=============#
# 获取歌曲信息 hash 为字符串 id为整型数据
def __get_musicInfo(self, hash, id):
music_url = 'https://wwwapi.kugou.com/yy/index.php'
parameter = {
'r': 'play/getdata',
'hash': hash,
'dfid': self.__get_dfid (23),
'mid': self.__get_mid (23),
'album_id': id,
'_': str (round (time.time () * 1000))# 时间戳
}
json_data = requests.get (music_url, headers=self.headers, params=parameter).json ()
music_info_dic = {
'audio_name': json_data['data']['audio_name'],
'play_url': json_data['data']['play_url'],
'lyrics': self.__klcTolrc(json_data['data']['lyrics']),
'img_conntent': json_data['data']['img']
}
return music_info_dic
# 获取a-z A-Z 0-9组成的随机23位数列
def __get_dfid(self, num):
random_str = ''.join (random.sample ((string.ascii_letters + string.digits), num))
return random_str
# 获取a-z0-9组成的随机23位数列
def __get_mid(self, num):
random_str = ''.join (random.sample ((string.ascii_letters[:26] + string.digits), num))
return random_str
# krc转成lrc
def __klcTolrc(self, lyrics):
index = lyrics.find ('[00:00')
lyrics = lyrics
return lyrics
if __name__ == '__main__':
d = kuGouMusic ()
# url='https://www.kugou.com/yy/rank/home/1-8888.html?from=rank'
# lis=d.get_rank_info(url)
# pprint.pprint(lis)
lis2=d.get_search_musicData()
print("\n")
for i in range(len(lis2)):
i_audio_name = lis2['audio_name']
i_play_url = lis2['play_url']
#i_lyrics = lis2['lyrics']
i_img_conntent = lis2['img_conntent']
print(str(i) + "--->" + i_audio_name)
print(i_play_url)
print(i_img_conntent)
print("请输入要保存的歌词索引:")
number = input()
with open(lis2['audio_name'] + "_lyrics.txt", 'w') as f:
f.write(str(lis2['lyrics']))
#print(lis2)
感谢楼主分享,我将代码转换成了PHP的API接口,可以放到自己的网站上
<?php
class kuGouMusicAPI {
private $headers = array(
'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36'
);
private function __get_response($url, $headers) {
$res = file_get_contents($url, false, stream_context_create(array('http' => $headers)));
return $res;
}
public function getRankList() {
$rank_url = 'https://www.kugou.com/yy/html/rank.html';
$res = $this->__get_response($rank_url, $this->headers);
preg_match_all('/<a title="(.*?)" .*? hidefocus="true" href="(.*?)"/', $res, $matches, PREG_SET_ORDER, 1);
$rank_list_urls = array_slice($matches, 1);
return $rank_list_urls;
}
public function getRankInfo($url) {
$res = $this->__get_response($url, $this->headers);
preg_match_all('/"Hash":"(.*?)"/', $res, $hash_matches);
preg_match_all('/"album_id":(.*?),/', $res, $album_id_matches);
$Hash_list = $hash_matches;
$album_id_list = $album_id_matches;
$play_list = array();
foreach ($Hash_list as $index => $Hash) {
$album_id = $album_id_list[$index];
$play_list[] = $this->__get_musicInfo($Hash, $album_id);
}
return $play_list;
}
public function getSearchMusicData($word = '任贤齐', $page_num = 1) {
$url = 'http://mobilecdn.kugou.com/api/v3/search/song';
$data_list = array();
$parameter = array(
'keyword' => $word,
'page' => $page_num,
'pagesize' => '30'
);
$res = file_get_contents($url . '?' . http_build_query($parameter), false, stream_context_create(array('http' => $this->headers)));
$res = json_decode($res, true);
$info_list = $res['data']['info'];
foreach ($info_list as $info) {
$data_list[] = $this->__get_musicInfo($info['hash'], $info['album_id']);
}
return $data_list;
}
private function __get_musicInfo($hash, $id) {
$music_url = 'https://wwwapi.kugou.com/yy/index.php';
$parameter = array(
'r' => 'play/getdata',
'hash' => $hash,
'dfid' => $this->__get_dfid(23),
'mid' => $this->__get_mid(23),
'album_id' => $id,
'_' => round(microtime(true) * 1000)
);
$music_json = $this->__get_response($music_url . '?' . http_build_query($parameter), $this->headers);
$music_info = json_decode($music_json, true);
$music_info_dic = array(
'audio_name' => $music_info['data']['audio_name'],
'play_url' => $music_info['data']['play_url'],
'lyrics' => $this->__klcTolrc($music_info['data']['lyrics']),
'img_conntent' => $music_info['data']['img']
);
return $music_info_dic;
}
private function __get_dfid($num) {
$random_str = substr(str_shuffle(str_repeat('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', $num)), 0, $num);
return $random_str;
}
private function __get_mid($num) {
$random_str = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz0123456789'), 0, $num);
return $random_str;
}
private function __klcTolrc($lyrics) {
$index = strpos($lyrics, '[00:00');
$lyrics = substr($lyrics, $index);
return $lyrics;
}
}
// 创建API实例
$kuGouAPI = new kuGouMusicAPI();
// 处理API请求
if (isset($_GET['action'])) {
$action = $_GET['action'];
switch ($action) {
case 'getRankList':
$result = $kuGouAPI->getRankList();
echo json_encode($result);
break;
case 'getRankInfo':
if (isset($_GET['url'])) {
$url = $_GET['url'];
$result = $kuGouAPI->getRankInfo($url);
echo json_encode($result);
} else {
echo json_encode(array('error' => 'Missing "url" parameter.'));
}
break;
case 'getSearchMusicData':
$word = isset($_GET['word']) ? $_GET['word'] : '任贤齐';
$page_num = isset($_GET['page_num']) ? $_GET['page_num'] : 1;
$result = $kuGouAPI->getSearchMusicData($word, $page_num);
echo json_encode($result);
break;
default:
echo json_encode(array('error' => 'Invalid action.'));
}
} else {
echo json_encode(array('error' => 'Missing "action" parameter.'));
}
?>
用法:
获取音乐榜单列表:http://your-api-url/api.php?action=getRankList
获取榜单详细信息:http://your-api-url/api.php?action=getRankInfo&url=https://www.kugou.com/yy/rank/home/1-8888.html?from=rank
搜索音乐数据:http://your-api-url/api.php?action=getSearchMusicData&word=关键词&page_num=1
action:确定要执行的操作,可以是以下之一:
getRankList:获取音乐榜单列表。
getRankInfo:获取榜单的详细信息,需要提供url参数指定榜单的地址。
getSearchMusicData:搜索音乐数据,可以提供以下参数:
word:搜索关键词,默认为'任贤齐'。
page_num:搜索结果的页数,默认为1。 LeonSmith153 发表于 2024-1-22 20:48
只是获取了资源链接喝资源信息,你根据链接下载对应的音乐资源就好了
谢谢大佬,不懂代码的小白不好意思哈哈 复制代码粘贴保存为py文件运行后,出现以下错误,请问是接口变了吗?
in __get_musicInfo
'audio_name': json_data['data']['audio_name'],
TypeError: list indices must be integers or slices, not str 多谢楼主分享。 多谢楼主分享。 可以下载无损吗?
多谢楼主分享。
多谢楼主分享。
多谢楼主分享。 学习了,膜拜 谢谢楼主,很有用 做个小程序就好!