|
| 1 | +# v17.0.0 2025/01/28 |
| 2 | + |
| 3 | +## Notice |
| 4 | + |
| 5 | +此次更新伴随着针对底层网络请求功能的大规模重构,可以算是本次更新中最重要的一点。 |
| 6 | + |
| 7 | +现在开始,模块底层的网络请求功能全部通过用户实现的 `BiliAPIClient`(一个抽象类) 具体实现,`BiliAPIClient` 应当以类的实例为载体对第三方请求库的会话对象进行封装,使第三方请求库可以处理模块指定传入的数据。这种模式下,用户理论上可以利用 `BiliAPIClient` 使模块运用上所有的第三方请求库,前提是需要自己具体实现对应的 `BiliAPIClient` 的实现。模块目前默认提供 `curl_cffi` 的 `BiliAPIClient` 实现,将 `curl_cffi` 作为第三方请求库。 |
| 8 | + |
| 9 | +更多信息见 [自定义请求库](https://nemo2011.github.io/bilibili-api/#/request_client)。 |
| 10 | + |
| 11 | +下文为本次更新其他更新内容,存在部分破坏修改。最后是所有在 `16.3.0 -> 17.0.0` 中修改的 API 的列表。 |
| 12 | + |
| 13 | +## What's Other Changed |
| 14 | + |
| 15 | +- chore(deps): remove `httpx` |
| 16 | +- chore(deps): update `aiohttp ~= 3.10.5 -> ~= 3.11.11` |
| 17 | +- chore(deps): update `pycryptodomex ~= 3.20.0 -> ~= 3.21.0` |
| 18 | +- chore(deps): update `yarl ~= 1.11.1 -> ~= 1.17.2` |
| 19 | +- chore(deps): update `qrcode ~= 7.4.2 -> ~= 8.0` |
| 20 | +- chore(deps): update `pyjwt ~= 2.9.0 -> ~= 2.10.0` |
| 21 | +- chore(deps): update `pillow ~= 10.4.0 -> ~= 11.0.0` |
| 22 | +- chore(deps): update `apscheduler ~= 3.10.4 -> ~= 3.11.0` |
| 23 | + |
| 24 | +- feat: `login_v2` module. 使用样例见 [自定义请求库](https://nemo2011.github.io/bilibili-api/#/examples/login_v2)。 |
| 25 | +- feat: 用户个人首页动态渲染数据风控 `w_webid` by @shouge in [#837](https://github.com/Nemo2011/bilibili-api/pull/837) |
| 26 | +- feat: 直播禁言用户添加hour参数 by @TZFC in [#846](https://github.com/Nemo2011/bilibili-api/pull/846) |
| 27 | +- feat: 禁言用户新增的参数,添加默认数值,以方便旧版本适配 by @TZFC in [#859](https://github.com/Nemo2011/bilibili-api/pull/859) |
| 28 | +- feat: 新增获取直播间可用表情包,与直播间发送表情包功能 by @TZFC in [#864](https://github.com/Nemo2011/bilibili-api/pull/864) |
| 29 | +- feat: `search.search_by_type` 增加功能:可以按照时间段查询 & 新增 `to_timestamps` 函数 by @xianrenzhou in [#866](https://github.com/Nemo2011/bilibili-api/pull/866) |
| 30 | +- feat: `Dynamic.set_favorite` |
| 31 | +- feat: `emoji.get_emoji_detail` & `emoji.get_all_emoji` |
| 32 | +- **[BREAKING CHANGE]** feat: `live_area.fetch_live_area_data` **之后调用 `live_area` 查询分区函数必须先调用此方法** |
| 33 | +- feat: `dynamic.get_lottery_info` |
| 34 | +- feat: 支持在事件循环已经运行时同步执行异步代码 by @LondonClass in [#743](https://github.com/Nemo2011/bilibili-api/pull/743) |
| 35 | +- feat: `dynamic.Dynamic.markdown` |
| 36 | +- feat: `manga.get_followed_manga` |
| 37 | + |
| 38 | +- fix: `VideoDownloadURLDataDetecter` |
| 39 | +- **[BREAKING CHANGE]** fix: remove argument `uid` for `User.get_relation` **之后调用 `get_relation` 默认判断 `User.get_uid()` 与自己的信息而不是传入函数的参数** |
| 40 | +- fix: 字母接口风控 [#841](https://github.com/Nemo2011/bilibili-api/issues/841) & 游客下无法访问用户视频投稿 |
| 41 | +- **[BREAKING CHANGE]** fix: `user.name2uid` 此方法目前必须携带凭据类 **经过测试,更改后的 api 只能登录后访问。若要不登录访问一定程度上可以使用搜索功能替代** |
| 42 | +- fix: `comment.get_comments_lazy` 传参问题 [#871](https://github.com/Nemo2011/bilibili-api/issues/871) |
| 43 | +- fix: `manga.get_info` |
| 44 | +- fix: 当 `buvid3` 已有时仍尝试获取 `buvid3` |
| 45 | +- fix: `Video.get_danmaku_view` |
| 46 | +- **[BREAKING CHANGE]** fix: 因为 `video.get_cid_info` (属于 biliplus <https://hd.biliplus.com> 的 api)部分新视频数据没有记录,暂时缺少方法处理笔记正文内容视频卡片的 `cid` 数据,所以目前 **`note.Note.fetch_content` 不再支持解析视频卡片。** |
| 47 | +- **[BREAKING CHANGE]** fix: 考虑到多方面因素,`interactive_video.InteractiveVideoDownloader` 参数 **`self_download_func` 不再默认提供。** |
| 48 | +- fix: 查看用户合集中的视频(新版)API变更 by @TangMisaka23001 in [#880](https://github.com/Nemo2011/bilibili-api/pull/880) |
| 49 | +- fix: `opus.get_info` |
| 50 | +- **[BREAKING CHANGE]** fix: 因更新频率过高且不易维护,`emote.json` 被移除。**`dynamic.BuildDynamic.add_emoji` 被修改。** |
| 51 | + |
| 52 | +- **[BREAKING CHANGE]** refactor: 重构 `bangumi` / `cheese` / `channel_series` / `video_tag` 等,移除所有同步代码,**部分原同步函数改为异步函数。**大多此类函数原来是同步的获取属性的函数,例如 `get_meta` `get_season_id`,这些数据原为 `__init__` 中通过同步请求获取。 |
| 53 | +- **[BREAKING CHANGE]** refactor: 重写大量 `opus` `dynamic` `article` `note` 间互相转换/关联的代码。 |
| 54 | +- refactor: `dynamic.BuildDynamic` 内部移除同步请求模式,相关完善正文内容请求将移至 `dynamic.send_dynamic` 进行,即 `dynamic.send_dynamic` 请求数可能会增多,但 `dynamic.BuildDynamic` 不会再有请求。 |
| 55 | + |
| 56 | +- **[BREAKING CHANGE]** chore: remove support for **Python 3.8**. |
| 57 | +- chore: 更新 `data/**.json` |
| 58 | +- **[BREAKING CHANGE]** chore: **`Manga` 类大多函数 和 `manga.manga_image_url_turn_to_Picture` `manga.get_raw_manga_index` `manga.get_manga_index` 无限期被移除。所有函数目前均已失效。**这是源于 bilibili 漫画接口在 2024 年末、2025 年初这段时间的变动,出现了新字段,接口返回数据也出现了加密。相关讨论:[#875](https://github.com/Nemo2011/bilibili-api/issues/875) [#bac1168](https://github.com/SocialSisterYi/bilibili-API-collect/issues/1168) [#bac1130](https://github.com/SocialSisterYi/bilibili-API-collect/discussions/1130) |
| 59 | +- **[BREAKING CHANGE]** chore: **移除 `login` `login_func` 模块。** |
| 60 | + |
| 61 | +## All Changed API |
| 62 | + |
| 63 | +- `__init__.py` |
| 64 | + - add `Api` |
| 65 | + - add `BiliAPIClient` |
| 66 | + - add `BiliAPIFile` |
| 67 | + - add `BiliAPIResponse` |
| 68 | + - add `BiliWsMsgType` |
| 69 | + - add `Geetest` |
| 70 | + - add `GeetestMeta` |
| 71 | + - add `GeetestServerNotFoundException` |
| 72 | + - add `GeetestUndoneException` |
| 73 | + - move async `Picture.async_load_url()` to async `Picture.load_url()` |
| 74 | + - move async `Picture.upload_file()` to async `Picture.upload()` |
| 75 | + - add async `Picture.upload_by_note()` |
| 76 | + - move `Picture.download_sync()` to `Picture.to_file()` |
| 77 | + - remove async `Picture.download()` |
| 78 | + - add `WbiRetryTimesExceedException` |
| 79 | + - remove `get_aiohttp_session()` |
| 80 | + - remove `set_aiohttp_session()` |
| 81 | + - remove `get_httpx_sync_session()` |
| 82 | + - remove `set_httpx_sync_session()` |
| 83 | + - remove `get_buvid3()` |
| 84 | + - rewrite `get_session()` response type `httpx.AsyncClient` -> `object` |
| 85 | + - rewrite `set_session()` argument type `httpx.AsyncClient` -> `object` |
| 86 | + - add `get_client()` |
| 87 | + - add `get_selected_client()` |
| 88 | + - add `register_client()` |
| 89 | + - add `unregister_client()` |
| 90 | + - add `select_client()` |
| 91 | + - add `request_log` |
| 92 | + - add `request_settings` |
| 93 | + - add `get_registered_clients()` |
| 94 | +- `article.py` |
| 95 | + - change `article.Article.turn_to_opus()` async |
| 96 | + - add async `article.Article.turn_to_dynamic()` |
| 97 | + - remove `article.ArticleType` |
| 98 | +- `bangumi.py` |
| 99 | + - change `bangumi.Bangumi.get_media_id()` async |
| 100 | + - change `bangumi.Bangumi.get_raw()` async |
| 101 | + - change `bangumi.Bangumi.get_season_id()` async |
| 102 | + - change `bangumi.Bangumi.get_up_info()` async |
| 103 | + - change `bangumi.Bangumi.set_media_id()` async |
| 104 | + - change `bangumi.Bangumi.set_ssid()` async |
| 105 | + - change `bangumi.Episode.get_aid()` async |
| 106 | + - change `bangumi.Episode.get_bangumi()` async |
| 107 | + - change `bangumi.Episode.get_bvid()` async |
| 108 | + - modify `bangumi.Episode.get_cid()` add `from_seg` `to_seg` arguments |
| 109 | +- `black_room.py` |
| 110 | + - change async `black_room.BlackRoom.get_id()` sync |
| 111 | + - change async `black_room.BlackRoom.set_id()` sync |
| 112 | +- `channel_series.py` |
| 113 | + - change `channel_series.ChannelSeries.get_meta()` async |
| 114 | +- `cheese.py` |
| 115 | + - change `cheese.CheeseList.get_season_id()` async |
| 116 | + - change `cheese.CheeseList.set_ep_id()` async |
| 117 | + - change `cheese.set_season_id()` async |
| 118 | + - change `cheese.Cheese.get_cheese()` async |
| 119 | + - change `cheese.Cheese.get_cid()` async |
| 120 | + - change `cheese.Cheese.get_meta()` async |
| 121 | + - change `cheese.Cheese.set_epid()` async |
| 122 | +- `dynamic.py` |
| 123 | + - modify `dynamic.BuildDynamic.add_at()` add `uname` argument, make `uid` argument `int | user.User` -> `int` |
| 124 | + - modify `dynamic.BuildDynamic.add_vote()` rename `vote` -> `vote_id` argument, make `vote_id` argument `vote.Vote` -> `int` |
| 125 | + - change `dynamic.BuildDynamic.get_contents()` async |
| 126 | + - add async `dynamic.Dynamic.get_lottery_info()` |
| 127 | + - change `dynamic.Dynamic.is_opus()` async |
| 128 | + - add async `dynamic.Dynamic.is_article()` |
| 129 | + - add async `dynamic.Dynamic.set_favorite()` |
| 130 | + - add async `dynamic.Dynamic.turn_to_article()` |
| 131 | + - remove `dynamic.upload_image_sync()` |
| 132 | + - add async `dynamic.Dynamic.markdown()` |
| 133 | + - add async `dynamic.Dynamic.get_rid()` |
| 134 | + - modify `dynamic.BuildDynamic.add_emoji()` remove `emoji_id` argument, add `emoji` argument |
| 135 | +- `emoji.py` |
| 136 | + - add async `emoji.get_all_emoji()` |
| 137 | + - add async `emoji.get_emoji_detail()` |
| 138 | + - modify async `emoji.get_emoji_list()` add `credential` argument |
| 139 | +- `interactive_video.py` |
| 140 | + - modify `interactive_video.InteractiveVideoDownloader.__init__` remove `self_download_func` argument's default value |
| 141 | + - modify `interactive_video.InteractiveVideoDownloaderEvents` remove attributes `DOWNLOAD_START` `DOWNLOAD_PART` `DOWNLOAD_SUCCESS` |
| 142 | +- `live.py` |
| 143 | + - modify async `live.LiveRoom.ban_user()` add argument `hour` |
| 144 | + - add async `live.LiveRoom.get_emoticons()` |
| 145 | + - add async `live.LiveRoom.send_emoticons()` |
| 146 | +- `live_area.py` |
| 147 | + - add async `live_area.fetch_live_area_data()` |
| 148 | +- `login.py` |
| 149 | + - remove all |
| 150 | +- `login_func.py` |
| 151 | + - remove all |
| 152 | +- `login_v2.py` |
| 153 | + - add `login_v2` |
| 154 | +- `manga.py` |
| 155 | + - remove async `manga.Manga.get_images()` |
| 156 | + - remove async `manga.manga_image_url_turn_to_Picture()` |
| 157 | + - add async `manga.get_followed_manga()` |
| 158 | + - add `manga.MangaOrderType` |
| 159 | + - remove async `manga.get_manga_index()` |
| 160 | + - remove async `manga.get_raw_manga_index()` |
| 161 | +- `note.py` |
| 162 | + - add async `note.upload_image()` |
| 163 | +- `opus.py` |
| 164 | + - change `opus.Opus.is_note()` async |
| 165 | + - change `opus.Opus.turn_to_article()` async |
| 166 | + - remove `opus.Opus.turn_to_note()` |
| 167 | + - remove `opus.Opus.is_note()` |
| 168 | + - remove `opus.Opus.get_type()` |
| 169 | + - add async `opus.Opus.is_article()` |
| 170 | + - remove `opus.OpusType` |
| 171 | + - change `opus.Opus.markdown()` async |
| 172 | + - add async `opus.Opus.set_like()` |
| 173 | + - add async `opus.Opus.set_favorite()` |
| 174 | + - add async `opus.Opus.add_coins()` |
| 175 | + - add async `opus.Opus.get_reaction()` |
| 176 | + - add async `opus.Opus.get_rid()` |
| 177 | +- `search.py` |
| 178 | + - modify async `search.search_by_type()` add `time_start` `time_end` arguments, remove `debug_param_func` argument |
| 179 | +- `user.py` |
| 180 | + - add async `user.User.get_access_id()` |
| 181 | + - modify async `user.User.get_relation()` remove `uid` argument |
| 182 | + - remove `user.get_user_info_sync()` |
| 183 | + - add async `user.User.is_access_id_expired()` |
| 184 | + - remove `user.name2uid_sync()` |
| 185 | +- `video.py` |
| 186 | + - remove `video.get_cid_info_sync()` |
| 187 | +- `video_tag.py` |
| 188 | + - remove async `video_tag.Tag.get_history_cards()` |
| 189 | + - change `video_tag.Tag.get_tag_id()` async |
| 190 | + - add async `video_tag.Tag.get_tag_name()` |
| 191 | +- `video_zone.py` |
| 192 | + - modify `video_zone.VideoZoneTypes` add attributes `MUSIC_FAN_VIDEOS` `MUSIC_AI_MUSIC` `MUSIC_RADIO` `CINEPHILE_MASHUP` `CINEPHILE_AI_IMAGING` `CINEPHILE_COMPREHENSIVE` `ENT_CP_RECOMMENDATION` `ENT_BEAUTY` `ENT_ENTERTAINMENT_NEWS` `TECH_DIY` `LIFE_PARENTING` `CAR_KNOWLEDGE` `ANIMAL_SECOND_EDITION` `ANIMAL_WILD_ANIMAL`, remove attributes `ANIMAL_PANDA` `ANIMAL_WILD_ANIMAL` `VLOG` |
| 193 | +- `vote.py` |
| 194 | + - remove `vote.Vote.get_info_sync()` |
| 195 | +- `watchroom.py` |
| 196 | + - change `watchroom.WatchRoom.get_episode_id()` async |
| 197 | + - change `watchroom.WatchRoom.get_season_id()` async |
0 commit comments