cursor_auto_register/handle_turnstile_update.py
2025-05-11 23:06:57 +08:00

122 lines
5.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

def handle_turnstile(self, tab=None, max_retries: int = 2, retry_interval: tuple = (1, 2)) -> bool:
"""
处理Turnstile验证
Args:
tab: 浏览器标签对象
max_retries: 最大重试次数
retry_interval: 重试间隔范围(最小值, 最大值)
Returns:
bool: 验证是否成功
Raises:
TurnstileError: 验证过程中的异常
"""
# 如果没有传入tab参数则使用实例的tab属性
tab = tab or self.tab
# 记录开始检测Turnstile验证的日志
logging.info(get_translation("detecting_turnstile"))
# 保存验证开始前的屏幕截图
save_screenshot(tab, "start")
# 初始化重试计数器
retry_count = 0
try:
# 在最大重试次数内循环尝试验证
while retry_count < max_retries:
# 增加重试计数
retry_count += 1
# 记录当前是第几次尝试验证
logging.debug(get_translation("retry_verification", count=retry_count))
try:
# 初始化元素变量
element = None
try:
# 尝试通过层级结构定位到Turnstile验证框的容器元素
element = (
tab.ele(".main-content") # 找到 .main-content 元素
.ele("tag:div") # 找到第一个子 div
.ele("tag:div") # 找到第二个子 div
.ele("tag:div") # 找到第三个子 div
)
except Exception as e:
# 如果无法通过第一种方式找到元素,忽略异常继续执行
pass
if element:
# 如果找到了容器元素,则在其中定位验证框的输入元素
challenge_check = (
element
.shadow_root.ele("tag:iframe") # 找到shadow DOM中的iframe
.ele("tag:body") # 找到iframe中的body
.sr("tag:input") # 找到body中的input元素
)
else:
# 如果没有找到容器元素,则尝试另一种方式定位验证框
challenge_check = (
tab.ele("@id=cf-turnstile", timeout=2) # 通过id直接找到turnstile元素
.child() # 获取其子元素
.shadow_root.ele("tag:iframe") # 找到shadow DOM中的iframe
.ele("tag:body") # 找到iframe中的body
.sr("tag:input") # 找到body中的input元素
)
if challenge_check:
# 如果找到了验证输入元素,记录日志
logging.info(get_translation("detected_turnstile"))
# 点击前随机延迟,模拟人工操作
time.sleep(random.uniform(1, 3))
# 点击验证元素触发验证
challenge_check.click()
# 等待验证处理
time.sleep(2)
# 保存点击验证后的屏幕截图
save_screenshot(tab, "clicked")
# 检查验证是否成功
if check_verification_success(tab):
# 验证成功,记录日志
logging.info(get_translation("turnstile_verification_passed"))
# 保存验证成功的屏幕截图
save_screenshot(tab, "success")
# 返回验证成功
return True
except Exception as e:
# 记录当前尝试失败的详细信息
logging.debug(f"Current attempt unsuccessful: {str(e)}")
# 再次检查验证是否已经成功(可能在异常处理过程中已经通过验证)
if check_verification_success(tab):
# 返回验证成功
return True
# 在下一次尝试前随机延迟
time.sleep(random.uniform(*retry_interval))
# 超过最大重试次数,验证失败
logging.error(get_translation("verification_failed_max_retries", max_retries=max_retries))
# 提供额外的帮助信息,引导用户访问开源项目
logging.error(
"Please visit the open source project for more information: https://github.com/wangffei/wf-cursor-auto-free.git"
)
# 保存验证失败的屏幕截图
save_screenshot(tab, "failed")
# 返回验证失败
return False
except Exception as e:
# 捕获整个验证过程中的异常
# 构建错误信息
error_msg = get_translation("turnstile_exception", error=str(e))
# 记录错误日志
logging.error(error_msg)
# 保存发生错误时的屏幕截图
save_screenshot(tab, "error")
# 抛出TurnstileError异常
raise TurnstileError(error_msg)