Browse Source

Add browser management and email verification functionality

- Introduced `BrowserManager` class in `browser_utils.py` for streamlined browser initialization and configuration.
- Added `EmailVerificationHandler` class in `get_veri_code.py` to handle email verification code retrieval.
- Updated `cursor_pro_keep_alive.py` to utilize the new browser and email handling classes, improving code organization and readability.
- Modified `config.ini` to update the email address for account configuration.
- Removed obsolete `log.txt` file to clean up the project structure.
- Added unit tests for email verification functionality in `test/get_veri_code_test.py`.
cheng zhen 1 năm trước cách đây
mục cha
commit
1757e5ed2f
6 tập tin đã thay đổi với 313 bổ sung214 xóa
  1. 59 0
      browser_utils.py
  2. 1 1
      config.ini
  3. 39 123
      cursor_pro_keep_alive.py
  4. 88 0
      get_veri_code.py
  5. 0 90
      log.txt
  6. 126 0
      test/get_veri_code_test.py

+ 59 - 0
browser_utils.py

@@ -0,0 +1,59 @@
+from DrissionPage import ChromiumOptions, Chromium
+import sys
+import os
+import logging
+
+
+class BrowserManager:
+    def __init__(self):
+        self.browser = None
+
+    def init_browser(self):
+        """初始化浏览器"""
+        co = self._get_browser_options()
+        self.browser = Chromium(co)
+        return self.browser
+
+    def _get_browser_options(self):
+        """获取浏览器配置"""
+        co = ChromiumOptions()
+        try:
+            extension_path = self._get_extension_path()
+            co.add_extension(extension_path)
+        except FileNotFoundError as e:
+            logging.warning(f"警告: {e}")
+
+        co.set_user_agent(
+            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.92 Safari/537.36"
+        )
+        co.set_pref("credentials_enable_service", False)
+        co.set_argument("--hide-crash-restore-bubble")
+        co.auto_port()
+
+        # Mac 系统特殊处理
+        if sys.platform == "darwin":
+            co.set_argument("--no-sandbox")
+            co.set_argument("--disable-gpu")
+
+        return co
+
+    def _get_extension_path(self):
+        """获取插件路径"""
+        root_dir = os.getcwd()
+        extension_path = os.path.join(root_dir, "turnstilePatch")
+
+        if hasattr(sys, "_MEIPASS"):
+            extension_path = os.path.join(sys._MEIPASS, "turnstilePatch")
+
+        if not os.path.exists(extension_path):
+            raise FileNotFoundError(f"插件不存在: {extension_path}")
+
+        return extension_path
+
+    def quit(self):
+        """关闭浏览器"""
+        if self.browser:
+            try:
+                self.browser.quit()
+            except:
+                pass

+ 1 - 1
config.ini

@@ -1,5 +1,5 @@
 [Account]
-email = apxeme@mailto.plus
+email = dounpuv@mailto.plus
 password = ccz14321@
 first_name = cheng
 last_name = zhen 

+ 39 - 123
cursor_pro_keep_alive.py

@@ -13,6 +13,8 @@ from configparser import ConfigParser
 import os
 import sys
 import logging
