diff --git a/browser_automation.py b/browser_automation.py index 9dae842..5c35ac3 100644 --- a/browser_automation.py +++ b/browser_automation.py @@ -3025,6 +3025,102 @@ def perform_s2a_authorization(page, email: str, password: str) -> bool: log_current_url(page, "S2A-密码步骤完成后") + # 检查是否需要邮箱验证码 + time.sleep(1) + current_url = page.url + if "/email-verification" in current_url: + log.step("检测到邮箱验证码页面,开始获取验证码...") + progress_update(phase="授权", step="等待验证码...") + + # 获取验证码 + verification_code, error, email_time = unified_get_verification_code(email) + + if not verification_code: + log.warning(f"自动获取验证码失败: {error}") + verification_code = input(" ⚠️ 请手动输入验证码: ").strip() + + if not verification_code: + log.error("S2A 无法获取邮箱验证码") + return False + + # 验证码重试循环 (最多重试 3 次) + max_code_retries = 3 + for code_attempt in range(max_code_retries): + log.step(f"输入验证码: {verification_code}") + + # 查找验证码输入框 + code_input = wait_for_element(page, 'css:input[name="code"]', timeout=10) + if not code_input: + code_input = wait_for_element(page, 'css:input[autocomplete="one-time-code"]', timeout=5) + if not code_input: + code_input = wait_for_element(page, 'css:input[inputmode="numeric"]', timeout=5) + + if not code_input: + log.error("S2A 无法找到验证码输入框") + return False + + # 清空并输入验证码 + try: + code_input.clear() + except Exception: + pass + type_slowly(page, 'css:input[name="code"], input[autocomplete="one-time-code"], input[inputmode="numeric"]', verification_code, base_delay=0.08) + time.sleep(0.5) + + # 点击继续 + log.step("点击继续...") + continue_btn = wait_for_element(page, 'css:button[type="submit"]', timeout=10) + if continue_btn: + old_url = page.url + continue_btn.click() + time.sleep(2) + + # 检查是否出现验证码错误 + try: + error_text = page.ele('text:代码不正确', timeout=1) + if not error_text: + error_text = page.ele('text:incorrect', timeout=1) + if not error_text: + error_text = page.ele('text:Invalid code', timeout=1) + + if error_text and error_text.states.is_displayed: + if code_attempt < max_code_retries - 1: + log.warning(f"S2A 验证码错误,尝试重新获取 ({code_attempt + 1}/{max_code_retries})...") + + # 点击重新发送 + resend_btn = page.ele('text:重新发送电子邮件', timeout=3) + if not resend_btn: + resend_btn = page.ele('text:Resend email', timeout=2) + if not resend_btn: + resend_btn = page.ele('text:resend', timeout=2) + + if resend_btn: + resend_btn.click() + log.info("已点击重新发送,等待新验证码...") + time.sleep(3) + + verification_code, error, email_time = unified_get_verification_code(email) + if not verification_code: + verification_code = input(" ⚠️ 请手动输入验证码: ").strip() + if verification_code: + continue + log.warning("S2A 无法重新发送验证码") + else: + log.error("S2A 验证码多次错误,放弃") + return False + else: + # 没有错误,验证码正确 + break + except Exception: + # 没有检测到错误元素,说明验证码正确 + break + + # 等待 URL 变化 + wait_for_url_change(page, old_url, timeout=5) + log_url_change(page, old_url, "S2A-输入验证码后") + + log_current_url(page, "S2A-验证码步骤完成后") + # 检查是否在授权确认页面,如果是则点击授权按钮 time.sleep(1) current_url = page.url @@ -3096,6 +3192,52 @@ def perform_s2a_authorization(page, email: str, password: str) -> bool: # 检测错误 check_and_handle_error(page) + # 检查是否在邮箱验证码页面 (有几率出现) + if "/email-verification" in current_url: + if progress_shown: + log.progress_clear() + progress_shown = False + log.step("回调等待中检测到邮箱验证码页面...") + progress_update(phase="授权", step="等待验证码...") + + verification_code, error, email_time = unified_get_verification_code(email) + if not verification_code: + log.warning(f"自动获取验证码失败: {error}") + verification_code = input(" ⚠️ 请手动输入验证码: ").strip() + if not verification_code: + log.error("S2A 无法获取邮箱验证码") + return False + + # 查找验证码输入框 + code_input = wait_for_element(page, 'css:input[name="code"]', timeout=5) + if not code_input: + code_input = wait_for_element(page, 'css:input[autocomplete="one-time-code"]', timeout=3) + if not code_input: + code_input = wait_for_element(page, 'css:input[inputmode="numeric"]', timeout=3) + + if code_input: + try: + code_input.clear() + except Exception: + pass + type_slowly(page, 'css:input[name="code"], input[autocomplete="one-time-code"], input[inputmode="numeric"]', verification_code, base_delay=0.08) + time.sleep(0.5) + + submit_btn = wait_for_element(page, 'css:button[type="submit"]', timeout=5) + if submit_btn: + old_url = page.url + submit_btn.click() + log.step("已提交验证码,等待页面跳转...") + wait_for_url_change(page, old_url, timeout=10) + log_url_change(page, old_url, "S2A-回调循环中输入验证码后") + else: + log.warning("S2A 回调循环中未找到验证码输入框") + + # 重置标记,让循环重新检测新页面状态 + auth_btn_clicked = False + error_detected = False + continue + # 检查是否需要点击 Authorize (只点击一次) if not auth_btn_clicked: try: