"""登录接口策略基类""" from abc import ABC, abstractmethod from typing import Tuple class LoginAPIStrategy(ABC): """登录接口策略基类 定义斗鱼登录各步骤的接口地址和参数构建方式。 子类需实现 wgapi 和 iframe 两套接口的差异部分。 """ @property @abstractmethod def name(self) -> str: """策略名称,如 'wgapi'、'iframe'""" ... @property @abstractmethod def first_login_url(self) -> str: """第一次登录接口 URL(获取极验参数)""" ... @property @abstractmethod def login_url(self) -> str: """第二次登录接口 URL(带极验验证)""" ... @property @abstractmethod def send_email_url(self) -> str: """发送邮箱验证 URL""" ... @property @abstractmethod def verify_url(self) -> str: """提交验证码 URL""" ... @abstractmethod def encrypt_username(self, username: str) -> str: """加密用户名(各接口加密方式不同)""" ... @abstractmethod def build_first_login_data(self, username: str, password: str, referer: str) -> dict: """构建第一次登录请求参数(获取极验参数)""" ... @abstractmethod def build_second_login_data( self, username: str, password: str, gt: str, challenge: str, validate: str, seccode: str, code_token: str, referer: str, ) -> dict: """构建第二次登录请求参数(带极验验证)""" ... @abstractmethod def build_send_email_data(self, code: str) -> dict: """构建发送邮箱验证参数""" ... @abstractmethod def build_verify_data(self, code: str, captcha: str) -> dict: """构建提交验证码参数""" ... def extract_geetest_params(self, payload: dict) -> Tuple[str, str, str]: """从第一次登录响应提取极验参数 Args: payload: 登录接口响应 JSON Returns: (gt, challenge, code_token) """ geetest_data = payload.get('data', {}).get('geetest', {}) code_data = geetest_data.get('code_data', {}) gt = code_data.get('gt', '') challenge = code_data.get('challenge', '') code_token = geetest_data.get('code_token', '') return gt, challenge, code_token def extract_remote_code(self, payload: dict) -> str: """从第二次登录响应提取 remote_code Args: payload: 登录接口响应 JSON Returns: remote_code 字符串 """ return payload.get('data', {}).get('remoteLogin', {}).get('code', '') def extract_login_url(self, payload: dict) -> str: """从验证码响应提取登录 URL Args: payload: 提交验证码接口响应 JSON Returns: 登录回调 URL """ return payload.get('data', {}).get('url', '')