+from browser_utils import BrowserManager
+from get_veri_code import EmailVerificationHandler
 
 # 在文件开头设置日志
 logging.basicConfig(
@@ -53,57 +55,6 @@ def load_config():
     raise FileNotFoundError(f"配置文件不存在: {config_path}")
 
 
-def get_veri_code(tab):
-    """获取验证码"""
-    username = account.split("@")[0]
-    try:
-        while True:
-            if tab.ele("@id=pre_button"):
-                tab.actions.click("@id=pre_button").type(Keys.CTRL_A).key_down(
-                    Keys.BACKSPACE
-                ).key_up(Keys.BACKSPACE).input(username).key_down(Keys.ENTER).key_up(
-                    Keys.ENTER
-                )
-                break
-            time.sleep(1)
-
-        while True:
-            new_mail = tab.ele("@class=mail")
-            if new_mail:
-                if new_mail.text:
-                    print("最新的邮件:", new_mail.text)
-                    tab.actions.click("@class=mail")
-                    break
-                else:
-                    print(new_mail)
-                    break
-            time.sleep(1)
-
-        if tab.ele("@class=overflow-auto mb-20"):
-            email_content = tab.ele("@class=overflow-auto mb-20").text
-            verification_code = re.search(
-                r"verification code is (\d{6})", email_content
-            )
-            if verification_code:
-                code = verification_code.group(1)
-                print("验证码:", code)
-            else:
-                print("未找到验证码")
-
-        if tab.ele("@id=delete_mail"):
-            tab.actions.click("@id=delete_mail")
-            time.sleep(1)
-
-        if tab.ele("@id=confirm_mail"):
-            tab.actions.click("@id=confirm_mail")
-            print("删除邮件")
-        tab.close()
-    except Exception as e:
-        print(e)
-
-    return code
-
-
 def handle_turnstile(tab):
     """处理 Turnstile 验证"""
     print("准备处理验证")
@@ -193,14 +144,10 @@ def delete_account(browser, tab):
             if tab.ele("Account Settings"):
                 break
             if tab.ele("@data-index=0"):
-                tab_mail = browser.new_tab(mail_url)
-                browser.activate_tab(tab_mail)
-                print("打开邮箱页面")
-                code = get_veri_code(tab_mail)
+                code = email_handler.get_verification_code(account)
 
                 if code:
                     print("获取验证码成功:", code)
-                    browser.activate_tab(tab)
                 else:
                     print("获取验证码失败,程序退出")
                     return False
@@ -266,10 +213,14 @@ def get_cursor_session_token(tab):
     """获取cursor session token"""
     cookies = tab.cookies()
     cursor_session_token = None
+    time.sleep(3)
+    print(cookies)
     for cookie in cookies:
         if cookie["name"] == "WorkosCursorSessionToken":
             cursor_session_token = cookie["value"].split("%3A%3A")[1]
             break
+    if not cursor_session_token:
+        print("未能获取到CursorSessionToken")
     return cursor_session_token
 
 
@@ -333,14 +284,10 @@ def sign_up_account(browser, tab):
             if tab.ele("Account Settings"):
                 break
             if tab.ele("@data-index=0"):
-                tab_mail = browser.new_tab(mail_url)
-                browser.activate_tab(tab_mail)
-                print("打开邮箱页面")
-                code = get_veri_code(tab_mail)
+                code = email_handler.get_verification_code(account)
 
                 if code:
                     print("获取验证码成功:", code)
-                    browser.activate_tab(tab)
                 else:
                     print("获取验证码失败,程序退出")
                     return False
@@ -377,49 +324,6 @@ def sign_up_account(browser, tab):
     return True
 
 
-def get_extension_path():
-    """获取插件路径"""
-    root_dir = os.getcwd()
-    extension_path = os.path.join(root_dir, "turnstilePatch")
-
-    if hasattr(sys, "_MEIPASS"):
-        print("运行在打包环境中")
-        extension_path = os.path.join(sys._MEIPASS, "turnstilePatch")
-
-    print(f"尝试加载插件路径: {extension_path}")
-
-    if not os.path.exists(extension_path):
-        raise FileNotFoundError(
-            f"插件不存在: {extension_path}\n请确保 turnstilePatch 文件夹在正确位置"
-        )
-
-    return extension_path
-
-
-def get_browser_options():
-    co = ChromiumOptions()
-    try:
-        extension_path = get_extension_path()
-        co.add_extension(extension_path)
-    except FileNotFoundError as e:
-        print(f"警告: {e}")
-
-    co.headless()
-    co.set_user_agent(
-        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.92 Safari/537.36"
-    )
-    co.set_pref("credentials_enable_service", False)
-    co.set_argument("--hide-crash-restore-bubble")
-    co.auto_port()
-
-    # Mac 系统特殊处理
-    if sys.platform == "darwin":
-        co.set_argument("--no-sandbox")
-        co.set_argument("--disable-gpu")
-
-    return co
-
-
 def cleanup_temp_files():
     """清理临时文件和缓存"""
     try:
@@ -438,11 +342,18 @@ def cleanup_temp_files():
 
 
 if __name__ == "__main__":
-    browser = None
+    browser_manager = None
     try:
         # 加载配置
         config = load_config()
 
+        # 初始化浏览器
+        browser_manager = BrowserManager()
+        browser = browser_manager.init_browser()
+
+        # 初始化��箱验证处理器
+        email_handler = EmailVerificationHandler(browser)
+
         # 固定的 URL 配置
         login_url = "https://authenticator.cursor.sh"
         sign_up_url = "https://authenticator.cursor.sh/sign-up"
@@ -457,10 +368,6 @@ if __name__ == "__main__":
 
         auto_update_cursor_auth = True
 
-        # 浏览器配置
-        co = get_browser_options()
-
-        browser = Chromium(co)
         tab = browser.latest_tab
         tab.run_js("try { turnstile.reset() } catch(e) { }")
 
@@ -474,29 +381,38 @@ if __name__ == "__main__":
             time.sleep(3)
             if sign_up_account(browser, tab):
                 token = get_cursor_session_token(tab)
-                print(f"CursorSessionToken: {token}")
-                print("账户注册成功")
-                if auto_update_cursor_auth:
-                    update_cursor_auth(
-                        email=account, access_token=token, refresh_token=token
-                    )
+                if token:
+                    print(f"CursorSessionToken: {token}")
+                    print("账户注册成功")
+                    if auto_update_cursor_auth:
+                        update_cursor_auth(
+                            email=account, access_token=token, refresh_token=token
+                        )
+                else:
+                    print("未能获取到CursorSessionToken")
             else:
                 print("账户注册失败")
         else:
             print("账户删除失败")
+        # if sign_up_account(browser, tab):
+        #     token = get_cursor_session_token(tab)
+        #     print(f"CursorSessionToken: {token}")
+        #     print("账户注册成功")
+        #     if auto_update_cursor_auth:
+        #         update_cursor_auth(
+        #             email=account, access_token=token, refresh_token=token
+        #         )
+        #     else:
+        #         print("账户注册失败")
 
         print("脚本执行完毕")
 
     except Exception as e:
-        print(f"程序执行出错: {str(e)}")
+        logging.error(f"程序执行出错: {str(e)}")
         import traceback
 
-        print(traceback.format_exc())
+        logging.error(traceback.format_exc())
     finally:
-        # 确保浏览器实例被正确关闭
-        if browser:
-            try:
-                browser.quit()
-            except:
-                pass
+        if browser_manager:
+            browser_manager.quit()
         input("\n按回车键退出...")

+ 88 - 0
get_veri_code.py

@@ -0,0 +1,88 @@
+from DrissionPage.common import Keys
+import time
+import re
+import logging
+
+
+class EmailVerificationHandler:
+    def __init__(self, browser, mail_url="https://tempmail.plus"):
+        self.browser = browser
+        self.mail_url = mail_url
+
+    def get_verification_code(self, email):
+        """获取邮箱验证码"""
+        username = email.split("@")[0]
+        code = None
+
+        try:
+            # 打开新标签页访问临时邮箱
+            tab_mail = self.browser.new_tab(self.mail_url)
+            self.browser.activate_tab(tab_mail)
+            logging.info("打开邮箱页面")
+
+            # 输入用户名
+            self._input_username(tab_mail, username)
+
+            # 等待并获取最新邮件
+            code = self._get_latest_mail_code(tab_mail)
+
+            # 清理邮件
+            self._cleanup_mail(tab_mail)
+
+            # 关闭标签页
+            tab_mail.close()
+
+        except Exception as e:
+            logging.error(f"获取验证码失败: {str(e)}")
+
+        return code
+
+    def _input_username(self, tab, username):
+        """输入用户名"""
+        while True:
+            if tab.ele("@id=pre_button"):
+                tab.actions.click("@id=pre_button")
+                time.sleep(0.5)
+                tab.run_js('document.getElementById("pre_button").value = ""')
+                time.sleep(0.5)
+                tab.actions.input(username).key_down(Keys.ENTER).key_up(Keys.ENTER)
+                break
+            time.sleep(1)
+
+    def _get_latest_mail_code(self, tab):
+        """获取最新邮件中的验证码"""
+        code = None
+        while True:
+            new_mail = tab.ele("@class=mail")
+            if new_mail:
+                if new_mail.text:
+                    logging.info(f"最新的邮件:{new_mail.text}")
+                    tab.actions.click("@class=mail")
+                    break
+                else:
+                    logging.info(str(new_mail))
+                    break
+            time.sleep(1)
+
+        if tab.ele("@class=overflow-auto mb-20"):
+            email_content = tab.ele("@class=overflow-auto mb-20").text
+            verification_code = re.search(
+                r"verification code is (\d{6})", email_content
+            )
+            if verification_code:
+                code = verification_code.group(1)
+                logging.info(f"验证码:{code}")
+            else:
+                logging.warning("未找到验证码")
+
+        return code
+
+    def _cleanup_mail(self, tab):
+        """清理邮件"""
+        if tab.ele("@id=delete_mail"):
+            tab.actions.click("@id=delete_mail")
+            time.sleep(1)
+
+        if tab.ele("@id=confirm_mail"):
+            tab.actions.click("@id=confirm_mail")
+            logging.info("删除邮件")

+ 0 - 90
log.txt

@@ -1,90 +0,0 @@
-[2024/12/26 周四 13:11:03.37] 寮€濮嬫墽琛岃剼鏈?
-[2024/12/26 周四 13:17:58.13] 寮€濮嬫墽琛岃剼鏈?
-开始执行删除和注册流程
-***请确认已经用https://tempmail.plus/zh邮箱成功申请过cursor账号!***
-
-开始删除账户...
-输入账号
-点击Continue
-准备处理验证
-验证框加载完成
-验证按钮已点击,等待验证完成...
-输入密码
-点击Sign in
-准备处理验证
-验证框加载完成
-验证按钮已点击,等待验证完成...
-准备处理验证
-无需验证
-进入设置页面
-点击Adavance
-点击Delete Account
-输入delete
-点击Delete
-账户删除成功
-
-开始注册新账户...
-已打开注册页面
-输入邮箱
-点击注册按钮
-准备处理验证
-验证框加载完成
-验证按钮已点击,等待验证完成...
-输入密码
-点击Continue按钮
-准备处理验证
-验证框加载完成
-验证按钮已点击,等待验证完成...
-打开邮箱页面
-最新的邮件: Cursor <no-reply@cursor.sh>
-07:19
-Verify your email address
-验证码: 227917
-删除邮件
-获取验证码成功: 227917
-准备处理验证
-验证框加载完成
-验证按钮已点击,等待验证完成...
-进入设置页面
-注册完成
-Cursor 账号: apxeme@mailto.plus
-       密码: ccz14321@
-CursorSessionToken: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSkcwUEZXQUNHSEQ5SDVNU1RWWlFHUDZOIiwidGltZSI6IjE3MzUxOTA0MDEiLCJyYW5kb21uZXNzIjoiYTM4NDBhYzEtZGYwNi00NDhkIiwiZXhwIjo0MzI3MTkwNDAxLCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.YYQ_C4BjbkHlShTFElkOvXFDqA8kYA-aWMqHKLa5RsU
-账户注册成功
-成功更新 cachedEmail
-成功更新 accessToken
-成功更新 refreshToken
-脚本执行完毕
-[2024/12/26 周四 13:20:14.57] 鑴氭湰鎵ц�瀹屾垚 
-Traceback (most recent call last):
-  File "cursor_pro_keep_alive.py", line 370, in <module>
-    if delete_account(browser, tab):
-       ~~~~~~~~~~~~~~^^^^^^^^^^^^^^
-  File "cursor_pro_keep_alive.py", line 146, in delete_account
-    if tab.ele("Account Settings"):
-       ~~~~~~~^^^^^^^^^^^^^^^^^^^^
-  File "DrissionPage\_pages\mix_tab.py", line 109, in ele
-  File "DrissionPage\_pages\chromium_base.py", line 424, in ele
-  File "DrissionPage\_base\base.py", line 356, in _ele
-  File "DrissionPage\_pages\mix_tab.py", line 192, in _find_elements
-  File "DrissionPage\_pages\chromium_base.py", line 492, in _find_elements
-  File "DrissionPage\_base\driver.py", line 176, in run
-  File "DrissionPage\_base\driver.py", line 84, in _send
-  File "queue.py", line 213, in get
-  File "threading.py", line 363, in wait
-KeyboardInterrupt
-[PYI-35588:ERROR] Failed to execute script 'cursor_pro_keep_alive' due to unhandled exception!
-开始执行删除和注册流程
-***请确认已经用https://tempmail.plus/zh邮箱成功申请过cursor账号!***
-
-开始删除账户...
-输入账号
-点击Continue
-准备处理验证
-验证框加载完成
-验证按钮已点击,等待验证完成...
-输入密码
-点击Sign in
-准备处理验证
-验证框加载完成
-验证按钮已点击,等待验证完成...

+ 126 - 0
test/get_veri_code_test.py

@@ -0,0 +1,126 @@
+from DrissionPage import ChromiumOptions, Chromium
+from DrissionPage.common import Keys
+import time
+import re
+import sys
+import os
+
+
+def get_extension_path():
+    """获取插件路径"""
+    root_dir = os.getcwd()
+    extension_path = os.path.join(root_dir, "turnstilePatch")
+
+    if hasattr(sys, "_MEIPASS"):
+        print("运行在打包环境中")
+        extension_path = os.path.join(sys._MEIPASS, "turnstilePatch")
+
+    print(f"尝试加载插件路径: {extension_path}")
+
+    if not os.path.exists(extension_path):
+        raise FileNotFoundError(
+            f"插件不存在: {extension_path}\n请确保 turnstilePatch 文件夹在正确位置"
+        )
+
+    return extension_path
+
+
+def get_browser_options():
+    co = ChromiumOptions()
+    try:
+        extension_path = get_extension_path()
+        co.add_extension(extension_path)
+    except FileNotFoundError as e:
+        print(f"警告: {e}")
+
+    co.set_user_agent(
+        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.92 Safari/537.36"
+    )
+    co.set_pref("credentials_enable_service", False)
+    co.set_argument("--hide-crash-restore-bubble")
+    co.auto_port()
+
+    # Mac 系统特殊处理
+    if sys.platform == "darwin":
+        co.set_argument("--no-sandbox")
+        co.set_argument("--disable-gpu")
+
+    return co
+
+
+def get_veri_code(username):
+    # 使用相同的浏览器配置
+    co = get_browser_options()
+    browser = Chromium(co)
+    code = None
+
+    try:
+        # 获取当前标签页
+        tab = browser.latest_tab
+        tab.run_js("try { turnstile.reset() } catch(e) { }")
+
+        # 打开临时邮箱网站
+        tab.get("https://tempmail.plus/zh")
+        time.sleep(2)
+
+        # 设置邮箱用户名
+        while True:
+            if tab.ele("@id=pre_button"):
+                # 点击输入框
+                tab.actions.click("@id=pre_button")
+                time.sleep(1)
+                # 删除之前的内容
+                tab.run_js('document.getElementById("pre_button").value = ""')
+
+                # 输入新用户名并回车
+                tab.actions.input(username).key_down(Keys.ENTER).key_up(Keys.ENTER)
+                break
+            time.sleep(1)
+
+        # 等待并获取新邮件
+        while True:
+            new_mail = tab.ele("@class=mail")
+            if new_mail:
+                if new_mail.text:
+                    print("最新的邮件:", new_mail.text)
+                    tab.actions.click("@class=mail")
+                    break
+                else:
+                    print(new_mail)
+                    break
+            time.sleep(1)
+
+        # 提取验证码
+        if tab.ele("@class=overflow-auto mb-20"):
+            email_content = tab.ele("@class=overflow-auto mb-20").text
+            verification_code = re.search(
+                r"verification code is (\d{6})", email_content
+            )
+            if verification_code:
+                code = verification_code.group(1)
+                print("验证码:", code)
+            else:
+                print("未找到验证码")
+
+        # 删除邮件
+        if tab.ele("@id=delete_mail"):
+            tab.actions.click("@id=delete_mail")
+            time.sleep(1)
+
+        if tab.ele("@id=confirm_mail"):
+            tab.actions.click("@id=confirm_mail")
+            print("删除邮件")
+
+    except Exception as e:
+        print(f"发生错误: {str(e)}")
+    finally:
+        browser.quit()
+
+    return code
+
+
+# 测试运行
+if __name__ == "__main__":
+    test_username = "test_user"  # 替换为你要测试的用户名
+    code = get_veri_code(test_username)
+    print(f"获取到的验证码: {code}")