Explorar el Código

分离重置机器码和注册流程

chendeben hace 1 año
padre
commit
f32def3b11
Se han modificado 2 ficheros con 151 adiciones y 25 borrados
  1. 144 22
      cursor_pro_keep_alive.py
  2. 7 3
      get_email_code.py

+ 144 - 22
cursor_pro_keep_alive.py

@@ -1,4 +1,7 @@
 import os
+import sys
+from enum import Enum
+from typing import Optional
 
 from exit_cursor import ExitCursor
 from reset_machine import MachineIDResetter
@@ -16,13 +19,96 @@ from get_email_code import EmailVerificationHandler
 from logo import print_logo
 from config import Config
 
+# 定义 EMOJI 字典
+EMOJI = {"ERROR": "❌", "WARNING": "⚠️", "INFO": "ℹ️"}
 
-def handle_turnstile(tab):
+
+class VerificationStatus(Enum):
+    """验证状态枚举"""
+
+    PASSWORD_PAGE = "@name=password"
+    CAPTCHA_PAGE = "@data-index=0"
+    ACCOUNT_SETTINGS = "Account Settings"
+
+
+class TurnstileError(Exception):
+    """Turnstile 验证相关异常"""
+
+    pass
+
+
+def save_screenshot(tab, stage: str, timestamp: bool = True) -> None:
+    """
+    保存页面截图
+
+    Args:
+        tab: 浏览器标签页对象
+        stage: 截图阶段标识
+        timestamp: 是否添加时间戳
+    """
+    try:
+        # 创建 screenshots 目录
+        screenshot_dir = "screenshots"
+        if not os.path.exists(screenshot_dir):
+            os.makedirs(screenshot_dir)
+
+        # 生成文件名
+        if timestamp:
+            filename = f"turnstile_{stage}_{int(time.time())}.png"
+        else:
+            filename = f"turnstile_{stage}.png"
+
+        filepath = os.path.join(screenshot_dir, filename)
+
+        # 保存截图
+        tab.get_screenshot(filepath)
+        logging.debug(f"截图已保存: {filepath}")
+    except Exception as e:
+        logging.warning(f"截图保存失败: {str(e)}")
+
+
+def check_verification_success(tab) -> Optional[VerificationStatus]:
+    """
+    检查验证是否成功
+
+    Returns:
+        VerificationStatus: 验证成功时返回对应状态,失败返回 None
+    """
+    for status in VerificationStatus:
+        if tab.ele(status.value):
+            logging.info(f"验证成功 - 已到达{status.name}页面")
+            return status
+    return None
+
+
+def handle_turnstile(tab, max_retries: int = 2, retry_interval: tuple = (1, 2)) -> bool:
+    """
+    处理 Turnstile 验证
+
+    Args:
+        tab: 浏览器标签页对象
+        max_retries: 最大重试次数
+        retry_interval: 重试间隔时间范围(最小值, 最大值)
+
+    Returns:
+        bool: 验证是否成功
+
+    Raises:
+        TurnstileError: 验证过程中出现异常
+    """
     logging.info("正在检测 Turnstile 验证...")
+    save_screenshot(tab, "start")
+
+    retry_count = 0
+
     try:
-        while True:
+        while retry_count < max_retries:
+            retry_count += 1
+            logging.debug(f"第 {retry_count} 次尝试验证")
+
             try:
-                challengeCheck = (
+                # 定位验证框元素
+                challenge_check = (
                     tab.ele("@id=cf-turnstile", timeout=2)
                     .child()
                     .shadow_root.ele("tag:iframe")
@@ -30,31 +116,43 @@ def handle_turnstile(tab):
                     .sr("tag:input")
                 )
 
-                if challengeCheck:
-                    logging.info("检测到 Turnstile 验证,正在处理...")
+                if challenge_check:
+                    logging.info("检测到 Turnstile 验证框,开始处理...")
+                    # 随机延时后点击验证
                     time.sleep(random.uniform(1, 3))
-                    challengeCheck.click()
+                    challenge_check.click()
                     time.sleep(2)
-                    logging.info("Turnstile 验证通过")
-                    return True
-            except:
-                pass
 
-            if tab.ele("@name=password"):
-                logging.info("验证成功 - 已到达密码输入页面")
-                break
-            if tab.ele("@data-index=0"):
-                logging.info("验证成功 - 已到达验证码输入页面")
-                break
-            if tab.ele("Account Settings"):
-                logging.info("验证成功 - 已到达账户设置页面")
-                break
+                    # 保存验证后的截图
+                    save_screenshot(tab, "clicked")
 
-            time.sleep(random.uniform(1, 2))
-    except Exception as e:
-        logging.error(f"Turnstile 验证失败: {str(e)}")
+                    # 检查验证结果
+                    if check_verification_success(tab):
+                        logging.info("Turnstile 验证通过")
+                        save_screenshot(tab, "success")
+                        return True
+
+            except Exception as e:
+                logging.debug(f"当前尝试未成功: {str(e)}")
+
+            # 检查是否已经验证成功
+            if check_verification_success(tab):
+                return True
+
+            # 随机延时后继续下一次尝试
+            time.sleep(random.uniform(*retry_interval))
+
+        # 超出最大重试次数
+        logging.error(f"验证失败 - 已达到最大重试次数 {max_retries}")
+        save_screenshot(tab, "failed")
         return False
 
+    except Exception as e:
+        error_msg = f"Turnstile 验证过程发生异常: {str(e)}"
+        logging.error(error_msg)
+        save_screenshot(tab, "error")
+        raise TurnstileError(error_msg)
+
 
 def get_cursor_session_token(tab, max_attempts=3, retry_interval=2):
     """
@@ -262,6 +360,30 @@ if __name__ == "__main__":
     try:
         logging.info("\n=== 初始化程序 ===")
         ExitCursor()
+
+        # 提示用户选择操作模式
+        print("\n请选择操作模式:")
+        print("1. 仅重置机器码")
+        print("2. 完整注册流程")
+
+        while True:
+            try:
+                choice = int(input("请输入选项 (1 或 2): ").strip())
+                if choice in [1, 2]:
+                    break
+                else:
+                    print("无效的选项,请重新输入")
+            except ValueError:
+                print("请输入有效的数字")
+
+        if choice == 1:
+            # 仅执行重置机器码
+            logging.info("正在重置机器码...")
+            MachineIDResetter().reset_machine_ids()
+            logging.info("机器码重置完成")
+            sys.exit(0)
+
+        # 如果选择2,继续执行完整注册流程
         logging.info("正在初始化浏览器...")
         browser_manager = BrowserManager()
         browser = browser_manager.init_browser()

+ 7 - 3
get_email_code.py

@@ -108,11 +108,15 @@ class EmailVerificationHandler:
                 clean_text = re.sub(r'<[^>]+>', '', clean_text)
                 # 移除多余的空白字符
                 clean_text = re.sub(r'\s+', ' ', clean_text).strip()
-                print("过滤后的邮件内容:", clean_text)
+                # print("过滤后的邮件内容:", clean_text)
                 # 从纯文本中提取 6 位数字验证码
-                code_match = re.search(r'Your verification code is (\d{6})', clean_text)
+                pattern = r'\b(\d{6})\b'
+                code_match = re.search(pattern, clean_text)
+
+                # code_match = re.search(r'Your verification code is (\d{6})', clean_text)
                 if code_match:
-                    return code_match.group(1)
+                    print("提取到验证码", code_match.group(0))
+                    return code_match.group(0)
             except Exception as e:
                 print(f"处理邮件内容时出错: {str(e)}")
                 time.sleep(retry_interval)