music-api-kuwo-fast-api/main.py
2023-06-09 01:13:55 +08:00

425 lines
13 KiB
Python

from fastapi import FastAPI # 导入FastAPI
from fastapi.middleware.cors import CORSMiddleware
import uvicorn # uvicorn:主要用于加载和提供应用程序的服务器
import requests
import json
import os
env = os.environ
headers = {
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Host': 'www.kuwo.cn',
'referer': 'https://www.kuwo.cn/',
'user-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/103.0.5060.114 Safari/537.36 Edg/103.0.1264.49'
}
# 创建一个app实例
app = FastAPI() if env.get("docs") is not None and env.get("docs").lower() == "true" else FastAPI(openapi_url=None)
# 配置 CORS 中间件
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 允许所有来源,可以根据需求进行配置
allow_credentials=True,
allow_methods=["*"], # 允许所有请求方法
allow_headers=["*"], # 允许所有请求头
)
# 获取酷我cookie
url = 'https://www.kuwo.cn/'
r = requests.get(url, headers=headers)
cookies = r.cookies.get('kw_token')
csrf = cookies
headers['csrf'] = csrf
headers['Cookie'] = r.headers['Set-Cookie']
# 专辑相关
# 专辑信息
@app.get("/albumInfo")
async def album_info(albumId: int = None, page: int = 1, size: int = 20):
if albumId is None:
info = {
"code": 403,
"msg": "Invalid Request"
}
return info
url = f'http://www.kuwo.cn/api/www/album/albumInfo?albumId={albumId}&pn={page}' \
f'&rn={size}&httpsStatus=1'
r = requests.get(url, headers=headers)
data = json.loads(r.text)["data"]
songList = data["musicList"]
info = {
"code": 200,
"msg": "success",
"total": data["total"],
"albumid": data["albumid"],
"name": data["album"],
"artistid": data["artistid"],
"artist": data["artist"],
"releaseDate": data["releaseDate"],
"lang": data["lang"],
"pic": data["pic"].replace("/300/", "/480/"),
"albuminfo": data["albuminfo"],
"data": [{
"rid": song["rid"],
"name": song["name"],
"artistid": song["artistid"],
"artist": song["artist"],
"albumid": song["albumid"],
"album": song["album"],
"pic": song["pic"],
"duration": song["duration"],
"songTime": song["songTimeMinutes"]
} for song in songList]
}
return info
# 歌手相关
# 歌手专辑
@app.get("/artistAlbum")
async def artistAlbum(artistid: int = None, page: int = 1, size: int = 20):
if artistid is None:
info = {
"code": 403,
"msg": "Invalid Request"
}
return info
url = f'http://www.kuwo.cn/api/www/artist/artistAlbum?artistid={artistid}&pn={page}' \
f'&rn={size}&httpsStatus=1'
r = requests.get(url, headers=headers)
data = json.loads(r.text)['data']
total = int(data["total"])
albumList = data["albumList"]
info = {
"code": 200,
"msg": "success",
"total": total,
"albumList": [{
"albumid": album["albumid"],
"name": album["album"],
"artistid": album["artistid"],
"artist": album["artist"],
"releaseDate": album["releaseDate"],
"pic": album["pic"].replace("/300/", "/480/"),
"lang": album["lang"],
"albuminfo": album["albuminfo"]
} for album in albumList]
}
return info
# 歌手信息
@app.get("/artist")
async def artist(artistid: int = None):
if artistid is None:
info = {
"code": 403,
"msg": "Invalid Request"
}
return info
url = f"https://www.kuwo.cn/api/www/artist/artist?artistid={artistid}&httpsStatus=1"
r = requests.get(url, headers=headers)
if r.headers.get('Set-Cookie') is not None:
headers['Cookie'] = r.headers['Set-Cookie']
headers['csrf'] = r.headers['Set-Cookie'].split("; ")[0].replace("kw_token=", "")
result = json.loads(r.text.replace(' ', ' '))["data"]
info = {
"code": 200,
"msg": "success",
"data": {
"artistid": result["id"],
"name": result["name"],
"albumNum": result["albumNum"],
"musicNum": result["musicNum"],
"mvNum": result["mvNum"],
"artistFans": result["artistFans"],
"pic": result["pic"].replace("/120/", "/480/"),
"gener": result["gener"],
"country": result["country"],
"constellation": result["constellation"],
"birthday": result["birthday"],
"birthplace": result["birthplace"],
"language": result["language"],
"height": result["tall"],
"weight": result["weight"],
"info": result["info"]
}
}
return info
# 歌手音乐
@app.get("/artistMusic")
async def artistMusic(artistid: int = None, page: int = 1, size: int = 20):
if artistid is None:
info = {
"code": 403,
"msg": "Invalid Request"
}
return info
url = f"https://www.kuwo.cn/api/www/artist/artistMusic?artistid={artistid}&pn={page}&rn={size}"
r = requests.get(url, headers=headers)
if r.headers.get('Set-Cookie') is not None:
headers['Cookie'] = r.headers['Set-Cookie']
headers['csrf'] = r.headers['Set-Cookie'].split("; ")[0].replace("kw_token=", "")
js = json.loads(r.text)
result = js["data"]["list"]
total = js["data"]["total"]
songinfos = []
for i in result:
songinfos.append({
'rid': i['rid'],
'name': i['name'].replace(' ', ' '),
'artistid': i['artistid'],
'artists': i['artist'].replace(' ', ' '),
'albumid': i['albumid'],
'album': i['album'].replace(' ', ' '),
'pic': i['pic'].replace('/120/', '/480/'),
'duration': i['duration'],
"songTime": i["songTimeMinutes"]
})
info = {
"code": 200,
"msg": "success",
"total": total,
"data": songinfos
}
return info
# 歌手排行榜
@app.get("/artistRank")
async def artistRank(type: str = "all", page: int = 1, size: int = 20, prefix: str = None):
keyWorkMap = {
"all": "0",
"cnMale": "1",
"cnFemale": "2",
"cnTeam": "3",
"jkMale": "4",
"jkFemale": "5",
"jkTeam": "6",
"eaMale": "7",
"eaFemale": "8",
"eaTeam": "9",
"other": "10"
}
if type not in keyWorkMap.keys():
info = {
"code": 404,
"msg": "Invalid Rank"
}
return info
url = f"https://www.kuwo.cn/api/www/artist/artistInfo?category={keyWorkMap[type]}" \
f"&pn={page}&rn={size}&httpsStatus=1"
url = url + f"&prefix={prefix}" if prefix is not None else url
r = requests.get(url, headers=headers)
if r.headers.get('Set-Cookie') is not None:
headers['Cookie'] = r.headers['Set-Cookie']
headers['csrf'] = r.headers['Set-Cookie'].split("; ")[0].replace("kw_token=", "")
js = json.loads(r.text)
artistList = js["data"]["artistList"]
total = int(js["data"]["total"])
info = {
"code": 200,
"msg": "success",
"total": total,
"data": [{
"artistid": result["id"],
"name": result["name"],
"albumNum": result["albumNum"],
"musicNum": result["musicNum"],
"mvNum": result["mvNum"],
"artistFans": result["artistFans"],
"pic": result["pic"].replace("/300/", "/480/"),
} for result in artistList]
}
return info
# 搜索
@app.get("/search")
async def search(key: str = None, page: int = 1, size: int = 20):
if key is None:
info = {
"code": 403,
"msg": "Invalid Request"
}
return info
url = f'https://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key={key}&pn={page}&rn={size}'
r = requests.get(url, headers=headers)
if r.headers.get('Set-Cookie') is not None:
headers['Cookie'] = r.headers['Set-Cookie']
headers['csrf'] = r.headers['Set-Cookie'].split("; ")[0].replace("kw_token=", "")
js = json.loads(r.text)
result = js['data']['list']
total = int(js['data']['total'])
songinfos = []
for i in result:
songinfos.append({
'rid': i['rid'],
'name': i['name'].replace(' ', ' '),
'artistid': i['artistid'],
'artists': i['artist'].replace(' ', ' '),
'albumid': i['albumid'],
'album': i['album'].replace(' ', ' '),
'pic': i['pic'].replace('/120/', '/480/'),
'duration': i['duration'],
'songTime': i['songTimeMinutes']
})
info = {
"code": 200,
"msg": "success",
"total": total,
"data": songinfos
}
return info
# 歌曲相关
# 下载链接
@app.get("/link")
async def link(rid: int = None):
if rid is None:
info = {
"code": 403,
"msg": "Invalid Request"
}
return info
url = f'http://www.kuwo.cn/api/v1/www/music/playUrl?mid={rid}&type=convert_url3&br=320kmp3'
r = requests.get(url, headers=headers)
result = json.loads(r.text)["data"]["url"]
info = {
"code": 200,
"msg": "success",
"data": {
"LQ": result
}
}
return info
# 歌词
@app.get("/lyric")
async def lyric(rid: int = None):
if rid is None:
info = {
"code": 403,
"msg": "Invalid Request"
}
return info
url = f'http://kuwo.cn/newh5/singles/songinfoandlrc?musicId={rid}'
r = requests.get(url, headers=headers)
data = json.loads(r.text)['data']['lrclist']
info = {
"code": 200,
"msg": "success",
"data": data
}
return info
# 歌曲排行榜
@app.get("/songRank")
async def songRank(type: str = None, page: int = 1, size: int = 20):
keyWorkMap = {
"hot": "16",
"new": "17",
"classic": "26",
}
if type not in keyWorkMap.keys():
info = {
"code": 404,
"msg": "Invalid Rank"
}
return info
url = f"https://www.kuwo.cn/api/www/bang/bang/musicList?bangId={keyWorkMap[type]}&pn={page}" \
f"&rn={size}&httpsStatus=1"
r = requests.get(url, headers=headers)
if r.headers.get('Set-Cookie') is not None:
headers['Cookie'] = r.headers['Set-Cookie']
headers['csrf'] = r.headers['Set-Cookie'].split("; ")[0].replace("kw_token=", "")
js = json.loads(r.text)
result = js["data"]["musicList"]
total = int(js["data"]["num"])
info = {
"code": 200,
"msg": "success",
"total": total,
"data": [{"rid": i["rid"], "name": i["name"], "artistid": i["artistid"],
"artist": i["artist"], "albumid": i["albumid"], "album": i["album"],
"pic": i["pic"], "duration": i["duration"], "songTime": i["songTimeMinutes"]} for i in result]}
return info
# 歌曲信息
@app.get("/songInfo")
async def songInfo(rid: int = None):
if rid is None:
info = {
"code": 403,
"msg": "Invalid Request"
}
return info
url = f'http://kuwo.cn/newh5/singles/songinfoandlrc?musicId={rid}'
r = requests.get(url, headers=headers)
data = json.loads(r.text)['data']['songinfo']
info = {
"code": 200,
"msg": "success",
"data": {
"rid": rid,
"name": data["songName"],
"artistid": int(data["artistId"]),
"artist": data["artist"],
"albumid": int(data["albumId"]),
"album": data["album"],
"pic": data["pic"].replace("/240/", "/480/")
.replace("kwcdn.kuwo.cn", "kuwo.cn").replace("http://", "https://"),
"duration": int(data["duration"]),
"songTime": data["songTimeMinutes"]
}
}
return info
# 歌曲信息以及歌词
@app.get("/songInfoAndLyric")
async def songInfoAndLyric(rid: int = None):
if rid is None:
info = {
"code": 403,
"msg": "Invalid Request"
}
return info
url = f'http://kuwo.cn/newh5/singles/songinfoandlrc?musicId={rid}'
r = requests.get(url, headers=headers)
result = json.loads(r.text)
lyric = result['data']['lrclist']
data = result['data']['songinfo']
info = {
"code": 200,
"msg": "success",
"songInfo": {
"rid": rid,
"name": data["songName"],
"artistid": int(data["artistId"]),
"artist": data["artist"],
"albumid": int(data["albumId"]),
"album": data["album"],
"pic": data["pic"].replace("/240/", "/480/"),
"duration": int(data["duration"]),
"songTime": data["songTimeMinutes"]
},
"lyric": lyric
}
return info
if __name__ == '__main__':
host = env.get("host") if env.get("host") is not None else "0.0.0.0"
port = int(env.get("port")) if env.get("port") is not None else 8000
uvicorn.run(app='main:app', host=host, port=port)