const { chromium } = require('playwright'); const path = require('path'); const LOGIN_URL = 'https://superstar.geelytravel.com/new-tmc/login'; const STATE_PATH = process.env.STATE_PATH || path.resolve(__dirname, 'state.json'); const USER_AGENT = process.env.USER_AGENT || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'; async function run() { // 1. 启动本地 Chrome 浏览器,并添加排除自动化检测的参数 const browser = await chromium.launch({ headless: false, channel: 'chrome', args: [ '--disable-blink-features=AutomationControlled', '--start-maximized', ], }); // 2. 设置上下文,伪造 User-Agent const context = await browser.newContext({ noViewport: true, userAgent: USER_AGENT, }); const page = await context.newPage(); try { // 3. 访问登录页 await page.goto(LOGIN_URL); // 输入信息:如需自动填写,可通过环境变量 USERNAME / PASSWORD 传入 if (process.env.USERNAME) { await page.getByPlaceholder('用户名').fill(process.env.USERNAME); } if (process.env.PASSWORD) { await page.getByPlaceholder('密码').fill(process.env.PASSWORD); } // 4. 进入暂停状态,此时手动滑动验证码并完成登录 console.log('请在浏览器中手动完成滑块验证,登录进入系统首页后回到终端按 Enter...'); await page.pause(); // 5. 关键:等待页面跳转完成,确保已进入登录后的状态 // 如需按业务页面确认登录成功,可打开下面一行并按实际 URL 片段调整。 // await page.waitForURL('**/report/**', { timeout: 60000 }); // 额外等待 3 秒,确保 Cookie 和 LocalStorage 完整写入内存 await page.waitForTimeout(3000); // 6. 保存状态 await context.storageState({ path: STATE_PATH }); console.log(`登录状态已保存至:${STATE_PATH}`); } finally { await context.close(); await browser.close(); } } run().catch((error) => { console.error(error); process.exitCode = 1; });