This commit is contained in:
dengqichen 2025-11-17 16:10:12 +08:00
parent 1a61f5c917
commit f0c9a0ef1d

View File

@ -47,8 +47,11 @@ class WindsurfRegister {
{ id: 4, name: '跳过问卷', method: 'step4_skipSurvey' },
{ id: 5, name: '选择计划', method: 'step5_selectPlan' },
{ id: 6, name: '填写支付信息', method: 'step6_fillPayment' },
// 根据实际注册流程继续添加
{ id: 7, name: '获取订阅信息', method: 'step7_getSubscriptionInfo' },
];
// 记录注册时间
this.registrationTime = null;
}
/**
@ -274,16 +277,55 @@ class WindsurfRegister {
logger.success(this.siteName, '✓ AdsPower 浏览器连接成功');
logger.info(this.siteName, '✓ 使用真实指纹,可同时绕过 Cloudflare 和 Stripe');
// 提示AdsPower 中需要手动安装 CapSolver 扩展
if (this.capsolverKey) {
logger.info(this.siteName, '');
logger.info(this.siteName, '💡 重要提示:');
logger.info(this.siteName, ' 请在 AdsPower 配置中手动安装 CapSolver 扩展');
logger.info(this.siteName, ' 扩展路径: extensions/capsolver');
logger.info(this.siteName, ' 这样可以自动处理 Cloudflare Turnstile 验证');
logger.info(this.siteName, '');
// 清除所有浏览器数据(类似 Ctrl+Shift+Delete
logger.info(this.siteName, ' → 清除所有浏览器数据Cookies、Cache、Storage等...');
try {
// 使用 Chrome DevTools Protocol 进行深度清理
const client = await this.page.target().createCDPSession();
// 1. 清除浏览器 Cookies
await client.send('Network.clearBrowserCookies');
logger.success(this.siteName, ' → ✓ 已清除所有 Cookies');
// 2. 清除浏览器缓存
await client.send('Network.clearBrowserCache');
logger.success(this.siteName, ' → ✓ 已清除浏览器缓存');
// 3. 清除所有存储数据localStorage, sessionStorage, IndexedDB, WebSQL, Cache Storage, Service Workers
await client.send('Storage.clearDataForOrigin', {
origin: '*',
storageTypes: 'all'
});
logger.success(this.siteName, ' → ✓ 已清除所有存储数据');
// 4. 额外清理:访问目标网站并清除其存储
await this.page.goto('https://windsurf.com', { waitUntil: 'domcontentloaded' });
await this.page.evaluate(() => {
try {
localStorage.clear();
sessionStorage.clear();
} catch (e) {}
});
// 5. 关闭 CDP 会话
await client.detach();
logger.success(this.siteName, ' → ✓ 浏览器数据清除完成(全新状态)');
} catch (e) {
logger.warn(this.siteName, ` → 清除浏览器数据失败: ${e.message}`);
}
// 提示AdsPower 中需要手动安装 CapSolver 扩展
logger.info(this.siteName, '');
logger.info(this.siteName, '💡 提示:');
logger.info(this.siteName, ' AdsPower 指纹浏览器已启动');
if (this.capsolverKey) {
logger.info(this.siteName, ' 请确保已在 AdsPower 配置中安装 CapSolver 扩展');
logger.info(this.siteName, ' 扩展路径: extensions/capsolver');
}
logger.info(this.siteName, '');
logger.info(this.siteName, '等待浏览器完全准备...');
await this.human.randomDelay(2000, 3000);
@ -501,7 +543,7 @@ class WindsurfRegister {
// 如果配置了 CapSolver 扩展,等待扩展自动处理验证
if (this.capsolverKey) {
logger.info(this.siteName, ' → 检测到 Cloudflare Turnstile 验证');
logger.info(this.siteName, ' → CapSolver 扩展将自动处理(预计 10-20 秒...');
logger.info(this.siteName, ' → 等待 CapSolver 扩展处理(请确保已在 AdsPower 中安装扩展...');
const startTime = Date.now();
let elapsed = 0;
@ -1624,8 +1666,23 @@ class WindsurfRegister {
await submitButton.click();
logger.success(this.siteName, ' → ✓ 已点击订阅按钮');
// 等待处理
await this.human.randomDelay(5000, 7000);
// 等待跳转到支付成功页面
logger.info(this.siteName, ' → 等待支付处理...');
try {
await this.page.waitForFunction(
() => window.location.href.includes('/billing/payment-success'),
{ timeout: 60000 }
);
// 记录注册时间(支付成功的时间)
this.registrationTime = new Date();
logger.success(this.siteName, ' → ✓ 支付成功!');
logger.info(this.siteName, ` → 注册时间: ${this.registrationTime.toLocaleString('zh-CN')}`);
await this.human.randomDelay(2000, 3000);
} catch (e) {
logger.warn(this.siteName, ` → 等待支付成功页面超时: ${e.message}`);
}
this.currentStep = 6;
logger.success(this.siteName, `步骤 6 完成`);
@ -1640,6 +1697,151 @@ class WindsurfRegister {
}
}
/**
* 步骤7: 获取订阅信息
*/
async step7_getSubscriptionInfo() {
logger.info(this.siteName, `[步骤 7/${this.getTotalSteps()}] 获取订阅信息`);
try {
// 0. 检查并关闭可能存在的弹窗("要打开 Windsurf 吗?"
logger.info(this.siteName, ' → 检查是否有弹窗需要关闭...');
try {
await this.page.waitForTimeout(2000); // 等待弹窗出现
// 尝试查找并点击"取消"或"打开Windsurf"按钮
const closeDialog = await this.page.evaluate(() => {
// 查找包含"取消"或"打开Windsurf"的按钮
const buttons = Array.from(document.querySelectorAll('button'));
const cancelBtn = buttons.find(btn =>
btn.textContent.includes('取消') ||
btn.textContent.includes('打开Windsurf') ||
btn.textContent.includes('Cancel')
);
if (cancelBtn) {
// 优先点击"取消"按钮
const actualCancelBtn = buttons.find(btn =>
btn.textContent.includes('取消') ||
btn.textContent.includes('Cancel')
);
if (actualCancelBtn) {
actualCancelBtn.click();
return '取消';
} else {
cancelBtn.click();
return '打开Windsurf';
}
}
return null;
});
if (closeDialog) {
logger.success(this.siteName, ` → ✓ 已关闭弹窗(点击了"${closeDialog}"`);
await this.human.randomDelay(1000, 2000);
} else {
logger.info(this.siteName, ' → 未检测到弹窗');
}
} catch (e) {
logger.info(this.siteName, ' → 未检测到弹窗或已自动关闭');
}
// 1. 跳转到订阅使用页面
logger.info(this.siteName, ' → 跳转到订阅使用页面...');
await this.page.goto('https://windsurf.com/subscription/usage', {
waitUntil: 'networkidle2',
timeout: 30000
});
// 等待页面加载
await this.human.randomDelay(3000, 5000);
// 2. 获取配额信息
logger.info(this.siteName, ' → 获取配额信息...');
const quotaInfo = await this.page.evaluate(() => {
// 查找包含配额的 p 标签
const quotaElement = document.querySelector('p.caption1.font-medium.text-sk-black\\/80');
if (!quotaElement) return null;
const spans = quotaElement.querySelectorAll('span.caption3 span');
if (spans.length >= 2) {
const used = spans[0].textContent.trim();
const total = spans[1].textContent.trim().replace('/', '').trim();
return { used, total };
}
return null;
});
if (quotaInfo) {
logger.success(this.siteName, ` → ✓ 配额: ${quotaInfo.used} / ${quotaInfo.total} used`);
} else {
logger.warn(this.siteName, ' → ⚠️ 未找到配额信息');
}
// 3. 获取下次账单日期信息
logger.info(this.siteName, ' → 获取账单周期信息...');
const billingInfo = await this.page.evaluate(() => {
// 查找包含 "Next billing cycle" 的 p 标签
const billingElement = Array.from(document.querySelectorAll('p.caption1'))
.find(p => p.textContent.includes('Next billing cycle'));
if (!billingElement) return null;
// 提取天数
const daysMatch = billingElement.textContent.match(/(\d+)\s+days?/);
const dateMatch = billingElement.textContent.match(/on\s+([A-Za-z]+\s+\d+,\s+\d{4})/);
return {
days: daysMatch ? daysMatch[1] : null,
date: dateMatch ? dateMatch[1] : null,
fullText: billingElement.textContent.trim()
};
});
if (billingInfo && billingInfo.days) {
logger.success(this.siteName, ` → ✓ 下次账单: ${billingInfo.days} 天后 (${billingInfo.date})`);
} else {
logger.warn(this.siteName, ' → ⚠️ 未找到账单周期信息');
}
// 4. 汇总打印所有信息
logger.info(this.siteName, '');
logger.info(this.siteName, '┌─────────────────────────────────────────────────────┐');
logger.info(this.siteName, '│ 订阅信息汇总 │');
logger.info(this.siteName, '└─────────────────────────────────────────────────────┘');
if (this.registrationTime) {
logger.info(this.siteName, `📅 注册时间: ${this.registrationTime.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
})}`);
}
if (quotaInfo) {
logger.info(this.siteName, `📊 使用配额: ${quotaInfo.used} / ${quotaInfo.total}`);
logger.info(this.siteName, `💎 剩余配额: ${quotaInfo.total - parseFloat(quotaInfo.used)}`);
}
if (billingInfo && billingInfo.days) {
logger.info(this.siteName, `🔄 下次账单: ${billingInfo.days} 天后`);
logger.info(this.siteName, `📆 账单日期: ${billingInfo.date}`);
}
logger.info(this.siteName, '');
this.currentStep = 7;
logger.success(this.siteName, `步骤 7 完成`);
} catch (error) {
logger.error(this.siteName, `获取订阅信息失败: ${error.message}`);
throw error;
}
}
/**
* 执行注册流程
* @param {Object} options - 选项