Files
nanocode/playwright-hotspots/scripts/weibo_login.js
T
Ubuntu 32b43f85bd a
2026-07-03 16:58:28 +08:00

205 lines
6.5 KiB
JavaScript

/**
* 微博登录助手 - 步骤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);