diff --git a/browser_utils.py b/browser_utils.py new file mode 100644 index 0000000..6c39c6b --- /dev/null +++ b/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 diff --git a/config.ini b/config.ini index a063651..4f3ac7d 100644 --- a/config.ini +++ b/config.ini @@ -1,5 +1,5 @@ [Account] -email = apxeme@mailto.plus +email = dounpuv@mailto.plus password = ccz14321@ first_name = cheng last_name = zhen \ No newline at end of file diff --git a/cursor_pro_keep_alive.py b/cursor_pro_keep_alive.py index 931a983..8e61565 100644 --- a/cursor_pro_keep_alive.py +++ b/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按回车键退出...") diff --git a/get_veri_code.py b/get_veri_code.py new file mode 100644 index 0000000..9192fc6 --- /dev/null +++ b/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("删除邮件") diff --git a/log.txt b/log.txt deleted file mode 100644 index 856427d..0000000 --- a/log.txt +++ /dev/null @@ -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 -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 - 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 -׼֤ -֤ -֤ťѵȴ֤... diff --git a/test/get_veri_code_test.py b/test/get_veri_code_test.py new file mode 100644 index 0000000..fc152e7 --- /dev/null +++ b/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}")