dasdasd
This commit is contained in:
parent
223c85d01a
commit
d33fc7e53a
@ -30,6 +30,7 @@ class WindsurfRegister {
|
||||
this.page = null;
|
||||
this.currentStep = 0;
|
||||
this.accountData = null;
|
||||
this.sessionData = null; // 会话数据(用于浏览器切换)
|
||||
|
||||
// 初始化 CapSolver(自动解决 Cloudflare Turnstile)
|
||||
this.capsolverKey = process.env.CAPSOLVER_API_KEY || null;
|
||||
@ -185,13 +186,16 @@ class WindsurfRegister {
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化浏览器(使用 puppeteer-real-browser 自动绕过 Cloudflare)
|
||||
* 初始化浏览器
|
||||
* @param {Object} options - 选项
|
||||
* @param {boolean} options.skipExtension - 是否跳过扩展加载(用于支付步骤)
|
||||
*/
|
||||
async initBrowser() {
|
||||
async initBrowser(options = {}) {
|
||||
const puppeteer = require('puppeteer');
|
||||
const path = require('path');
|
||||
|
||||
logger.info(this.siteName, '启动浏览器(集成 CapSolver 扩展)...');
|
||||
const browserType = options.skipExtension ? '干净浏览器(无扩展)' : '浏览器(集成 CapSolver 扩展)';
|
||||
logger.info(this.siteName, `启动${browserType}...`);
|
||||
|
||||
// 随机视口大小
|
||||
const viewports = [
|
||||
@ -211,8 +215,8 @@ class WindsurfRegister {
|
||||
]
|
||||
};
|
||||
|
||||
// 如果配置了 CapSolver,加载扩展
|
||||
if (this.capsolverKey) {
|
||||
// 如果配置了 CapSolver 且 不跳过扩展,加载扩展
|
||||
if (!options.skipExtension && this.capsolverKey) {
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
|
||||
@ -270,6 +274,8 @@ class WindsurfRegister {
|
||||
logger.warn(this.siteName, `⚠️ CapSolver 扩展未找到: ${extensionPath}`);
|
||||
logger.warn(this.siteName, '请检查扩展目录是否存在');
|
||||
}
|
||||
} else if (options.skipExtension) {
|
||||
logger.info(this.siteName, '✓ 跳过扩展加载(避免干扰支付流程)');
|
||||
}
|
||||
|
||||
this.browser = await puppeteer.launch(launchOptions);
|
||||
@ -310,6 +316,91 @@ class WindsurfRegister {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存会话数据(用于浏览器切换)
|
||||
*/
|
||||
async saveSession() {
|
||||
logger.info(this.siteName, ' → 保存会话数据...');
|
||||
|
||||
this.sessionData = {
|
||||
cookies: await this.page.cookies(),
|
||||
localStorage: await this.page.evaluate(() => JSON.stringify(localStorage)),
|
||||
sessionStorage: await this.page.evaluate(() => JSON.stringify(sessionStorage)),
|
||||
url: this.page.url()
|
||||
};
|
||||
|
||||
logger.success(this.siteName, ` → ✓ 会话数据已保存 (${this.sessionData.cookies.length} cookies)`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复会话数据(用于浏览器切换)
|
||||
*/
|
||||
async restoreSession() {
|
||||
if (!this.sessionData) {
|
||||
throw new Error('没有可恢复的会话数据');
|
||||
}
|
||||
|
||||
logger.info(this.siteName, ' → 恢复会话数据...');
|
||||
|
||||
// 1. 先访问域名(必须在同一域名下才能设置 cookies)
|
||||
const url = new URL(this.sessionData.url);
|
||||
await this.page.goto(url.origin, { waitUntil: 'networkidle2', timeout: 30000 });
|
||||
|
||||
// 2. 设置 cookies
|
||||
await this.page.setCookie(...this.sessionData.cookies);
|
||||
logger.info(this.siteName, ` → ✓ 已恢复 ${this.sessionData.cookies.length} 个 cookies`);
|
||||
|
||||
// 3. 访问原始 URL
|
||||
await this.page.goto(this.sessionData.url, { waitUntil: 'networkidle2', timeout: 30000 });
|
||||
|
||||
// 4. 恢复 localStorage 和 sessionStorage
|
||||
await this.page.evaluate((ls, ss) => {
|
||||
// 恢复 localStorage
|
||||
const localData = JSON.parse(ls);
|
||||
for (let key in localData) {
|
||||
localStorage.setItem(key, localData[key]);
|
||||
}
|
||||
|
||||
// 恢复 sessionStorage
|
||||
const sessionData = JSON.parse(ss);
|
||||
for (let key in sessionData) {
|
||||
sessionStorage.setItem(key, sessionData[key]);
|
||||
}
|
||||
}, this.sessionData.localStorage, this.sessionData.sessionStorage);
|
||||
|
||||
// 5. 刷新页面以应用所有存储
|
||||
await this.page.reload({ waitUntil: 'networkidle2', timeout: 30000 });
|
||||
|
||||
logger.success(this.siteName, ' → ✓ 会话数据已恢复,登录状态保持');
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换到干净的浏览器(无扩展)
|
||||
*/
|
||||
async switchBrowser() {
|
||||
logger.info(this.siteName, '');
|
||||
logger.info(this.siteName, '┌─────────────────────────────────────────────────────┐');
|
||||
logger.info(this.siteName, '│ 🔄 切换到干净浏览器(避免扩展干扰支付) │');
|
||||
logger.info(this.siteName, '└─────────────────────────────────────────────────────┘');
|
||||
|
||||
// 1. 保存会话
|
||||
await this.saveSession();
|
||||
|
||||
// 2. 关闭当前浏览器
|
||||
logger.info(this.siteName, ' → 关闭带扩展的浏览器...');
|
||||
await this.browser.close();
|
||||
|
||||
// 3. 启动干净浏览器
|
||||
logger.info(this.siteName, ' → 启动干净浏览器(无扩展)...');
|
||||
await this.initBrowser({ skipExtension: true });
|
||||
|
||||
// 4. 恢复会话
|
||||
await this.restoreSession();
|
||||
|
||||
logger.success(this.siteName, '✓ 浏览器切换完成');
|
||||
logger.info(this.siteName, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* 步骤1: 填写基本信息
|
||||
*/
|
||||
@ -463,7 +554,7 @@ class WindsurfRegister {
|
||||
|
||||
// 点击按钮
|
||||
await Promise.all([
|
||||
this.page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 15000 }).catch(() => {}),
|
||||
this.page.waitForNavigation({ waitUntil: 'load', timeout: 10000 }).catch(() => {}),
|
||||
this.human.humanClick(this.page, 'button:not([disabled])')
|
||||
]);
|
||||
|
||||
@ -474,8 +565,8 @@ class WindsurfRegister {
|
||||
await this.page.keyboard.press('Enter');
|
||||
}
|
||||
|
||||
// 等待页面稳定
|
||||
await this.human.randomDelay(2000, 3000);
|
||||
// 等待页面稳定(优化:减少等待时间)
|
||||
await this.human.randomDelay(500, 1000);
|
||||
|
||||
// ===== Cloudflare Turnstile 验证处理 =====
|
||||
|
||||
@ -531,7 +622,8 @@ class WindsurfRegister {
|
||||
logger.info(this.siteName, ` → 等待验证中... 已用时 ${elapsed/1000}秒`);
|
||||
}
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
// 优化:减少轮询间隔,更快检测到完成状态
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
elapsed = Date.now() - startTime;
|
||||
}
|
||||
|
||||
@ -544,7 +636,7 @@ class WindsurfRegister {
|
||||
// 点击 Continue 进入邮箱验证
|
||||
logger.info(this.siteName, ' → 点击Continue进入邮箱验证...');
|
||||
await Promise.all([
|
||||
this.page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 15000 }).catch(() => {}),
|
||||
this.page.waitForNavigation({ waitUntil: 'load', timeout: 10000 }).catch(() => {}),
|
||||
this.human.humanClick(this.page, 'button:not([disabled])')
|
||||
]);
|
||||
|
||||
@ -1521,14 +1613,20 @@ class WindsurfRegister {
|
||||
|
||||
this.currentStep = 5;
|
||||
logger.success(this.siteName, `步骤 5 完成 (共尝试 ${retryCount + 1} 次)`);
|
||||
|
||||
// 保存会话数据(为步骤6的浏览器切换做准备)
|
||||
await this.saveSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* 步骤6: 填写支付信息
|
||||
* 步骤6: 填写支付信息(在干净浏览器中完成)
|
||||
*/
|
||||
async step6_fillPayment() {
|
||||
logger.info(this.siteName, `[步骤 6/${this.getTotalSteps()}] 填写支付信息`);
|
||||
|
||||
// 切换到干净的浏览器(无扩展,避免干扰 Stripe)
|
||||
await this.switchBrowser();
|
||||
|
||||
try {
|
||||
// 等待页面加载
|
||||
await this.human.readPage(3, 5);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user