init repo
This commit is contained in:
147
explore.mjs
Normal file
147
explore.mjs
Normal file
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* 探索脚本:登录店小秘,截图页面结构
|
||||
*/
|
||||
import { chromium } from 'playwright';
|
||||
import { mkdirSync } from 'fs';
|
||||
|
||||
const SCREENSHOTS_DIR = './screenshots';
|
||||
mkdirSync(SCREENSHOTS_DIR, { recursive: true });
|
||||
|
||||
const browser = await chromium.launch({ headless: false }); // 有头模式方便观察
|
||||
const context = await browser.newContext({
|
||||
viewport: { width: 1920, height: 1080 },
|
||||
locale: 'zh-CN',
|
||||
});
|
||||
const page = await context.newPage();
|
||||
|
||||
try {
|
||||
// 1. 打开登录页
|
||||
console.log('>> 打开店小秘登录页...');
|
||||
await page.goto('https://www.dianxiaomi.com/home.htm', { waitUntil: 'networkidle', timeout: 30000 });
|
||||
await page.screenshot({ path: `${SCREENSHOTS_DIR}/01-homepage.png`, fullPage: true });
|
||||
console.log('>> 截图: 01-homepage.png');
|
||||
|
||||
// 打印页面标题
|
||||
console.log('>> 页面标题:', await page.title());
|
||||
|
||||
// 查找登录表单元素
|
||||
const inputs = await page.$$('input');
|
||||
for (const input of inputs) {
|
||||
const type = await input.getAttribute('type');
|
||||
const name = await input.getAttribute('name');
|
||||
const placeholder = await input.getAttribute('placeholder');
|
||||
const id = await input.getAttribute('id');
|
||||
console.log(` input: type=${type}, name=${name}, id=${id}, placeholder=${placeholder}`);
|
||||
}
|
||||
|
||||
// 查找所有按钮
|
||||
const buttons = await page.$$('button, input[type="submit"], .btn, a.btn');
|
||||
for (const btn of buttons) {
|
||||
const text = await btn.textContent();
|
||||
const tag = await btn.evaluate(el => el.tagName);
|
||||
console.log(` button: tag=${tag}, text="${text.trim().substring(0, 50)}"`);
|
||||
}
|
||||
|
||||
// 2. 尝试登录
|
||||
console.log('\n>> 尝试填写登录信息...');
|
||||
|
||||
// 尝试多种可能的选择器
|
||||
const usernameSelectors = [
|
||||
'input[name="username"]', 'input[name="userName"]', 'input[name="account"]',
|
||||
'input[name="loginName"]', 'input[id="username"]', 'input[id="account"]',
|
||||
'input[placeholder*="账号"]', 'input[placeholder*="用户"]', 'input[placeholder*="手机"]',
|
||||
'input[type="text"]:first-of-type'
|
||||
];
|
||||
|
||||
const passwordSelectors = [
|
||||
'input[name="password"]', 'input[name="pwd"]', 'input[type="password"]',
|
||||
'input[id="password"]', 'input[placeholder*="密码"]'
|
||||
];
|
||||
|
||||
let usernameInput = null;
|
||||
let passwordInput = null;
|
||||
|
||||
for (const sel of usernameSelectors) {
|
||||
usernameInput = await page.$(sel);
|
||||
if (usernameInput) {
|
||||
console.log(` 找到用户名输入框: ${sel}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const sel of passwordSelectors) {
|
||||
passwordInput = await page.$(sel);
|
||||
if (passwordInput) {
|
||||
console.log(` 找到密码输入框: ${sel}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (usernameInput && passwordInput) {
|
||||
await usernameInput.fill('MiLe-kf01');
|
||||
await passwordInput.fill('Vxdas@302');
|
||||
await page.screenshot({ path: `${SCREENSHOTS_DIR}/02-filled-login.png` });
|
||||
console.log('>> 截图: 02-filled-login.png');
|
||||
|
||||
// 查找登录按钮
|
||||
const loginBtnSelectors = [
|
||||
'button:has-text("登录")', 'button:has-text("登 录")', 'input[type="submit"]',
|
||||
'a:has-text("登录")', '.login-btn', '#loginBtn', 'button[type="submit"]'
|
||||
];
|
||||
|
||||
let loginBtn = null;
|
||||
for (const sel of loginBtnSelectors) {
|
||||
loginBtn = await page.$(sel);
|
||||
if (loginBtn) {
|
||||
console.log(` 找到登录按钮: ${sel}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (loginBtn) {
|
||||
await loginBtn.click();
|
||||
console.log('>> 点击登录...');
|
||||
|
||||
// 等待页面跳转或加载
|
||||
await page.waitForTimeout(5000);
|
||||
await page.screenshot({ path: `${SCREENSHOTS_DIR}/03-after-login.png`, fullPage: true });
|
||||
console.log('>> 截图: 03-after-login.png');
|
||||
console.log('>> 登录后URL:', page.url());
|
||||
console.log('>> 登录后标题:', await page.title());
|
||||
|
||||
// 打印页面上的所有导航链接
|
||||
console.log('\n>> 页面导航链接:');
|
||||
const links = await page.$$('a, .menu-item, .nav-item, [class*="menu"], [class*="nav"]');
|
||||
for (const link of links.slice(0, 50)) {
|
||||
const text = (await link.textContent()).trim();
|
||||
const href = await link.getAttribute('href');
|
||||
if (text && text.length < 30) {
|
||||
console.log(` link: "${text}" -> ${href || '(no href)'}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 查找"采购"相关菜单
|
||||
console.log('\n>> 查找采购/仓库相关元素:');
|
||||
const purchaseElements = await page.$$('*:has-text("采购"), *:has-text("仓库"), *:has-text("导出")');
|
||||
for (const el of purchaseElements.slice(0, 20)) {
|
||||
const tag = await el.evaluate(el => el.tagName);
|
||||
const text = (await el.textContent()).trim().substring(0, 60);
|
||||
const className = await el.getAttribute('class');
|
||||
if (tag === 'A' || tag === 'LI' || tag === 'SPAN' || tag === 'DIV') {
|
||||
console.log(` ${tag}.${className}: "${text}"`);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('!! 未找到登录表单,请查看截图 01-homepage.png');
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
console.error('错误:', err.message);
|
||||
await page.screenshot({ path: `${SCREENSHOTS_DIR}/error.png`, fullPage: true });
|
||||
} finally {
|
||||
// 保持浏览器打开 30 秒方便观察
|
||||
console.log('\n>> 浏览器将在 30 秒后关闭...');
|
||||
await page.waitForTimeout(30000);
|
||||
await browser.close();
|
||||
}
|
||||
Reference in New Issue
Block a user