/** * 微博登录 - 分步骤执行 * Step 1: 打开登录页,截图二维码 * Step 2: 等待用户扫码 * Step 3: 保存登录后的 Cookie */ const puppeteer = require('puppeteer-core'); const { getLaunchOptions } = require('../config/browser'); const fs = require('fs'); const SCREENSHOT_DIR = '/tmp/weibo_step_login'; const COOKIE_FILE = '/home/ubuntu/weibo_cookies_qr.json'; const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); // 确保目录存在 if (!fs.existsSync(SCREENSHOT_DIR)) { fs.mkdirSync(SCREENSHOT_DIR, { recursive: true }); } async function stepByStepLogin() { console.log('🌐 启动浏览器...'); const browser = await puppeteer.launch({ ...getLaunchOptions(), headless: true, }); const page = await browser.newPage(); await page.setViewport({ width: 1280, height: 900 }); try { // ===== STEP 1: 打开登录页并截图 ===== const loginUrl = 'https://passport.weibo.com/sso/signin?entry=miniblog&source=miniblog&disp=popup&url=https%3A%2F%2Fweibo.com%2Fnewlogin%3Ftabtype%3Dweibo%26gid%3D102803%26openLoginLayer%3D0%26url%3Dhttps%3A%2F%2Fweibo.com%2F&from=weibopro'; console.log('\n📍 Step 1: 打开登录页面...'); await page.goto(loginUrl, { waitUntil: 'networkidle2', timeout: 60000, }); await delay(5000); console.log('✅ 登录页已加载'); // 截图二维码 const qrScreenshot = `${SCREENSHOT_DIR}/qr_step1.png`; await page.screenshot({ path: qrScreenshot, fullPage: false }); console.log(`📸 已截图: ${qrScreenshot}`); // 复制到 web 目录 fs.copyFileSync(qrScreenshot, `/home/ubuntu/nanocode/audiobook-player/static/qr_step1.png`); console.log('📤 已上传: http://129.211.173.87:8899/screenshots/qr_step1.png'); console.log('\n' + '='.repeat(60)); console.log('🛑 请扫码!'); console.log('📱 打开微博 App → 扫一扫'); console.log('🔗 http://129.211.173.87:8899/screenshots/qr_step1.png'); console.log('⏳ 扫码完成后告诉我,我会继续保存 Cookie'); console.log('='.repeat(60) + '\n'); // 保存浏览器实例,等待用户指令 // 我们会保持浏览器打开,但需要等待用户回复 // 测试:等待一段时间检查是否已扫码 let loggedIn = false; let attempts = 0; const maxAttempts = 60; // 最多等待60次,每次2秒 = 120秒 while (!loggedIn && attempts < maxAttempts) { await delay(2000); attempts++; // 检查当前URL const currentUrl = page.url(); // 如果URL变了,不再包含 passport,说明可能登录成功 if (!currentUrl.includes('passport.weibo.com')) { console.log(`\n✅ 检测到页面跳转!URL: ${currentUrl}`); loggedIn = true; break; } // 每10秒提示一次 if (attempts % 5 === 0) { console.log(`⏳ 等待扫码中... (${attempts * 2}秒)`); } } if (loggedIn) { // ===== STEP 3: 保存 Cookie ===== console.log('\n📍 Step 3: 保存登录 Cookie...'); const cookies = await page.cookies(); fs.writeFileSync(COOKIE_FILE, JSON.stringify(cookies, null, 2)); console.log(`💾 Cookie 已保存到: ${COOKIE_FILE}`); console.log(`📊 共 ${cookies.length} 个 Cookie`); // 显示关键 Cookie const keyCookies = cookies.filter(c => ['SUB', 'SUBP', 'ALF', 'SCF', 'SSOLoginState'].includes(c.name) ); console.log('\n🔑 关键 Cookie:'); keyCookies.forEach(c => { console.log(` - ${c.name}: ${c.value.substring(0, 30)}...`); }); // 验证登录状态 await page.goto('https://weibo.com/u/me', { waitUntil: 'networkidle2' }); await delay(3000); const verifyScreenshot = `${SCREENSHOT_DIR}/logged_in.png`; await page.screenshot({ path: verifyScreenshot }); fs.copyFileSync(verifyScreenshot, `/home/ubuntu/nanocode/audiobook-player/static/logged_in.png`); console.log('\n📸 验证截图: http://129.211.173.87:8899/screenshots/logged_in.png'); console.log('\n✅ 全部完成!Cookie 已保存,可以发邮件给你'); } else { console.log('\n⏱️ 等待超时(120秒),可能未扫码'); } } catch (error) { console.error('❌ 错误:', error.message); } finally { await browser.close(); } } stepByStepLogin().catch(console.error);