diff --git a/auto_gpt_team.py b/auto_gpt_team.py index bd56d48..09fb61c 100644 --- a/auto_gpt_team.py +++ b/auto_gpt_team.py @@ -1083,60 +1083,154 @@ def run_payment_flow(page, email, step_callback=None): step_cb("提交订阅...") log_progress("[7] 点击订阅...") time.sleep(1) + + # 多种方式尝试点击订阅按钮(Linux 无头模式下需要更可靠的方式) + subscribe_clicked = False + + # 方式1: 使用 DrissionPage 的 click try: subscribe_btn = page.ele('css:button[type="submit"]', timeout=5) if subscribe_btn: + # 确保按钮可见并滚动到视图 + page.run_js('arguments[0].scrollIntoView({block: "center"})', subscribe_btn) + time.sleep(0.5) subscribe_btn.click() + subscribe_clicked = True + log_progress("[OK] 点击订阅按钮 (方式1)") + except Exception as e: + log_progress(f"[!] 方式1点击失败: {e}") + + # 方式2: 使用 JS 点击 + if not subscribe_clicked: + try: + result = page.run_js(''' + const btn = document.querySelector('button[type="submit"]'); + if (btn) { + btn.scrollIntoView({block: "center"}); + btn.click(); + return "clicked"; + } + return "not found"; + ''') + if result == "clicked": + subscribe_clicked = True + log_progress("[OK] 点击订阅按钮 (方式2-JS)") + else: + log_progress(f"[!] 方式2: {result}") + except Exception as e: + log_progress(f"[!] 方式2点击失败: {e}") + + # 方式3: 使用 JS dispatchEvent 模拟点击 + if not subscribe_clicked: + try: + result = page.run_js(''' + const btn = document.querySelector('button[type="submit"]'); + if (btn) { + const event = new MouseEvent('click', { + bubbles: true, + cancelable: true, + view: window + }); + btn.dispatchEvent(event); + return "dispatched"; + } + return "not found"; + ''') + if result == "dispatched": + subscribe_clicked = True + log_progress("[OK] 点击订阅按钮 (方式3-dispatchEvent)") + except Exception as e: + log_progress(f"[!] 方式3点击失败: {e}") + + # 记录当前 URL 用于调试 + try: + log_progress(f"点击后URL: {page.url}") except: - page.run_js('document.querySelector("button[type=submit]").click()') + pass # ========== 步骤 8: 等待支付成功 ========== step_cb("等待支付处理...") log_status("等待", "等待支付处理(超时90秒)...") - + # 使用轮询方式等待支付成功 - # 注意:需要用 try-except 包裹 page.url 访问,避免页面加载时的异常被误判 payment_success = False start_time = time.time() max_wait = 90 # 最多等待 90 秒 last_log_time = 0 - + last_url = "" + while time.time() - start_time < max_wait: try: current_url = page.url - + + # URL 变化时输出日志 + if current_url != last_url: + log_progress(f"[URL变化] {current_url[:80]}...") + last_url = current_url + # 检查是否支付成功 if 'payments/success' in current_url or 'success-team' in current_url: payment_success = True log_status("成功", "[OK] 支付成功!") break - + # 检查是否有错误页面 if 'error' in current_url.lower() or 'failed' in current_url.lower(): log_status("失败", f"[X] 支付失败: {current_url}") return None - + + # 检查页面上是否有错误提示(Stripe 可能显示错误但不改变 URL) + try: + error_elem = page.ele('css:[class*="error"], [class*="Error"], [role="alert"]', timeout=0.5) + if error_elem and error_elem.text: + error_text = error_elem.text[:100] + if error_text and 'error' in error_text.lower(): + log_progress(f"[!] 页面错误: {error_text}") + except: + pass + except Exception as e: - # 页面加载中可能会抛出异常,这是正常的,继续等待 - pass - + # 页面加载中可能会抛出异常,记录但继续等待 + log_progress(f"[!] 页面访问异常: {str(e)[:50]}") + # 检查停止请求 if _is_shutdown_requested(): log_progress("[!] 检测到停止请求") return {"stopped": True} - + # 每 10 秒输出一次日志 elapsed = int(time.time() - start_time) if elapsed >= last_log_time + 10: log_progress(f"[等待中] 已等待 {elapsed} 秒...") last_log_time = elapsed - + + # 每 30 秒检查一次页面状态 + if elapsed % 30 == 0: + try: + # 检查是否还在支付页 + if 'pay.openai.com' in current_url or 'checkout.stripe.com' in current_url: + log_progress("[!] 仍在支付页,可能卡住了") + # 尝试再次点击提交按钮 + try: + page.run_js('document.querySelector("button[type=submit]")?.click()') + log_progress("[!] 尝试重新点击提交按钮") + except: + pass + except: + pass + time.sleep(2) - + if not payment_success: log_status("超时", "[X] 支付未完成(超时)") try: log_progress(f"最终URL: {page.url}") + # 尝试获取页面截图信息(调试用) + try: + page_title = page.run_js('return document.title') + log_progress(f"页面标题: {page_title}") + except: + pass except: pass return None @@ -1249,25 +1343,34 @@ def browser_pay_with_cookies(reg, email: str, proxy: str = None, headless: bool co.set_argument('--disable-infobars') co.set_argument('--disable-dev-shm-usage') co.set_argument('--no-sandbox') + co.set_argument('--disable-gpu') # Linux 无头模式必需 + co.set_argument('--incognito') # 无痕模式 + co.set_argument('--lang=en-US') # 设置语言为英文(Stripe 页面) co.set_argument(f'--user-agent={fingerprint["user_agent"]}') - + screen = fingerprint.get("screen", {"width": 1920, "height": 1080}) - + if headless: co.set_argument('--headless=new') co.set_argument(f'--window-size={screen["width"]},{screen["height"]}') else: co.set_argument(f'--window-size={screen["width"]},{screen["height"]}') - + if proxy: co.set_argument(f'--proxy-server={proxy}') - + if is_linux: co.set_argument('--disable-software-rasterizer') co.set_argument('--disable-extensions') co.set_argument('--disable-setuid-sandbox') - co.set_argument('--single-process') + # 注意:不使用 --single-process,可能导致 Stripe 页面异常 co.set_argument('--remote-debugging-port=0') + co.set_argument('--disable-background-networking') + co.set_argument('--disable-default-apps') + co.set_argument('--disable-sync') + co.set_argument('--metrics-recording-only') + co.set_argument('--mute-audio') + co.set_argument('--no-zygote') # 替代 single-process,更稳定 chrome_paths = [ '/usr/bin/google-chrome', '/usr/bin/google-chrome-stable', @@ -1278,6 +1381,7 @@ def browser_pay_with_cookies(reg, email: str, proxy: str = None, headless: bool for chrome_path in chrome_paths: if os.path.exists(chrome_path): co.set_browser_path(chrome_path) + log_status("浏览器", f"使用: {chrome_path}") break else: co.auto_port(True) @@ -1321,13 +1425,21 @@ def browser_pay_with_cookies(reg, email: str, proxy: str = None, headless: bool step_cb("跳转到支付页...") log_status("订阅", "跳转到支付页...") page.get(checkout_url) - + try: page.wait.url_change('pay.openai.com', timeout=15) log_progress("[OK] 已跳转到支付页") except: time.sleep(2) - + + # 重新注入指纹(跳转到新域名后需要重新注入) + if RANDOM_FINGERPRINT: + inject_fingerprint(page, fingerprint) + log_progress("[OK] 已重新注入指纹到支付页") + + # 等待页面完全加载 + time.sleep(2) + # 执行支付流程 step_cb("执行 SEPA 支付...") result = run_payment_flow(page, email, step_cb)