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)