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`.
This commit is contained in:
59
browser_utils.py
Normal file
59
browser_utils.py
Normal file
@@ -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,5 +1,5 @@
|
|||||||
[Account]
|
[Account]
|
||||||
email = apxeme@mailto.plus
|
email = dounpuv@mailto.plus
|
||||||
password = ccz14321@
|
password = ccz14321@
|
||||||
first_name = cheng
|
first_name = cheng
|
||||||
last_name = zhen
|
last_name = zhen
|
||||||
@@ -13,6 +13,8 @@ from configparser import ConfigParser
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import logging
|
import logging
|
||||||
|
from browser_utils import BrowserManager
|
||||||
|
from get_veri_code import EmailVerificationHandler
|
||||||
|
|
||||||
# 在文件开头设置日志
|
# 在文件开头设置日志
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
@@ -53,57 +55,6 @@ def load_config():
|
|||||||
raise FileNotFoundError(f"配置文件不存在: {config_path}")
|
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):
|
def handle_turnstile(tab):
|
||||||
"""处理 Turnstile 验证"""
|
"""处理 Turnstile 验证"""
|
||||||
print("准备处理验证")
|
print("准备处理验证")
|
||||||
@@ -193,14 +144,10 @@ def delete_account(browser, tab):
|
|||||||
if tab.ele("Account Settings"):
|
if tab.ele("Account Settings"):
|
||||||
break
|
break
|
||||||
if tab.ele("@data-index=0"):
|
if tab.ele("@data-index=0"):
|
||||||
tab_mail = browser.new_tab(mail_url)
|
code = email_handler.get_verification_code(account)
|
||||||
browser.activate_tab(tab_mail)
|
|
||||||
print("打开邮箱页面")
|
|
||||||
code = get_veri_code(tab_mail)
|
|
||||||
|
|
||||||
if code:
|
if code:
|
||||||
print("获取验证码成功:", code)
|
print("获取验证码成功:", code)
|
||||||
browser.activate_tab(tab)
|
|
||||||
else:
|
else:
|
||||||
print("获取验证码失败,程序退出")
|
print("获取验证码失败,程序退出")
|
||||||
return False
|
return False
|
||||||
@@ -266,10 +213,14 @@ def get_cursor_session_token(tab):
|
|||||||
"""获取cursor session token"""
|
"""获取cursor session token"""
|
||||||
cookies = tab.cookies()
|
cookies = tab.cookies()
|
||||||
cursor_session_token = None
|
cursor_session_token = None
|
||||||
|
time.sleep(3)
|
||||||
|
print(cookies)
|
||||||
for cookie in cookies:
|
for cookie in cookies:
|
||||||
if cookie["name"] == "WorkosCursorSessionToken":
|
if cookie["name"] == "WorkosCursorSessionToken":
|
||||||
cursor_session_token = cookie["value"].split("%3A%3A")[1]
|
cursor_session_token = cookie["value"].split("%3A%3A")[1]
|
||||||
break
|
break
|
||||||
|
if not cursor_session_token:
|
||||||
|
print("未能获取到CursorSessionToken")
|
||||||
return cursor_session_token
|
return cursor_session_token
|
||||||
|
|
||||||
|
|
||||||
@@ -333,14 +284,10 @@ def sign_up_account(browser, tab):
|
|||||||
if tab.ele("Account Settings"):
|
if tab.ele("Account Settings"):
|
||||||
break
|
break
|
||||||
if tab.ele("@data-index=0"):
|
if tab.ele("@data-index=0"):
|
||||||
tab_mail = browser.new_tab(mail_url)
|
code = email_handler.get_verification_code(account)
|
||||||
browser.activate_tab(tab_mail)
|
|
||||||
print("打开邮箱页面")
|
|
||||||
code = get_veri_code(tab_mail)
|
|
||||||
|
|
||||||
if code:
|
if code:
|
||||||
print("获取验证码成功:", code)
|
print("获取验证码成功:", code)
|
||||||
browser.activate_tab(tab)
|
|
||||||
else:
|
else:
|
||||||
print("获取验证码失败,程序退出")
|
print("获取验证码失败,程序退出")
|
||||||
return False
|
return False
|
||||||
@@ -377,49 +324,6 @@ def sign_up_account(browser, tab):
|
|||||||
return True
|
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():
|
def cleanup_temp_files():
|
||||||
"""清理临时文件和缓存"""
|
"""清理临时文件和缓存"""
|
||||||
try:
|
try:
|
||||||
@@ -438,11 +342,18 @@ def cleanup_temp_files():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
browser = None
|
browser_manager = None
|
||||||
try:
|
try:
|
||||||
# 加载配置
|
# 加载配置
|
||||||
config = load_config()
|
config = load_config()
|
||||||
|
|
||||||
|
# 初始化浏览器
|
||||||
|
browser_manager = BrowserManager()
|
||||||
|
browser = browser_manager.init_browser()
|
||||||
|
|
||||||
|
# 初始化<E5A78B><E58C96>箱验证处理器
|
||||||
|
email_handler = EmailVerificationHandler(browser)
|
||||||
|
|
||||||
# 固定的 URL 配置
|
# 固定的 URL 配置
|
||||||
login_url = "https://authenticator.cursor.sh"
|
login_url = "https://authenticator.cursor.sh"
|
||||||
sign_up_url = "https://authenticator.cursor.sh/sign-up"
|
sign_up_url = "https://authenticator.cursor.sh/sign-up"
|
||||||
@@ -457,10 +368,6 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
auto_update_cursor_auth = True
|
auto_update_cursor_auth = True
|
||||||
|
|
||||||
# 浏览器配置
|
|
||||||
co = get_browser_options()
|
|
||||||
|
|
||||||
browser = Chromium(co)
|
|
||||||
tab = browser.latest_tab
|
tab = browser.latest_tab
|
||||||
tab.run_js("try { turnstile.reset() } catch(e) { }")
|
tab.run_js("try { turnstile.reset() } catch(e) { }")
|
||||||
|
|
||||||
@@ -474,29 +381,38 @@ if __name__ == "__main__":
|
|||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
if sign_up_account(browser, tab):
|
if sign_up_account(browser, tab):
|
||||||
token = get_cursor_session_token(tab)
|
token = get_cursor_session_token(tab)
|
||||||
|
if token:
|
||||||
print(f"CursorSessionToken: {token}")
|
print(f"CursorSessionToken: {token}")
|
||||||
print("账户注册成功")
|
print("账户注册成功")
|
||||||
if auto_update_cursor_auth:
|
if auto_update_cursor_auth:
|
||||||
update_cursor_auth(
|
update_cursor_auth(
|
||||||
email=account, access_token=token, refresh_token=token
|
email=account, access_token=token, refresh_token=token
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
print("未能获取到CursorSessionToken")
|
||||||
else:
|
else:
|
||||||
print("账户注册失败")
|
print("账户注册失败")
|
||||||
else:
|
else:
|
||||||
print("账户删除失败")
|
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("脚本执行完毕")
|
print("脚本执行完毕")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"程序执行出错: {str(e)}")
|
logging.error(f"程序执行出错: {str(e)}")
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
print(traceback.format_exc())
|
logging.error(traceback.format_exc())
|
||||||
finally:
|
finally:
|
||||||
# 确保浏览器实例被正确关闭
|
if browser_manager:
|
||||||
if browser:
|
browser_manager.quit()
|
||||||
try:
|
|
||||||
browser.quit()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
input("\n按回车键退出...")
|
input("\n按回车键退出...")
|
||||||
|
|||||||
88
get_veri_code.py
Normal file
88
get_veri_code.py
Normal file
@@ -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("删除邮件")
|
||||||
90
log.txt
90
log.txt
@@ -1,90 +0,0 @@
|
|||||||
[2024/12/26 <20><><EFBFBD><EFBFBD> 13:11:03.37] 开始执行脚<E8A18C><E8849A>?
|
|
||||||
[2024/12/26 <20><><EFBFBD><EFBFBD> 13:17:58.13] 开始执行脚<E8A18C><E8849A>?
|
|
||||||
<EFBFBD><EFBFBD>ʼִ<EFBFBD><EFBFBD>ɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
***<2A><>ȷ<EFBFBD><C8B7><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD>https://tempmail.plus/zh<7A><68><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>cursor<6F>˺ţ<CBBA>***
|
|
||||||
|
|
||||||
<EFBFBD><EFBFBD>ʼɾ<EFBFBD><EFBFBD><EFBFBD>˻<EFBFBD>...
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˺<EFBFBD>
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Continue
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
|
||||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD>ť<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Sign in
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
|
||||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD>ť<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD>
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Adavance
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Delete Account
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>delete
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Delete
|
|
||||||
<EFBFBD>˻<EFBFBD>ɾ<EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>
|
|
||||||
|
|
||||||
<EFBFBD><EFBFBD>ʼע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˻<EFBFBD>...
|
|
||||||
<EFBFBD>Ѵ<EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD>
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD>ᰴť
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
|
||||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD>ť<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Continue<EFBFBD><EFBFBD>ť
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
|
||||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD>ť<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD>
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD> Cursor <no-reply@cursor.sh>
|
|
||||||
07:19
|
|
||||||
Verify your email address
|
|
||||||
<EFBFBD><EFBFBD>֤<EFBFBD>룺 227917
|
|
||||||
ɾ<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD>
|
|
||||||
<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD> 227917
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
|
||||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD>ť<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD>
|
|
||||||
ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
Cursor <20>˺ţ<CBBA> apxeme@mailto.plus
|
|
||||||
<20><><EFBFBD>룺 ccz14321@
|
|
||||||
CursorSessionToken: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSkcwUEZXQUNHSEQ5SDVNU1RWWlFHUDZOIiwidGltZSI6IjE3MzUxOTA0MDEiLCJyYW5kb21uZXNzIjoiYTM4NDBhYzEtZGYwNi00NDhkIiwiZXhwIjo0MzI3MTkwNDAxLCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.YYQ_C4BjbkHlShTFElkOvXFDqA8kYA-aWMqHKLa5RsU
|
|
||||||
<EFBFBD>˻<EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>
|
|
||||||
<EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> cachedEmail
|
|
||||||
<EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> accessToken
|
|
||||||
<EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> refreshToken
|
|
||||||
<EFBFBD>ű<EFBFBD>ִ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
[2024/12/26 <20><><EFBFBD><EFBFBD> 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!
|
|
||||||
<EFBFBD><EFBFBD>ʼִ<EFBFBD><EFBFBD>ɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
***<2A><>ȷ<EFBFBD><C8B7><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD>https://tempmail.plus/zh<7A><68><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>cursor<6F>˺ţ<CBBA>***
|
|
||||||
|
|
||||||
<EFBFBD><EFBFBD>ʼɾ<EFBFBD><EFBFBD><EFBFBD>˻<EFBFBD>...
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˺<EFBFBD>
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Continue
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
|
||||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD>ť<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Sign in
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
|
||||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD>ť<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
|
||||||
126
test/get_veri_code_test.py
Normal file
126
test/get_veri_code_test.py
Normal file
@@ -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}")
|
||||||
Reference in New Issue
Block a user