6 Commits

Author SHA1 Message Date
suyiiyii 1031e9f9a5 💡 在 _choose_cookie 方法中添加适当注释 2024-12-24 22:11:21 +08:00
suyiiyii 57e68ac0b9 👷 fix by ruff 2024-12-24 22:11:21 +08:00
suyiiyii 29a807df5a 🐛 fix type hint 2024-12-24 22:11:20 +08:00
suyiiyii 59846642cc B站 cookie选择策略优化 2024-12-24 22:11:20 +08:00
github-actions[bot] e45bf03e49 📝 Update changelog 2024-12-24 07:42:44 +00:00
suyiiyii 3421e3ac5e 🐛 change "proxies" to "proxy" in http.py 2024-12-24 15:42:14 +08:00
4 changed files with 47 additions and 4 deletions
+1
View File
@@ -9,6 +9,7 @@
### Bug 修复 ### Bug 修复
- :bug: 修复新版 httpx 中 proxy 不起效的问题 [@suyiiyii](https://github.com/suyiiyii) ([#669](https://github.com/MountainDash/nonebot-bison/pull/669))
- :bug: 修复 cookie 模块 type hint [@suyiiyii](https://github.com/suyiiyii) ([#658](https://github.com/MountainDash/nonebot-bison/pull/658)) - :bug: 修复 cookie 模块 type hint [@suyiiyii](https://github.com/suyiiyii) ([#658](https://github.com/MountainDash/nonebot-bison/pull/658))
- :bug: B站转发动态补充 DeletedItem 类型解析 [@AzideCupric](https://github.com/AzideCupric) ([#659](https://github.com/MountainDash/nonebot-bison/pull/659)) - :bug: B站转发动态补充 DeletedItem 类型解析 [@AzideCupric](https://github.com/AzideCupric) ([#659](https://github.com/MountainDash/nonebot-bison/pull/659))
- :bug: 小刻食堂cdn使用https [@phidiaLam](https://github.com/phidiaLam) ([#650](https://github.com/MountainDash/nonebot-bison/pull/650)) - :bug: 小刻食堂cdn使用https [@phidiaLam](https://github.com/phidiaLam) ([#650](https://github.com/MountainDash/nonebot-bison/pull/650))
+43 -1
View File
@@ -1,14 +1,17 @@
from collections.abc import Callable
from datetime import datetime, timedelta from datetime import datetime, timedelta
import json import json
import random import random
from typing import TYPE_CHECKING, ClassVar, TypeVar from typing import TYPE_CHECKING, ClassVar, TypeVar
from typing_extensions import override from typing_extensions import override
from httpx import AsyncClient from httpx import AsyncClient, Response
from nonebot import logger, require from nonebot import logger, require
from playwright.async_api import Cookie from playwright.async_api import Cookie
from nonebot_bison.config import config
from nonebot_bison.config.db_model import Cookie as CookieModel from nonebot_bison.config.db_model import Cookie as CookieModel
from nonebot_bison.config.db_model import Target
from nonebot_bison.utils import Site, http_client from nonebot_bison.utils import Site, http_client
from nonebot_bison.utils.site import CookieClientManager from nonebot_bison.utils.site import CookieClientManager
@@ -23,6 +26,8 @@ B = TypeVar("B", bound="Bilibili")
class BilibiliClientManager(CookieClientManager): class BilibiliClientManager(CookieClientManager):
_default_cookie_cd = timedelta(seconds=120) _default_cookie_cd = timedelta(seconds=120)
_current_user_cookie: CookieModel | None = None
_site_name = "bilibili.com"
async def _get_cookies(self) -> list[Cookie]: async def _get_cookies(self) -> list[Cookie]:
browser = await get_browser() browser = await get_browser()
@@ -57,6 +62,43 @@ class BilibiliClientManager(CookieClientManager):
) )
return cookie return cookie
def _generate_hook(self, cookie: CookieModel) -> Callable:
"""hook 函数生成器,用于回写请求状态到数据库"""
async def _response_hook(resp: Response):
await resp.aread()
if resp.status_code == 200 and "-352" not in resp.text:
logger.trace(f"请求成功: {cookie.id} {resp.request.url}")
cookie.status = "success"
else:
logger.warning(f"请求失败: {cookie.id} {resp.request.url}, 状态码: {resp.status_code}")
cookie.status = "failed"
self._current_user_cookie = None
cookie.last_usage = datetime.now()
await config.update_cookie(cookie)
return _response_hook
async def _get_next_user_cookie(self) -> CookieModel | None:
"""选择下一个用户 cookie"""
cookies = await config.get_cookie(self._site_name, is_anonymous=False)
available_cookies = [cookie for cookie in cookies if cookie.last_usage + cookie.cd < datetime.now()]
if not available_cookies:
return None
cookie = min(available_cookies, key=lambda x: x.last_usage)
return cookie
async def _choose_cookie(self, target: Target | None) -> CookieModel:
"""选择 cookie 的具体算法"""
if self._current_user_cookie is None:
# 若当前没有选定用户 cookie 则尝试获取
self._current_user_cookie = await self._get_next_user_cookie()
if self._current_user_cookie:
# 如果当前有选定的用户 cookie 则直接返回
return self._current_user_cookie
# 否则返回匿名 cookie
return (await config.get_cookie(self._site_name, is_anonymous=True))[0]
@override @override
async def refresh_client(self): async def refresh_client(self):
await self._refresh_anonymous_cookie() await self._refresh_anonymous_cookie()
+1 -1
View File
@@ -3,7 +3,7 @@ import httpx
from nonebot_bison.plugin_config import plugin_config from nonebot_bison.plugin_config import plugin_config
http_args = { http_args = {
"proxies": plugin_config.bison_proxy or None, "proxy": plugin_config.bison_proxy or None,
} }
http_headers = {"user-agent": plugin_config.bison_ua} http_headers = {"user-agent": plugin_config.bison_ua}
+2 -2
View File
@@ -124,8 +124,8 @@ class CookieClientManager(ClientManager):
async def _choose_cookie(self, target: Target | None) -> Cookie: async def _choose_cookie(self, target: Target | None) -> Cookie:
"""选择 cookie 的具体算法""" """选择 cookie 的具体算法"""
cookies = await config.get_cookie(self._site_name, target) cookies = await config.get_cookie(self._site_name, target)
avaliable_cookies = (cookie for cookie in cookies if cookie.last_usage + cookie.cd < datetime.now()) available_cookies = (cookie for cookie in cookies if cookie.last_usage + cookie.cd < datetime.now())
cookie = min(avaliable_cookies, key=lambda x: x.last_usage) cookie = min(available_cookies, key=lambda x: x.last_usage)
return cookie return cookie
async def get_client(self, target: Target | None) -> AsyncClient: async def get_client(self, target: Target | None) -> AsyncClient: