From 0faaa2c30271c6576b4d147858647df2482e3774 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Fri, 26 Jun 2026 17:43:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8F=A6=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E6=8E=A5=E5=8F=A3-=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/douyu/login.py | 7 +++++- core/douyu/login_api_iframe.py | 45 ++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/core/douyu/login.py b/core/douyu/login.py index 83a383b..086b95a 100644 --- a/core/douyu/login.py +++ b/core/douyu/login.py @@ -543,7 +543,12 @@ class DouyuLogin: remote_code = self.api.extract_remote_code(payload) if not remote_code: - raise ValueError("获取remote_code失败") + # 提取可能的风控提示 + data = payload.get('data', {}) + security_quiz = data.get('securityQuiz', '') + msg = payload.get('msg', '') + detail = security_quiz or msg or '未知原因' + raise ValueError(f"获取remote_code失败: {detail}") logger.info(f"获取remote_code成功: {remote_code[:20]}...") diff --git a/core/douyu/login_api_iframe.py b/core/douyu/login_api_iframe.py index 0988e48..ae21ca2 100644 --- a/core/douyu/login_api_iframe.py +++ b/core/douyu/login_api_iframe.py @@ -10,13 +10,11 @@ from .login_api import LoginAPIStrategy class IframeLoginAPI(LoginAPIStrategy): """iframe 版接口策略 - 使用旧版 iframe 接口,参数嵌套结构,用户名 RC4 加密后 URL 编码。 - 第一次登录使用 wgapi 接口获取极验参数,第二次登录使用 iframe 接口。 + 混合模式(与 e 语言一致): + - 登录:使用 wgapi 接口 + - 邮箱验证:使用 iframe 接口 """ - # e 语言中硬编码的 did 值 - DEFAULT_DID = "6ab33184203a7d50d5f9a8fa00021701" - @property def name(self) -> str: return "iframe" @@ -28,15 +26,17 @@ class IframeLoginAPI(LoginAPIStrategy): @property def login_url(self) -> str: - """第二次登录用 iframe 接口""" - return "https://passport.douyu.com/iframe/loginNew" + """第二次登录用 wgapi 接口(与 e 语言一致)""" + return "https://passport.douyu.com/wgapi/member/passport/login" @property def send_email_url(self) -> str: + """发送邮箱验证用 iframe 接口""" return "https://passport.douyu.com/iframe/sendEmail" @property def verify_url(self) -> str: + """提交验证码用 iframe 接口""" return "https://passport.douyu.com/iframe/remoteLogin" def encrypt_username(self, username: str) -> str: @@ -78,28 +78,37 @@ class IframeLoginAPI(LoginAPIStrategy): ) -> dict: """构建第二次登录参数(带极验验证) - 使用 iframe 接口的嵌套参数结构。 - 注意:iframe 接口使用 username 参数(直接用户名URL编码),而非 nicknameOrPhoneEncrypt。 + 登录使用 wgapi 接口,参数格式与 wgapi 策略一致。 """ - # seccode 格式: validate|jordan - seccode_value = validate + '%7Cjordan' + # seccode 格式: validate|jordan(requests 会自动 URL 编码) + seccode_value = validate + '|jordan' + + # 使用 base64 编码(wgapi 接口要求),而不是 URL 编码 + encrypted_username = encrypt_nickname_or_phone(username) return { - 'username': username, # iframe 接口用 username,直接用户名 + 'type': '1', + 'nicknameOrPhoneEncrypt': encrypted_username, 'password': encrypt_password(password), 'room_id': '0', - 'code_verify_data[code_type]': '1', - 'code_verify_data[code_token]': code_token, - 'code_verify_data[code_data][geetest_challenge]': challenge, - 'code_verify_data[code_data][geetest_validate]': validate, - 'code_verify_data[code_data][geetest_seccode]': seccode_value, - 'code_verify_data[code_data][gt_version]': 'v3', + 'code_type': '1', + 'code_token': code_token, + 'gt_version': 'v3', + 'geetest_challenge': challenge, + 'geetest_validate': validate, + 'geetest_seccode': seccode_value, + 'code_data[geetest_challenge]': challenge, + 'code_data[geetest_validate]': validate, + 'code_data[geetest_seccode]': seccode_value, + 'code_data[gt_version]': 'v3', + 'code_data[code]': '', 'redirect_url': referer, 't': str(int(time.time() * 1000)), 'client_id': '1', 'did': '', 'lang': '', 'isMultiAccount': '0', + 'biz_type': '1', } def build_send_email_data(self, code: str) -> dict: