Files
20260324-42433647/login-save-cookies.mjs
2026-04-25 21:50:03 +08:00

120 lines
4.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 第一步:有头浏览器手动登录,保存 Cookie
* 用法node login-save-cookies.mjs
*
* 运行后会打开浏览器,手动输入验证码并登录,
* 登录成功后脚本自动保存 Cookie 到 cookies.json
*/
import { chromium } from 'playwright';
import { writeFileSync, existsSync } from 'fs';
const COOKIE_FILE = './cookies.json';
const browser = await chromium.launch({
headless: false, // 有头模式让你操作
channel: 'chrome', // 用系统 Chrome
});
const context = await browser.newContext({
viewport: { width: 1920, height: 1080 },
locale: 'zh-CN',
});
const page = await context.newPage();
console.log('>> 打开店小秘登录页...');
console.log('>> 请在浏览器中手动输入验证码并登录');
console.log('>> 登录成功后脚本会自动保存 Cookie\n');
await page.goto('https://www.dianxiaomi.com/home.htm', { waitUntil: 'networkidle', timeout: 30000 });
// 自动填入账号密码
const usernameInput = await page.$('input[name="account"]');
const passwordInput = await page.$('input[type="password"]');
const rememberCheckbox = await page.$('input[name="remeber"]');
if (usernameInput && passwordInput) {
await usernameInput.fill('MiLe-kf01');
await passwordInput.fill('Vxdas@302');
// 勾选"记住我"延长 Cookie 有效期
if (rememberCheckbox) {
await rememberCheckbox.check();
}
console.log('>> 已自动填入账号密码,请手动输入验证码后点击"登录"');
}
// 等待用户手动登录成功 - 检测 URL 变化(离开登录页)
// 店小秘后台通常会跳转到 /saleManage/ 或类似路径
try {
await page.waitForURL(url => {
const u = url.toString();
return !u.includes('/home.htm') && !u.includes('/index.htm') && u.includes('dianxiaomi.com');
}, { timeout: 300000 }); // 等待 5 分钟
console.log('\n>> 登录成功当前URL:', page.url());
// 多等几秒让页面完全加载
await page.waitForTimeout(3000);
// 保存 Cookie
const cookies = await context.cookies();
writeFileSync(COOKIE_FILE, JSON.stringify(cookies, null, 2));
console.log(`>> Cookie 已保存到 ${COOKIE_FILE}(共 ${cookies.length} 条)`);
// 截图后台页面
await page.screenshot({ path: './screenshots/04-dashboard.png', fullPage: true });
console.log('>> 已截图: screenshots/04-dashboard.png');
// 打印页面结构 - 查找导航菜单
console.log('\n>> ===== 后台菜单结构 =====');
// 通常的左侧菜单
const menuItems = await page.$$eval(
'a, .menu-item, [class*="menu"] a, [class*="nav"] a, .sidebar a, li a',
els => els
.map(el => ({ text: el.textContent.trim(), href: el.href, className: el.className }))
.filter(e => e.text && e.text.length < 40 && e.text.length > 0)
.filter((e, i, arr) => arr.findIndex(a => a.text === e.text) === i) // 去重
.slice(0, 80)
);
for (const item of menuItems) {
console.log(` [${item.text}] -> ${item.href}`);
}
// 特别搜索采购、仓库、导出相关
console.log('\n>> ===== 采购/仓库/导出 相关菜单 =====');
const relatedItems = menuItems.filter(i =>
i.text.includes('采购') || i.text.includes('仓库') || i.text.includes('导出') ||
i.text.includes('库存') || i.text.includes('备货')
);
for (const item of relatedItems) {
console.log(` ★ [${item.text}] -> ${item.href}`);
}
// 保持浏览器打开让用户可以继续观察
console.log('\n>> 浏览器将在 60 秒后关闭(你可以在这段时间内浏览后台页面)');
await page.waitForTimeout(60000);
} catch (e) {
if (e.name === 'TimeoutError') {
console.log('\n>> 等待超时5分钟请重新运行脚本');
} else {
console.error('错误:', e.message);
}
// 检查是否已经在后台了(可能 URL 检测没覆盖到)
const currentUrl = page.url();
console.log('>> 当前 URL:', currentUrl);
if (currentUrl.includes('dianxiaomi.com') && !currentUrl.includes('/home.htm')) {
const cookies = await context.cookies();
writeFileSync(COOKIE_FILE, JSON.stringify(cookies, null, 2));
console.log(`>> 看起来已登录Cookie 已保存到 ${COOKIE_FILE}`);
}
await page.waitForTimeout(30000);
}
await browser.close();
console.log('>> 完成');