/** * Windsurf Register - Windsurf网站注册 * https://windsurf.com/account/register * * 注册流程: * Step 1: 填写基本信息(First Name, Last Name, Email) * Step 2: 设置密码 * Step 3: 邮箱验证 * Step 4: 完善个人信息 * ... 根据实际情况继续添加步骤 */ const AccountDataGenerator = require('../generator'); const HumanBehavior = require('../utils/human-behavior'); const logger = require('../../../shared/logger'); class WindsurfRegister { constructor() { this.siteName = 'Windsurf'; this.siteUrl = 'https://windsurf.com/account/register'; this.dataGen = new AccountDataGenerator(); this.human = new HumanBehavior(); this.browser = null; this.page = null; this.currentStep = 0; this.accountData = null; // 定义所有步骤 this.steps = [ { id: 1, name: '填写基本信息', method: 'step1_fillBasicInfo' }, { id: 2, name: '设置密码', method: 'step2_setPassword' }, { id: 3, name: '邮箱验证', method: 'step3_emailVerification' }, // 根据实际注册流程继续添加 ]; } /** * 获取步骤总数 */ getTotalSteps() { return this.steps.length; } /** * 获取当前步骤信息 */ getCurrentStepInfo() { if (this.currentStep === 0) { return { id: 0, name: '未开始', total: this.getTotalSteps() }; } const step = this.steps[this.currentStep - 1]; return { ...step, current: this.currentStep, total: this.getTotalSteps() }; } /** * 生成账号数据(干运行模式) */ generateData(options = {}) { logger.info(this.siteName, '生成账号数据...'); const account = this.dataGen.generateAccount({ name: options.name, email: options.email, username: options.username, password: options.password, includePhone: false // Windsurf第一步不需要手机号 }); return account; } /** * 初始化浏览器(使用rebrowser-puppeteer,自带反检测) */ async initBrowser() { // rebrowser-puppeteer 已经打好补丁,无需额外配置 const puppeteer = require('puppeteer'); logger.info(this.siteName, '启动浏览器(反检测模式)...'); // 随机视口大小(模拟不同设备) const viewports = [ { width: 1920, height: 1080 }, { width: 1366, height: 768 }, { width: 1536, height: 864 }, { width: 1440, height: 900 } ]; const viewport = viewports[Math.floor(Math.random() * viewports.length)]; this.browser = await puppeteer.launch({ headless: false, // 非无头模式更难被检测 args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-blink-features=AutomationControlled', '--disable-dev-shm-usage', `--window-size=${viewport.width},${viewport.height}` ], ignoreDefaultArgs: ['--enable-automation'] }); this.page = await this.browser.newPage(); // 设置随机视口 await this.page.setViewport(viewport); // 随机用户代理 const userAgents = [ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36' ]; await this.page.setUserAgent( userAgents[Math.floor(Math.random() * userAgents.length)] ); // 设置语言和时区 await this.page.setExtraHTTPHeaders({ 'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7' }); logger.success(this.siteName, `浏览器启动成功 (${viewport.width}x${viewport.height})`); } /** * 关闭浏览器 */ async closeBrowser() { if (this.browser) { await this.browser.close(); logger.info(this.siteName, '浏览器已关闭'); } } /** * 步骤1: 填写基本信息(First Name, Last Name, Email)- 使用人类行为 */ async step1_fillBasicInfo() { logger.info(this.siteName, `[步骤 1/${this.getTotalSteps()}] 填写基本信息`); // 打开注册页面 logger.info(this.siteName, `打开注册页面: ${this.siteUrl}`); await this.page.goto(this.siteUrl, { waitUntil: 'networkidle2', timeout: 30000 }); // 模拟阅读页面(1-3秒) await this.human.readPage(1, 3); // 填写First Name(使用人类行为) logger.info(this.siteName, ' → 填写First Name...'); await this.page.waitForSelector('#firstName', { timeout: 10000 }); await this.human.humanType(this.page, '#firstName', this.accountData.firstName); // 填写Last Name logger.info(this.siteName, ' → 填写Last Name...'); await this.page.waitForSelector('#lastName', { timeout: 10000 }); await this.human.humanType(this.page, '#lastName', this.accountData.lastName); // 填写Email logger.info(this.siteName, ' → 填写Email...'); await this.page.waitForSelector('#email', { timeout: 10000 }); await this.human.humanType(this.page, '#email', this.accountData.email); // 勾选同意条款(如果有) try { const checkbox = await this.page.$('input[type="checkbox"]'); if (checkbox) { logger.info(this.siteName, ' → 勾选同意条款...'); await this.human.humanCheckbox(this.page, 'input[type="checkbox"]'); } } catch (error) { logger.warn(this.siteName, ' → 未找到同意条款checkbox,跳过'); } // 点击Continue按钮(使用人类行为) logger.info(this.siteName, ' → 点击Continue按钮...'); // 尝试查找按钮 let buttonSelector = null; const possibleSelectors = [ 'button:has-text("Continue")', 'button[type="submit"]', 'button.continue-button', 'button[class*="continue"]' ]; for (const selector of possibleSelectors) { try { const button = await this.page.$(selector); if (button) { buttonSelector = selector; break; } } catch (e) { // 继续尝试下一个 } } if (buttonSelector) { await this.human.visualSearch(this.page, buttonSelector); await this.human.humanClick(this.page, buttonSelector); } else { logger.warn(this.siteName, ' → 未找到Continue按钮,尝试按Enter键'); await this.human.randomDelay(500, 1000); await this.page.keyboard.press('Enter'); } // 等待跳转或响应 await this.human.randomDelay(2000, 4000); this.currentStep = 1; logger.success(this.siteName, `步骤 1 完成`); } /** * 步骤2: 设置密码 */ async step2_setPassword() { logger.info(this.siteName, `[步骤 2/${this.getTotalSteps()}] 设置密码`); // 等待密码页面加载 await this.human.readPage(1, 2); // 填写密码 logger.info(this.siteName, ' → 填写密码...'); await this.page.waitForSelector('#password', { timeout: 10000 }); await this.human.humanType(this.page, '#password', this.accountData.password); // 填写确认密码 logger.info(this.siteName, ' → 填写确认密码...'); await this.page.waitForSelector('#passwordConfirmation', { timeout: 10000 }); await this.human.humanType(this.page, '#passwordConfirmation', this.accountData.password); // 查找并点击Continue按钮 logger.info(this.siteName, ' → 点击Continue按钮...'); const possibleSelectors = [ 'button:has-text("Continue")', 'button[type="submit"]', 'button.continue-button', 'button[class*="continue"]' ]; let buttonSelector = null; for (const selector of possibleSelectors) { try { const button = await this.page.$(selector); if (button) { buttonSelector = selector; break; } } catch (e) { // 继续尝试 } } if (buttonSelector) { await this.human.visualSearch(this.page, buttonSelector); await this.human.humanClick(this.page, buttonSelector); } else { logger.warn(this.siteName, ' → 未找到Continue按钮,尝试按Enter键'); await this.human.randomDelay(500, 1000); await this.page.keyboard.press('Enter'); } // 等待跳转或响应 await this.human.randomDelay(2000, 4000); this.currentStep = 2; logger.success(this.siteName, `步骤 2 完成`); } /** * 步骤3: 邮箱验证(待实现) */ async step3_emailVerification() { logger.info(this.siteName, `[步骤 3/${this.getTotalSteps()}] 邮箱验证`); // 邮箱验证逻辑 // ... this.currentStep = 3; logger.warn(this.siteName, '步骤 3 待实现(需要邮箱验证码)'); } /** * 执行注册流程 * @param {Object} options - 选项 * @param {number} options.fromStep - 从第几步开始(默认1) * @param {number} options.toStep - 执行到第几步(默认全部) */ async register(options = {}) { const fromStep = options.fromStep || 1; const toStep = options.toStep || this.getTotalSteps(); try { // 1. 生成数据 this.accountData = this.generateData(options); logger.success(this.siteName, '账号数据生成完成'); logger.info(this.siteName, `First Name: ${this.accountData.firstName}`); logger.info(this.siteName, `Last Name: ${this.accountData.lastName}`); logger.info(this.siteName, `Email: ${this.accountData.email}`); logger.info(this.siteName, `Password: ${this.accountData.password}`); // 2. 初始化浏览器 await this.initBrowser(); // 3. 执行指定范围的步骤 logger.info(this.siteName, `\n开始执行步骤 ${fromStep} 到 ${toStep} (共 ${this.getTotalSteps()} 步)\n`); for (let i = fromStep; i <= toStep && i <= this.getTotalSteps(); i++) { const step = this.steps[i - 1]; if (typeof this[step.method] === 'function') { try { await this[step.method](); } catch (error) { logger.error(this.siteName, `步骤 ${i} 执行失败: ${error.message}`); throw error; } } else { logger.warn(this.siteName, `步骤 ${i} (${step.name}) 未实现`); break; } } const stepInfo = this.getCurrentStepInfo(); logger.success(this.siteName, `\n已完成步骤 ${fromStep} 到 ${this.currentStep}`); if (this.currentStep < this.getTotalSteps()) { logger.info(this.siteName, `剩余步骤需要手动完成或等待后续开发`); } // 不自动关闭浏览器,让用户查看结果 if (!options.keepBrowserOpen) { logger.info(this.siteName, '10秒后关闭浏览器...'); await this.page.waitForTimeout(10000); await this.closeBrowser(); } else { logger.info(this.siteName, '浏览器保持打开状态'); } return { success: true, account: this.accountData, completedSteps: this.currentStep, totalSteps: this.getTotalSteps(), message: `完成 ${this.currentStep}/${this.getTotalSteps()} 步` }; } catch (error) { logger.error(this.siteName, `注册失败: ${error.message}`); // 截图保存错误状态 if (this.page) { try { const screenshotPath = `/tmp/windsurf-error-${Date.now()}.png`; await this.page.screenshot({ path: screenshotPath }); logger.info(this.siteName, `错误截图已保存: ${screenshotPath}`); } catch (e) { // 忽略截图错误 } } await this.closeBrowser(); throw error; } } } module.exports = WindsurfRegister;