Spaces:
Sleeping
Sleeping
""" | |
bilibili_api.rank | |
和哔哩哔哩视频排行榜相关的 API | |
""" | |
from enum import Enum | |
from typing import Union | |
from .utils.utils import get_api | |
from .utils.credential import Credential | |
from .utils.network import Api | |
API = get_api("rank") | |
class RankAPIType(Enum): | |
""" | |
排行榜 API 接口类型 | |
- PGC: https://api.bilibili.com/pgc/web/rank/list | |
- V2: https://api.bilibili.com/x/web-interface/ranking/v2 | |
""" | |
PGC = "pgc" | |
V2 = "x" | |
class RankDayType(Enum): | |
""" | |
RankAPIType.PGC 排行榜时间类型 | |
- THREE_DAY: 三日排行 | |
- WEEK: 周排行 | |
""" | |
THREE_DAY = 3 | |
WEEK = 7 | |
class RankType(Enum): | |
""" | |
排行榜类型 | |
- All: 全部 | |
- Bangumi: 番剧 | |
- GuochuangAnime: 国产动画 | |
- Guochuang: 国创相关 | |
- Documentary: 纪录片 | |
- Douga: 动画 | |
- Music: 音乐 | |
- Dance: 舞蹈 | |
- Game: 游戏 | |
- Knowledge: 知识 | |
- Technology: 科技 | |
- Sports: 运动 | |
- Car: 汽车 | |
- Life: 生活 | |
- Food: 美食 | |
- Animal: 动物圈 | |
- Kitchen: 鬼畜 | |
- Fashion: 时尚 | |
- Ent: 娱乐 | |
- Cinephile: 影视 | |
- Movie: 电影 | |
- TV: 电视剧 | |
- Variety: 综艺 | |
- Original: 原创 | |
- Rookie: 新人 | |
""" | |
All = {"api_type": "x", "rid": 0, "type": "all"} | |
Bangumi = {"api_type": "pgc", "season_type": 1} | |
GuochuangAnime = {"api_type": "pgc", "season_type": 4} | |
Guochuang = {"api_type": "x", "rid": 168, "type": "all"} | |
Documentary = {"api_type": "pgc", "season_type": 3} | |
Douga = {"api_type": "x", "rid": 1, "type": "all"} | |
Music = {"api_type": "x", "rid": 3, "type": "all"} | |
Dance = {"api_type": "x", "rid": 129, "type": "all"} | |
Game = {"api_type": "x", "rid": 4, "type": "all"} | |
Knowledge = {"api_type": "x", "rid": 36, "type": "all"} | |
Technology = {"api_type": "x", "rid": 188, "type": "all"} | |
Sports = {"api_type": "x", "rid": 234, "type": "all"} | |
Car = {"api_type": "x", "rid": 223, "type": "all"} | |
Life = {"api_type": "x", "rid": 160, "type": "all"} | |
Food = {"api_type": "x", "rid": 211, "type": "all"} | |
Animal = {"api_type": "x", "rid": 217, "type": "all"} | |
Kichiku = {"api_type": "x", "rid": 119, "type": "all"} | |
Fashion = {"api_type": "x", "rid": 155, "type": "all"} | |
Ent = {"api_type": "x", "rid": 5, "type": "all"} | |
Cinephile = {"api_type": "x", "rid": 181, "type": "all"} | |
Movie = {"api_type": "pgc", "season_type": 2} | |
TV = {"api_type": "pgc", "season_type": 5} | |
Variety = {"api_type": "pgc", "season_type": 7} | |
Original = {"api_type": "x", "rid": 0, "type": "origin"} | |
Rookie = {"api_type": "x", "rid": 0, "type": "rookie"} | |
class VIPRankType(Enum): | |
""" | |
大会员中心热播榜单类型,即 rank_id | |
- VIP: 会员 | |
- BANGUMI: 番剧 | |
- GUOCHUANG: 国创 | |
- MOVIE: 电影 | |
- DOCUMENTARY: 纪录片 | |
- TV: 电视剧 | |
- VARIETY: 综艺 | |
""" | |
VIP = 279 | |
BANGUMI = 118 | |
GUOCHUANG = 119 | |
MOVIE = 174 | |
DOCUMENTARY = 175 | |
TV = 176 | |
VARIETY = 177 | |
class MangeRankType(Enum): | |
""" | |
漫画排行榜类型 | |
- NEW: 新作 | |
- BOY: 男生 | |
- GRIL: 女生 | |
- GUOCHUANG: 国漫 | |
- JAPAN: 日漫 | |
- SOUTHKOREA: 韩漫 | |
- OFFICAL: 宝藏 | |
- FINISH: 完结 | |
""" | |
NEW = 7 | |
BOY = 11 | |
GRIL = 12 | |
GUOCHUANG = 1 | |
JAPAN = 0 | |
SOUTHKOREA = 2 | |
OFFICAL = 5 | |
FINISH = 13 | |
class LiveRankType(Enum): | |
""" | |
直播通用榜类型 | |
- SAIL_BOAT_VALUE: 主播舰队榜 | |
- SAIL_BOAT_TICKET: 船员价值榜 | |
- SAIL_BOAT_NUMBER: 舰船人数榜 | |
- MASTER_LEVEL: 主播等级榜 | |
- USER_LEVEL: 用户等级榜 | |
""" | |
SAIL_BOAT_VALUE = "sail_boat_value" | |
SAIL_BOAT_TICKET = "sail_boat_ticket" | |
SAIL_BOAT_NUMBER = "sail_boat_number" | |
MASTER_LEVEL = "master_level" | |
USER_LEVEL = "user_level" | |
class LiveEnergyRankType(Enum): | |
""" | |
直播超能用户榜类型 | |
- MONTH: 本月 | |
- PRE_MONTH: 上月 | |
""" | |
MONTH = "month" | |
PRE_MONTH = "pre_month" | |
async def get_rank( | |
type_: RankType = RankType.All, day: RankDayType = RankDayType.THREE_DAY | |
) -> dict: | |
""" | |
获取视频排行榜 | |
Args: | |
type_ (RankType): 排行榜类型. Defaults to RankType.All | |
day (RankDayType): 排行榜时间. Defaults to RankDayType.THREE_DAY | |
仅对 api_type 为 RankAPIType.PGC 有效 | |
Returns: | |
dict: 调用 API 返回的结果 | |
""" | |
params = {} | |
# 确定 API 接口类型 | |
if type_.value["api_type"] == RankAPIType.V2.value: | |
api = API["info"]["v2_ranking"] | |
params["rid"] = type_.value["rid"] | |
elif type_.value["api_type"] == RankAPIType.PGC.value: | |
api = API["info"]["pgc_ranking"] | |
params["season_type"] = type_.value["season_type"] | |
params["day"] = day.value | |
else: | |
raise Exception("Unknown RankType") | |
return await Api(**api).update_params(**params).result | |
async def get_music_rank_list() -> dict: | |
""" | |
获取全站音乐榜每周信息(不包括具体的音频列表) | |
Returns: | |
dict: 调用 API 返回的结果 | |
""" | |
api = API["info"]["music_weekly_series"] | |
params = {"list_type": 1} | |
return await Api(**api).update_params(**params).result | |
async def get_music_rank_weekly_detail(week: int = 1) -> dict: | |
""" | |
获取全站音乐榜一周的详细信息(不包括具体的音频列表) | |
Args: | |
week(int): 第几周. Defaults to 1. | |
Returns: | |
dict: 调用 API 返回的结果 | |
""" | |
api = API["info"]["music_weekly_details"] | |
params = {"list_id": week} | |
return await Api(**api).update_params(**params).result | |
async def get_music_rank_weekly_musics(week: int = 1) -> dict: | |
""" | |
获取全站音乐榜一周的音频列表(返回的音乐的 id 对应了 music.Music 类创建实例传入的 id) | |
Args: | |
week(int): 第几周. Defaults to 1. | |
Returns: | |
dict: 调用 API 返回的结果 | |
""" | |
api = API["info"]["music_weekly_content"] | |
params = {"list_id": week} | |
return await Api(**api).update_params(**params).result | |
async def get_vip_rank(type_: VIPRankType = VIPRankType.VIP) -> dict: | |
""" | |
获取大会员中心的排行榜 | |
Args: | |
type_ (VIPRankType): 排行榜类型. Defaults to VIPRankType.VIP | |
Returns: | |
dict: 调用 API 返回的结果 | |
""" | |
api = API["info"]["VIP_rank"] | |
params = {"rank_id": type_.value} | |
return await Api(**api).update_params(**params).result | |
async def get_manga_rank(type_: MangeRankType = MangeRankType.NEW, credential: Credential = None) -> dict: | |
""" | |
获取漫画专属排行榜 | |
Args: | |
credential (Credential): 凭据类 | |
Returns: | |
dict: 调用 API 返回的结果 | |
""" | |
credential = credential if credential else Credential() | |
credential.raise_for_no_sessdata() | |
api = API["info"]["manga_rank"] | |
params = {"device": "pc", "platform": "web"} | |
data = {"id": type_.value} | |
return ( | |
await Api(**api, no_csrf=True, credential=credential) | |
.update_data(**data) | |
.update_params(**params) | |
.result | |
) | |
async def get_live_hot_rank() -> dict: | |
""" | |
获取直播首页人气排行榜 | |
Returns: | |
dict: 调用 API 返回的结果 | |
""" | |
api = API["info"]["live_hot_rank"] | |
return await Api(**api).result | |
async def get_live_sailing_rank() -> dict: | |
""" | |
获取首页直播大航海排行榜 | |
Returns: | |
dict: 调用 API 返回的结果 | |
""" | |
api = API["info"]["live_sailing_rank"] | |
return await Api(**api).update_params(**{}).result | |
async def get_live_energy_user_rank( | |
date: LiveEnergyRankType = LiveEnergyRankType.MONTH, pn: int = 1, ps: int = 20 | |
) -> dict: | |
""" | |
获取直播超能用户榜 | |
Args: | |
date (LiveEnergyRankType): 月份. Defaults to LiveEnergyRankType.MONTH | |
pn (int): 页码. Defaults to 1 | |
ps (int): 每页数量. Defaults to 20 | |
Returns: | |
dict: 调用 API 返回的结果 | |
""" | |
api = API["info"]["live_energy_user_rank"] | |
params = {"date": date.value, "page": pn, "page_size": ps} | |
return await Api(**api).update_params(**params).result | |
async def get_live_rank( | |
_type: LiveRankType = LiveRankType.SAIL_BOAT_VALUE, pn: int = 1, ps: int = 20 | |
) -> dict: | |
""" | |
获取直播通用榜单 | |
Args: | |
_type (LiveRankType): 榜单类型. Defaults to LiveRankType.VALUE | |
pn (int): 页码. Defaults to 1 | |
ps (int): 每页数量. Defaults to 20 | |
Returns: | |
dict: 调用 API 返回的结果 | |
""" | |
api = API["info"]["live_web_top"] | |
params = { | |
"type": _type.value, | |
"page": pn, | |
"page_size": ps, | |
"is_trend": 1, | |
"area_id": None, | |
} | |
return await Api(**api).update_params(**params).result | |
async def get_live_user_medal_rank(pn: int = 1, ps: int = 20) -> dict: | |
""" | |
获取直播用户勋章榜 | |
Args: | |
pn (int): 页码. Defaults to 1 | |
ps (int): 每页数量. Defaults to 20 | |
Returns: | |
dict: 调用 API 返回的结果 | |
""" | |
api = API["info"]["live_medal_level_rank"] | |
params = {"page": pn, "page_size": ps} | |
return await Api(**api).update_params(**params).result | |
async def subscribe_music_rank( | |
status: bool = True, credential: Union[Credential, None] = None | |
) -> dict: | |
""" | |
设置关注全站音乐榜 | |
Args: | |
status (bool) : 关注状态. Defaults to True. | |
credential (Credential): 凭据类. Defaults to None. | |
""" | |
credential = credential if credential else Credential() | |
credential.raise_for_no_sessdata() | |
credential.raise_for_no_bili_jct() | |
api = API["operate"]["subscribe"] | |
data = {"list_id": 1, "state": (1 if status else 2)} | |
return await Api(**api, credential=credential).update_data(**data).result | |
async def get_playlet_rank_phases() -> dict: | |
""" | |
获取全站短剧榜期数 | |
Returns: | |
dict: 调用 API 返回的结果 | |
""" | |
api = API["info"]["playlet_rank_phase"] | |
return await Api(**api, json_body=True, no_csrf=True).result | |
async def get_playlet_rank_info(phase_id: int) -> dict: | |
""" | |
获取全站短剧榜 | |
https://www.bilibili.com/v/popular/drama/ | |
Args: | |
phase_id (int): 期数,从 get_playlet_rank_phase 获取 | |
Returns: | |
dict: 调用 API 返回的结果 | |
""" | |
api = API["info"]["playlet_rank_info"] | |
data = {"phaseID": phase_id} | |
return await Api(**api, json_body=True, no_csrf=True).update_data(**data).result | |