/** * 微博登录助手 - 步骤1: 获取验证码 */ const puppeteer = require('puppeteer-core'); const { getLaunchOptions } = require('../config/browser'); const fs = require('fs'); const PHONE = process.argv[2] || '18688929976'; const SCREENSHOT_DIR = '/tmp/weibo_login'; // 延迟函数 const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); // 确保截图目录存在 if (!fs.existsSync(SCREENSHOT_DIR)) { fs.mkdirSync(SCREENSHOT_DIR, { recursive: true }); } async function weiboLoginStep1() { console.log('🌐 正在打开微博登录页面...'); const browser = await puppeteer.launch({ ...getLaunchOptions(), headless: true, }); try { const page = await browser.newPage(); await page.setViewport({ width: 1280, height: 900 }); // 打开微博 await page.goto('https://weibo.com', { waitUntil: 'networkidle2', timeout: 60000, }); console.log('✅ 页面加载完成'); await delay(3000); // 保存初始页面截图 await page.screenshot({ path: `${SCREENSHOT_DIR}/01_initial.png` }); console.log('📸 初始页面已截图'); // 检查是否有登录框,如果没有可能需要点击登录按钮 const loginBtn = await page.$('a[href*="login"], .login, [node-type="loginBtn"], .W_btn_g'); if (loginBtn) { const text = await page.evaluate(el => el.textContent, loginBtn); console.log(`🔘 发现登录按钮: "${text?.trim()}",点击中...`); await loginBtn.click(); await delay(3000); await page.screenshot({ path: `${SCREENSHOT_DIR}/02_login_modal.png` }); } // 查找手机号输入框 console.log('📱 查找手机号输入框...'); const phoneSelectors = [ 'input[name="username"]', 'input[name="phone"]', 'input[placeholder*="手机号"]', 'input[placeholder*="邮箱"]', 'input[type="tel"]', 'input[type="text"]', '#loginname', '.W_input', 'input[node-type="username"]', 'input[action-type="text_copy"]', ]; let phoneInput = null; let usedSelector = ''; for (const sel of phoneSelectors) { const inputs = await page.$$(sel); for (const input of inputs) { const type = await page.evaluate(el => el.type, input); const placeholder = await page.evaluate(el => el.placeholder, input); console.log(` 检查: ${sel} (type=${type}, placeholder=${placeholder})`); if (!phoneInput) { phoneInput = input; usedSelector = sel; } } if (phoneInput) break; } if (!phoneInput) { console.log('⚠️ 尝试获取所有输入框...'); const allInputs = await page.$$('input'); console.log(` 找到 ${allInputs.length} 个输入框`); if (allInputs.length > 0) { phoneInput = allInputs[0]; } } if (!phoneInput) { throw new Error('未找到输入框'); } console.log(`✅ 找到输入框: ${usedSelector}`); // 清空并输入手机号 await phoneInput.click({ clickCount: 3 }); // 全选 await phoneInput.type(PHONE, { delay: 50 }); console.log(`✅ 手机号已输入: ${PHONE}`); await page.screenshot({ path: `${SCREENSHOT_DIR}/03_phone_entered.png` }); // 查找"获取验证码"按钮 console.log('🔍 查找"获取验证码"按钮...'); const codeBtnSelectors = [ 'a[action-type="get_code"]', 'a[node-type="btn_code"]', '.W_btn_g', '.get_code', 'a:has-text("获取")', 'a:has-text("验证码")', 'button:has-text("获取")', 'button:has-text("验证码")', ]; let codeBtn = null; for (const sel of codeBtnSelectors) { try { codeBtn = await page.$(sel); if (codeBtn) { const text = await page.evaluate(el => el.textContent, codeBtn); console.log(` 找到按钮: "${text?.trim()}" (${sel})`); break; } } catch (e) {} } // 如果没找到,尝试查找所有按钮/链接 if (!codeBtn) { console.log(' 尝试查找所有按钮...'); const allBtns = await page.$$('a, button'); for (const btn of allBtns) { const text = await page.evaluate(el => el.textContent, btn); if (text && (text.includes('获取') || text.includes('验证码') || text.includes('code'))) { console.log(` 候选: "${text.trim()}"`); if (!codeBtn && text.includes('获取')) { codeBtn = btn; } } } } if (codeBtn) { const btnText = await page.evaluate(el => el.textContent, codeBtn); console.log(`\n🖱️ 点击按钮: "${btnText?.trim()}"`); await codeBtn.click(); console.log('✅ 已点击"获取验证码"'); // 等待几秒钟,让短信发送 await delay(5000); await page.screenshot({ path: `${SCREENSHOT_DIR}/04_code_requested.png` }); // 检查是否有提示信息 const tips = await page.$$eval('.W_layer, .W_tips, .tip, .error, .info', els => els.map(el => el.textContent?.trim()).filter(Boolean) ); if (tips.length > 0) { console.log('\n💬 页面提示:', tips.slice(0, 3)); } } else { console.log('⚠️ 未找到验证码按钮,请查看截图手动确认'); } // 保存当前页面HTML用于分析 const html = await page.content(); fs.writeFileSync(`${SCREENSHOT_DIR}/page.html`, html); console.log('\n' + '='.repeat(60)); console.log('📋 步骤1完成,当前状态:'); console.log(` 手机号: ${PHONE}`); console.log(` 验证码: ⏳ 等待发送...`); console.log('\n📸 截图文件:'); fs.readdirSync(SCREENSHOT_DIR).forEach(f => { console.log(` - ${SCREENSHOT_DIR}/${f}`); }); console.log('\n📱 请检查手机,收到验证码后告诉我'); console.log('格式: 验证码 123456'); console.log('='.repeat(60)); // 保存浏览器状态,等待下一步 await page.screenshot({ path: `${SCREENSHOT_DIR}/05_waiting_code.png` }); // 保持浏览器实例供后续使用(通过文件记录WSEndpoint) const wsEndpoint = browser.wsEndpoint(); fs.writeFileSync(`${SCREENSHOT_DIR}/browser_ws.txt`, wsEndpoint); console.log('\n⏳ 浏览器保持连接,等待下一步...'); // 保持运行 await new Promise(() => {}); } catch (error) { console.error('❌ 操作失败:', error.message); await browser.close(); process.exit(1); } } weiboLoginStep1().catch(console.error);