From fca06770a69e7905c387b10a2c295a5fc1c8a8bf Mon Sep 17 00:00:00 2001 From: LWR Date: Thu, 14 Sep 2023 22:30:59 +0800 Subject: [PATCH] fix: Fixed the issue where the obtained live data was incorrect due to bilibili new anti-spam policy --- starbot/api/live.json | 9 +++++++++ starbot/core/live.py | 26 ++++++++++++++++++++++---- starbot/utils/network.py | 24 ++++++++++++++---------- 3 files changed, 45 insertions(+), 14 deletions(-) diff --git a/starbot/api/live.json b/starbot/api/live.json index c7d28d4..85a4152 100644 --- a/starbot/api/live.json +++ b/starbot/api/live.json @@ -18,6 +18,15 @@ }, "comment": "获取聊天弹幕服务器配置信息(websocket)" }, + "chat_conf_new": { + "url": "https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuInfo", + "method": "GET", + "verify": false, + "params": { + "id": "int: 真实房间号" + }, + "comment": "获取新版聊天弹幕服务器配置信息(websocket)" + }, "room_info": { "url": "https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom", "method": "GET", diff --git a/starbot/core/live.py b/starbot/core/live.py index 9d9a61a..71547f6 100644 --- a/starbot/core/live.py +++ b/starbot/core/live.py @@ -6,6 +6,7 @@ import asyncio import base64 import json +import random import struct import time from enum import Enum @@ -146,6 +147,16 @@ class LiveRoom: } return await request(api['method'], api["url"], params, credential=self.credential) + async def get_chat_conf_new(self): + """ + 获取新版聊天弹幕服务器配置信息(websocket) + """ + api = API["info"]["chat_conf_new"] + params = { + "id": self.room_display_id + } + return await request(api['method'], api["url"], params, credential=self.credential) + async def get_room_info(self): """ 获取直播间信息(标题,简介等) @@ -672,20 +683,19 @@ class LiveDanmaku(AsyncEvent): # 获取真实房间号和开播时间 logger.debug(f"正在获取直播间 {self.room_display_id} 的真实房间号") info = await room.get_room_play_info() - self.__uid = info["uid"] self.__room_real_id = info["room_id"] self.live_time = info["live_time"] logger.debug(f"获取成功, 真实房间号: {self.__room_real_id}") # 获取直播服务器配置 logger.debug(f"正在获取直播间 {self.room_display_id} 的聊天服务器配置") - conf = await room.get_chat_conf() + conf = await room.get_chat_conf_new() logger.debug(f"直播间 {self.room_display_id} 的聊天服务器配置获取成功") # 连接直播间 logger.debug(f"开始连接直播间 {self.room_display_id}") session = get_session() - available_hosts: List[dict] = conf["host_server_list"] + available_hosts: List[dict] = conf["host_list"] host = None @self.on('TIMEOUT') @@ -714,7 +724,15 @@ class LiveDanmaku(AsyncEvent): logger.debug(f"正在尝试连接直播间 {self.room_display_id} 的主机: {uri}") try: - async with session.ws_connect(uri, headers={"User-Agent": "Mozilla/5.0"}) as ws: + # 如果用户提供代理则设置代理 + proxy = None + config_proxy = config.get("PROXY") + if isinstance(config_proxy, str): + proxy = config_proxy + elif isinstance(config_proxy, list): + proxy = random.choice(config_proxy) + + async with session.ws_connect(uri, headers={"User-Agent": "Mozilla/5.0"}, proxy=proxy) as ws: @self.on('VERIFICATION_SUCCESSFUL') async def on_verification_successful(data): """ diff --git a/starbot/utils/network.py b/starbot/utils/network.py index 9a69df1..778e0ca 100644 --- a/starbot/utils/network.py +++ b/starbot/utils/network.py @@ -5,12 +5,14 @@ import asyncio import atexit import json +import random import re from typing import Any, Union, Dict import aiohttp from aiohttp import TCPConnector, ServerDisconnectedError +from . import config from .Credential import Credential from ..exception import ResponseCodeException, ResponseException, NetworkException @@ -89,7 +91,7 @@ async def request(method: str, if params.get("jsonp", "") == "jsonp": params["callback"] = "callback" - config = { + args = { "method": method, "url": url, "params": params, @@ -98,22 +100,24 @@ async def request(method: str, "cookies": credential.get_cookies() } - config.update(kwargs) + args.update(kwargs) if json_body: - config["headers"]["Content-Type"] = "application/json" - config["data"] = json.dumps(config["data"]) - - # 如果用户提供代理则设置代理 - proxy = config.get("PROXY") - if proxy: - config["proxy"] = proxy + args["headers"]["Content-Type"] = "application/json" + args["data"] = json.dumps(args["data"]) session = get_session() for i in range(3): + # 如果用户提供代理则设置代理 + proxy = config.get("PROXY") + if isinstance(proxy, str): + args["proxy"] = proxy + elif isinstance(proxy, list): + args["proxy"] = random.choice(proxy) + try: - async with session.request(**config) as resp: + async with session.request(**args) as resp: # 检查状态码 try: