Skip to content

Commit

Permalink
feat: 支持 impersonate, http2 设置
Browse files Browse the repository at this point in the history
  • Loading branch information
Nemo2011 committed Feb 3, 2025
1 parent 7e1b52f commit c4abe00
Show file tree
Hide file tree
Showing 9 changed files with 494 additions and 477 deletions.
17 changes: 8 additions & 9 deletions bilibili_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@
unregister_client,
select_client,
get_selected_client,
get_available_settings,
get_registered_clients,
get_registered_available_settings,
get_client,
get_session,
set_session,
get_registered_clients,
# credential
Credential,
# api
Expand Down Expand Up @@ -108,13 +110,8 @@

def __register_all_clients():
import importlib

all_clients = [
("curl_cffi", "CurlCFFIClient"),
("aiohttp", "AioHTTPClient"),
("httpx", "HTTPXClient"),
][::-1]
for module, client in all_clients:
from .clients import ALL_PROVIDED_CLIENTS
for module, client, settings in ALL_PROVIDED_CLIENTS[::-1]:
try:
importlib.import_module(module)
except ModuleNotFoundError:
Expand All @@ -123,7 +120,7 @@ def __register_all_clients():
name=f".clients.{client}", package="bilibili_api"
)
client_class = eval(f"client_module.{client}")
register_client(module, client_class)
register_client(module, client_class, settings)


__register_all_clients()
Expand Down Expand Up @@ -187,8 +184,10 @@ def __register_all_clients():
"favorite_list",
"festival",
"game",
"get_available_settings",
"get_client",
"get_real_url",
"get_registered_available_settings",
"get_registered_clients",
"get_selected_client",
"get_session",
Expand Down
40 changes: 36 additions & 4 deletions bilibili_api/clients/CurlCFFIClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
BiliWsMsgType,
request_log,
)
from curl_cffi import requests # pylint: disable=E0401
import curl_cffi # pylint: disable=E0401
from curl_cffi import requests # pylint: disable=E0401
import curl_cffi # pylint: disable=E0401
from typing import Optional, Dict, Union, Tuple, AsyncGenerator
import asyncio

Expand All @@ -28,8 +28,22 @@ def __init__(
timeout: float = 0.0,
verify_ssl: bool = True,
trust_env: bool = True,
impersonate: str = "chrome131",
http2: bool = False,
session: Optional[requests.AsyncSession] = None,
) -> None:
"""
Args:
proxy (str, optional): 代理地址. Defaults to "".
timeout (float, optional): 请求超时时间. Defaults to 0.0.
verify_ssl (bool, optional): 是否验证 SSL. Defaults to True.
trust_env (bool, optional): `trust_env`. Defaults to True.
impersonate (str, optional): 伪装的浏览器,可参考 curl_cffi 文档. Defaults to chrome131.
http2 (bool, optional): 是否使用 HTTP2. Defaults to False.
session (object, optional): 会话对象. Defaults to None.
Note: 仅当用户只提供 `session` 参数且用户中途未调用 `set_xxx` 函数才使用用户提供的 `session`。
"""
if session:
self.__session = session
else:
Expand All @@ -40,7 +54,8 @@ def __init__(
proxies={"all": proxy},
verify=verify_ssl,
trust_env=trust_env,
impersonate="chrome131",
impersonate=impersonate,
http_version=(curl_cffi.CurlHttpVersion.V2_0 if http2 else None),
)
self.__ws: Dict[int, requests.AsyncWebSocket] = {}
self.__ws_cnt: int = 0
Expand All @@ -64,6 +79,24 @@ def set_verify_ssl(self, verify_ssl: bool = True) -> None:
def set_trust_env(self, trust_env: bool = True) -> None:
self.__session.trust_env = trust_env

def set_impersonate(self, impersonate: str = "chrome131") -> None:
"""
设置 curl_cffi 伪装的浏览器,可参考 curl_cffi 文档。
Args:
impersonate (str, optional): 伪装的浏览器. Defaults to chrome131.
"""
self.__session.impersonate = impersonate

def set_http2(self, http2: bool = False) -> None:
"""
设置是否使用 http2.
Args:
impersonate (str, optional): 是否使用 http2. Defaults to False.
"""
self.__session.http_version = curl_cffi.CurlHttpVersion.V2_0 if http2 else None

async def request(
self,
method: str = "",
Expand Down Expand Up @@ -258,7 +291,6 @@ async def ws_close(self, cnt: int) -> None:
async def close(self) -> None:
await self.__session.close()

__init__.__doc__ = BiliAPIClient.__init__.__doc__
get_wrapped_session.__doc__ = BiliAPIClient.get_wrapped_session.__doc__
set_proxy.__doc__ = BiliAPIClient.set_proxy.__doc__
set_timeout.__doc__ = BiliAPIClient.set_timeout.__doc__
Expand Down
35 changes: 33 additions & 2 deletions bilibili_api/clients/HTTPXClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
request_log,
)
from ..exceptions import ApiException
import httpx # pylint: disable=E0401
import httpx # pylint: disable=E0401
from typing import AsyncGenerator, Optional, Dict, Union


Expand All @@ -26,12 +26,25 @@ def __init__(
timeout: float = 0.0,
verify_ssl: bool = True,
trust_env: bool = True,
http2: bool = False,
session: Optional[httpx.AsyncClient] = None,
) -> None:
"""
Args:
proxy (str, optional): 代理地址. Defaults to "".
timeout (float, optional): 请求超时时间. Defaults to 0.0.
verify_ssl (bool, optional): 是否验证 SSL. Defaults to True.
trust_env (bool, optional): `trust_env`. Defaults to True.
http2 (bool, optional): 是否使用 HTTP2. Defaults to False.
session (object, optional): 会话对象. Defaults to None.
Note: 仅当用户只提供 `session` 参数且用户中途未调用 `set_xxx` 函数才使用用户提供的 `session`。
"""
self.__proxy = proxy
self.__timeout = timeout
self.__verify_ssl = verify_ssl
self.__trust_env = trust_env
self.__http2 = http2
if session:
self.__session = session
else:
Expand All @@ -40,6 +53,7 @@ def __init__(
proxy=self.__proxy if self.__proxy != "" else None,
verify=self.__verify_ssl,
trust_env=self.__trust_env,
http2=self.__http2,
)
self.__downloads: Dict[int, httpx.Response] = {}
self.__download_iter: Dict[int, AsyncGenerator] = {}
Expand All @@ -55,6 +69,7 @@ def set_proxy(self, proxy: str = "") -> None:
proxy=self.__proxy if self.__proxy != "" else None,
verify=self.__verify_ssl,
trust_env=self.__trust_env,
http2=self.__http2,
)

def set_timeout(self, timeout: float = 0.0) -> None:
Expand All @@ -68,12 +83,29 @@ def set_verify_ssl(self, verify_ssl: bool = True) -> None:
proxy=self.__proxy if self.__proxy != "" else None,
verify=self.__verify_ssl,
trust_env=self.__trust_env,
http2=self.__http2,
)

def set_trust_env(self, trust_env: bool = True) -> None:
self.__trust_env = trust_env
self.__session.trust_env = trust_env

def set_http2(self, http2: bool = False) -> None:
"""
设置是否使用 http2.
Args:
impersonate (str, optional): 是否使用 http2. Defaults to False.
"""
self.__http2 = http2
self.__session = httpx.AsyncClient(
timeout=self.__timeout,
proxy=self.__proxy if self.__proxy != "" else None,
verify=self.__verify_ssl,
trust_env=self.__trust_env,
http2=self.__http2,
)

async def request(
self,
method: str = "",
Expand Down Expand Up @@ -213,7 +245,6 @@ async def ws_close(self, *args, **kwargs) -> None:
async def close(self) -> None:
await self.__session.aclose()

__init__.__doc__ = BiliAPIClient.__init__.__doc__
get_wrapped_session.__doc__ = BiliAPIClient.get_wrapped_session.__doc__
set_proxy.__doc__ = BiliAPIClient.set_proxy.__doc__
set_timeout.__doc__ = BiliAPIClient.set_timeout.__doc__
Expand Down
9 changes: 9 additions & 0 deletions bilibili_api/clients/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""
bilibili_api.clients
"""

ALL_PROVIDED_CLIENTS = [
("curl_cffi", "CurlCFFIClient", {"impersonate": "chrome131", "http2": False}),
("aiohttp", "AioHTTPClient", {}),
("httpx", "HTTPXClient", {"http2": False}),
]
Loading

0 comments on commit c4abe00

Please sign in to comment.