a
This commit is contained in:
221
auto_gpt_team.py
221
auto_gpt_team.py
@@ -380,6 +380,108 @@ def generate_random_birthday():
|
|||||||
day = random.randint(1, max_day)
|
day = random.randint(1, max_day)
|
||||||
return str(year), f"{month:02d}", f"{day:02d}"
|
return str(year), f"{month:02d}", f"{day:02d}"
|
||||||
|
|
||||||
|
|
||||||
|
def _detect_page_language(page) -> str:
|
||||||
|
"""检测页面语言
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: 'zh' 中文, 'en' 英文
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
html = page.html
|
||||||
|
# 检查中文关键词
|
||||||
|
chinese_keywords = ['确认', '继续', '登录', '注册', '验证', '邮箱', '密码', '姓名', '生日']
|
||||||
|
for keyword in chinese_keywords:
|
||||||
|
if keyword in html:
|
||||||
|
return 'zh'
|
||||||
|
return 'en'
|
||||||
|
except Exception:
|
||||||
|
return 'en' # 默认英文
|
||||||
|
|
||||||
|
|
||||||
|
def _input_birthday_precise(page, birth_year: str, birth_month: str, birth_day: str) -> bool:
|
||||||
|
"""精确输入生日 (使用 data-type 选择器定位输入框)
|
||||||
|
|
||||||
|
中文界面: yyyy/mm/dd (年/月/日)
|
||||||
|
英文界面: mm/dd/yyyy (月/日/年)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
page: 浏览器页面对象
|
||||||
|
birth_year: 年份 (如 "2000")
|
||||||
|
birth_month: 月份 (如 "07")
|
||||||
|
birth_day: 日期 (如 "15")
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: 是否成功
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# 使用 data-type 属性精确定位三个输入框
|
||||||
|
year_input = page.ele('css:[data-type="year"]', timeout=5)
|
||||||
|
month_input = page.ele('css:[data-type="month"]', timeout=3)
|
||||||
|
day_input = page.ele('css:[data-type="day"]', timeout=3)
|
||||||
|
|
||||||
|
if not all([year_input, month_input, day_input]):
|
||||||
|
log_progress("⚠ 未找到完整的生日输入框 (data-type),尝试备用方案...")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 检测页面语言
|
||||||
|
lang = _detect_page_language(page)
|
||||||
|
log_progress(f"生日: {birth_year}-{birth_month}-{birth_day} (界面: {lang})")
|
||||||
|
|
||||||
|
# 根据语言决定输入顺序
|
||||||
|
if lang == 'zh':
|
||||||
|
# 中文: 年 -> 月 -> 日
|
||||||
|
input_order = [(year_input, birth_year),
|
||||||
|
(month_input, birth_month),
|
||||||
|
(day_input, birth_day)]
|
||||||
|
else:
|
||||||
|
# 英文: 月 -> 日 -> 年
|
||||||
|
input_order = [(month_input, birth_month),
|
||||||
|
(day_input, birth_day),
|
||||||
|
(year_input, birth_year)]
|
||||||
|
|
||||||
|
# 按顺序输入
|
||||||
|
for input_elem, value in input_order:
|
||||||
|
try:
|
||||||
|
input_elem.click()
|
||||||
|
time.sleep(0.15)
|
||||||
|
input_elem.input(value, clear=True)
|
||||||
|
time.sleep(0.2)
|
||||||
|
except Exception as e:
|
||||||
|
log_progress(f"⚠ 生日字段输入异常: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
log_progress("✓ 生日已输入 (精确模式)")
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
log_progress(f"⚠ 精确生日输入失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _input_birthday_fallback(page, birth_year: str, birth_month: str, birth_day: str):
|
||||||
|
"""备用生日输入方式 (Tab 键切换 + 逐字符输入)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
page: 浏览器页面对象
|
||||||
|
birth_year: 年份
|
||||||
|
birth_month: 月份
|
||||||
|
birth_day: 日期
|
||||||
|
"""
|
||||||
|
log_progress(f"生日: {birth_year}-{birth_month}-{birth_day} (备用模式)")
|
||||||
|
|
||||||
|
# 使用 Tab 键切换到生日字段
|
||||||
|
page.actions.key_down('Tab').key_up('Tab')
|
||||||
|
time.sleep(0.3)
|
||||||
|
|
||||||
|
# 逐字符输入
|
||||||
|
birth_str = birth_year + birth_month + birth_day
|
||||||
|
for digit in birth_str:
|
||||||
|
page.actions.type(digit)
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
log_progress("✓ 生日已输入 (备用模式)")
|
||||||
|
|
||||||
# 地址格式: (街道, 邮编, 城市)
|
# 地址格式: (街道, 邮编, 城市)
|
||||||
SEPA_ADDRESSES = [
|
SEPA_ADDRESSES = [
|
||||||
# 柏林
|
# 柏林
|
||||||
@@ -1249,17 +1351,13 @@ def run_main_process():
|
|||||||
name_input = page.ele('@name=name', timeout=20)
|
name_input = page.ele('@name=name', timeout=20)
|
||||||
name_input.input(real_name)
|
name_input.input(real_name)
|
||||||
log_progress(f"姓名: {real_name}")
|
log_progress(f"姓名: {real_name}")
|
||||||
|
|
||||||
# 使用 Tab 键切换到生日字段
|
|
||||||
page.actions.key_down('Tab').key_up('Tab')
|
|
||||||
|
|
||||||
# 生成随机生日并输入
|
# 生成随机生日
|
||||||
birth_year, birth_month, birth_day = generate_random_birthday()
|
birth_year, birth_month, birth_day = generate_random_birthday()
|
||||||
birth_str = birth_year + birth_month + birth_day
|
|
||||||
log_progress(f"生日: {birth_year}-{birth_month}-{birth_day}")
|
# 优先使用精确输入,失败则使用备用方案
|
||||||
for digit in birth_str:
|
if not _input_birthday_precise(page, birth_year, birth_month, birth_day):
|
||||||
page.actions.type(digit)
|
_input_birthday_fallback(page, birth_year, birth_month, birth_day)
|
||||||
time.sleep(0.1)
|
|
||||||
|
|
||||||
time.sleep(1.5)
|
time.sleep(1.5)
|
||||||
# 点击继续/完成注册(使用 type=submit)
|
# 点击继续/完成注册(使用 type=submit)
|
||||||
@@ -1268,6 +1366,53 @@ def run_main_process():
|
|||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
log_progress(f"当前URL: {page.url}")
|
log_progress(f"当前URL: {page.url}")
|
||||||
|
|
||||||
|
# === 检测提交后是否有错误或需要额外操作 ===
|
||||||
|
submit_success = False
|
||||||
|
for check_attempt in range(10):
|
||||||
|
current_url = page.url
|
||||||
|
|
||||||
|
# 检查是否已跳转出 about-you 页面
|
||||||
|
if 'about-you' not in current_url:
|
||||||
|
log_progress(f"✓ 页面已跳转: {current_url[:50]}...")
|
||||||
|
submit_success = True
|
||||||
|
break
|
||||||
|
|
||||||
|
# 检查是否有错误提示
|
||||||
|
try:
|
||||||
|
error_elem = page.ele('css:[role="alert"], [class*="error"], [class*="Error"]', timeout=1)
|
||||||
|
if error_elem and error_elem.text:
|
||||||
|
log_progress(f"⚠ 发现错误提示: {error_elem.text[:50]}")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 检查是否有未勾选的 checkbox(如服务条款)
|
||||||
|
try:
|
||||||
|
unchecked = page.ele('css:input[type="checkbox"]:not(:checked)', timeout=1)
|
||||||
|
if unchecked:
|
||||||
|
log_progress("发现未勾选的选项,尝试勾选...")
|
||||||
|
unchecked.click()
|
||||||
|
time.sleep(0.5)
|
||||||
|
# 重新点击提交
|
||||||
|
final_reg_btn = page.ele('css:button[type="submit"]', timeout=5)
|
||||||
|
if final_reg_btn:
|
||||||
|
final_reg_btn.click()
|
||||||
|
time.sleep(2)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 检查是否有 CAPTCHA
|
||||||
|
try:
|
||||||
|
captcha = page.ele('css:iframe[src*="captcha"], iframe[src*="recaptcha"], [class*="captcha"]', timeout=1)
|
||||||
|
if captcha:
|
||||||
|
log_progress("⚠ 检测到 CAPTCHA,需要人工处理或等待...")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
if not submit_success:
|
||||||
|
log_progress(f"⚠ 提交后仍在 about-you 页面,当前URL: {page.url}")
|
||||||
|
|
||||||
# =======================================================
|
# =======================================================
|
||||||
# 【关键节点】等待进入主页后再执行 JS 跳转到支付页
|
# 【关键节点】等待进入主页后再执行 JS 跳转到支付页
|
||||||
# =======================================================
|
# =======================================================
|
||||||
@@ -1611,14 +1756,13 @@ def run_single_registration(progress_callback=None, step_callback=None) -> dict:
|
|||||||
name_input = page.ele('@name=name', timeout=20)
|
name_input = page.ele('@name=name', timeout=20)
|
||||||
name_input.input(real_name)
|
name_input.input(real_name)
|
||||||
log_progress(f"姓名: {real_name}")
|
log_progress(f"姓名: {real_name}")
|
||||||
page.actions.key_down('Tab').key_up('Tab')
|
|
||||||
|
|
||||||
|
# 生成随机生日
|
||||||
birth_year, birth_month, birth_day = generate_random_birthday()
|
birth_year, birth_month, birth_day = generate_random_birthday()
|
||||||
birth_str = birth_year + birth_month + birth_day
|
|
||||||
log_progress(f"生日: {birth_year}-{birth_month}-{birth_day}")
|
# 优先使用精确输入,失败则使用备用方案
|
||||||
for digit in birth_str:
|
if not _input_birthday_precise(page, birth_year, birth_month, birth_day):
|
||||||
page.actions.type(digit)
|
_input_birthday_fallback(page, birth_year, birth_month, birth_day)
|
||||||
time.sleep(0.1)
|
|
||||||
|
|
||||||
time.sleep(1.5)
|
time.sleep(1.5)
|
||||||
final_reg_btn = page.ele('css:button[type="submit"]', timeout=20)
|
final_reg_btn = page.ele('css:button[type="submit"]', timeout=20)
|
||||||
@@ -1626,6 +1770,53 @@ def run_single_registration(progress_callback=None, step_callback=None) -> dict:
|
|||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
log_progress(f"当前URL: {page.url}")
|
log_progress(f"当前URL: {page.url}")
|
||||||
|
|
||||||
|
# === 检测提交后是否有错误或需要额外操作 ===
|
||||||
|
submit_success = False
|
||||||
|
for check_attempt in range(10):
|
||||||
|
current_url = page.url
|
||||||
|
|
||||||
|
# 检查是否已跳转出 about-you 页面
|
||||||
|
if 'about-you' not in current_url:
|
||||||
|
log_progress(f"✓ 页面已跳转: {current_url[:50]}...")
|
||||||
|
submit_success = True
|
||||||
|
break
|
||||||
|
|
||||||
|
# 检查是否有错误提示
|
||||||
|
try:
|
||||||
|
error_elem = page.ele('css:[role="alert"], [class*="error"], [class*="Error"]', timeout=1)
|
||||||
|
if error_elem and error_elem.text:
|
||||||
|
log_progress(f"⚠ 发现错误提示: {error_elem.text[:50]}")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 检查是否有未勾选的 checkbox(如服务条款)
|
||||||
|
try:
|
||||||
|
unchecked = page.ele('css:input[type="checkbox"]:not(:checked)', timeout=1)
|
||||||
|
if unchecked:
|
||||||
|
log_progress("发现未勾选的选项,尝试勾选...")
|
||||||
|
unchecked.click()
|
||||||
|
time.sleep(0.5)
|
||||||
|
# 重新点击提交
|
||||||
|
final_reg_btn = page.ele('css:button[type="submit"]', timeout=5)
|
||||||
|
if final_reg_btn:
|
||||||
|
final_reg_btn.click()
|
||||||
|
time.sleep(2)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 检查是否有 CAPTCHA
|
||||||
|
try:
|
||||||
|
captcha = page.ele('css:iframe[src*="captcha"], iframe[src*="recaptcha"], [class*="captcha"]', timeout=1)
|
||||||
|
if captcha:
|
||||||
|
log_progress("⚠ 检测到 CAPTCHA,需要人工处理或等待...")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
if not submit_success:
|
||||||
|
log_progress(f"⚠ 提交后仍在 about-you 页面,当前URL: {page.url}")
|
||||||
|
|
||||||
# 等待进入主页 - 改进检测逻辑
|
# 等待进入主页 - 改进检测逻辑
|
||||||
step_cb("等待进入主页...")
|
step_cb("等待进入主页...")
|
||||||
log_status("订阅", "等待进入 ChatGPT 主页...")
|
log_status("订阅", "等待进入 ChatGPT 主页...")
|
||||||
|
|||||||
Reference in New Issue
Block a user