#!/usr/bin/env python3 """ 腾讯混元3D 邮箱验证码登录 CLI 工具 (CloakBrowser 持久化版本) 第一次输入邮箱回车后自动发送验证码 第二次输入验证码后回车自动点击登录按钮 登录状态会自动保存到 ./hunyuan3d_profile,下次运行无需重新登录 """ import os import sys import time from cloakbrowser import launch_persistent_context from ..config import get_profile_dir, get_cookie_path PROFILE_DIR = str(get_profile_dir()) def _extract_and_save_cookies(context): """从浏览器上下文提取 Cookie 并保存到文件""" try: cookies = context.cookies() relevant_names = {"hunyuan_user", "hunyuan_token", "hunyuan_source", "hy_user"} cookie_dict = {c["name"]: c["value"] for c in cookies if c["name"] in relevant_names} if cookie_dict: cookie_str = "; ".join(f"{k}={v}" for k, v in cookie_dict.items()) cookie_path = get_cookie_path() cookie_path.write_text(cookie_str, encoding="utf-8") print(f"Cookie 已自动保存到: {cookie_path}") return True else: print("警告: 未找到 hunyuan 相关 Cookie,API 客户端可能无法使用") except Exception as e: print(f"自动提取 Cookie 失败: {e}") return False def main(): # 使用持久化上下文,cookie 和登录状态会保存到 PROFILE_DIR context = launch_persistent_context(PROFILE_DIR, headless=False) page = context.new_page() print("正在打开腾讯混元3D...") page.goto("https://3d.hunyuan.tencent.com/") time.sleep(2) # 检查是否已经是登录状态(没有登录按钮说明已登录) login_btn = page.locator("button").filter(has_text="登录").first if login_btn.count() == 0: print("检测到已有登录状态,无需重新登录。") print(f"当前页面: {page.url}") else: # 未登录,走登录流程 login_btn.click() time.sleep(1.5) # 切换到邮箱登录 email_tab = page.locator("text=邮箱").first if email_tab.count() > 0: email_tab.click() time.sleep(1.5) else: print("未找到邮箱登录选项") context.close() return # 定位元素 email_input = page.locator('input[placeholder="请输入邮箱地址"]') code_input = page.locator('input[type="number"][placeholder="请输入邮箱验证码"]') send_code_btn = page.locator("a.hyc-email-login__send-code") login_submit_btn = page.locator("button.hyc-email-login__btn") checkbox = page.locator(".t-checkbox__former") # 第一次交互:输入邮箱并发送验证码 print("\n============================================") email = input("请输入邮箱地址,按回车发送验证码: ").strip() if not email: print("邮箱不能为空,退出") context.close() return email_input.fill(email) time.sleep(0.5) # 勾选协议(如果未勾选) if checkbox.count() > 0: is_checked = checkbox.evaluate("el => el.checked") if not is_checked: checkbox.evaluate("el => el.click()") time.sleep(0.3) if send_code_btn.count() > 0: send_code_btn.click() print("已点击发送验证码,请查收邮件...") else: print("未找到发送验证码按钮") context.close() return # 第二次交互:输入验证码并登录 print("\n============================================") code = input("请输入邮箱验证码,按回车登录: ").strip() if not code: print("验证码不能为空,退出") context.close() return code_input.fill(code) time.sleep(0.5) # 点击登录 if login_submit_btn.count() > 0: login_submit_btn.click() print("已点击登录按钮,等待跳转...") else: print("未找到登录提交按钮") context.close() return # 等待登录成功跳转 try: page.wait_for_url(lambda url: "login" not in url, timeout=30000) print(f"\n登录成功!当前页面: {page.url}") print(f"登录状态已保存到: {os.path.abspath(PROFILE_DIR)}") _extract_and_save_cookies(context) except Exception: print("\n登录可能仍在处理中,或出现错误。请检查浏览器状态。") # 保持浏览器打开 print("\n按 Enter 键关闭浏览器并退出...") input() context.close() if __name__ == "__main__": try: main() except KeyboardInterrupt: print("\n已取消") sys.exit(0)