Files
playwright-gitcode/utils/browser.js
2026-07-06 09:34:39 +08:00

99 lines
3.1 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.
/**
* 浏览器管理模块
* 负责:启动浏览器、创建上下文、加载/保存登录状态
*/
const { chromium } = require('playwright');
const fs = require('fs');
const path = require('path');
const config = require('../config');
const logger = require('./logger');
/**
* 启动浏览器实例
* @returns {Promise<import('playwright').Browser>}
*/
async function launchBrowser() {
const headless = config.browser.headless;
logger.info(`启动浏览器... (headless: ${headless})`);
logger.info(' → 调用 chromium.launch()...');
const browser = await chromium.launch({
headless,
});
logger.info('✅ 浏览器启动成功');
return browser;
}
/**
* 创建浏览器上下文
* - 如果 state.json 存在且有效,加载登录状态
* - 否则创建干净的上下文
* @param {import('playwright').Browser} browser
* @returns {Promise<{context: import('playwright').BrowserContext, stateLoaded: boolean}>}
*/
async function createContext(browser) {
let stateLoaded = false;
const statePath = path.resolve(config.statePath);
logger.info('检查 state.json...');
logger.info(` → 路径: ${statePath}`);
if (fs.existsSync(statePath)) {
logger.info(' → state.json 文件存在,开始验证内容...');
try {
const raw = fs.readFileSync(statePath, 'utf-8');
logger.info(` → 文件大小: ${raw.length} 字节`);
const state = JSON.parse(raw);
const hasCookies = Array.isArray(state.cookies) && state.cookies.length > 0;
const hasOrigins = Array.isArray(state.origins) && state.origins.length > 0;
logger.info(` → cookies: ${hasCookies ? state.cookies.length + '条' : '空'}`);
logger.info(` → origins: ${hasOrigins ? state.origins.length + '条' : '空'}`);
if (!hasCookies && !hasOrigins) {
logger.warn(' → state.json 内容无效(空 cookies 和 origins将重新登录');
stateLoaded = false;
} else {
logger.info(' → state.json 有效,将加载登录状态');
stateLoaded = true;
}
} catch (err) {
logger.warn(` → state.json 解析失败: ${err.message},将重新登录`);
stateLoaded = false;
}
} else {
logger.info(' → state.json 不存在,将创建新上下文');
stateLoaded = false;
}
const contextOptions = {
locale: config.browser.locale,
};
if (stateLoaded) {
contextOptions.storageState = statePath;
}
logger.info('正在创建浏览器上下文...');
const context = await browser.newContext(contextOptions);
logger.info(stateLoaded ? '✅ 上下文已创建(已加载登录状态)' : '✅ 上下文已创建(未登录)');
return { context, stateLoaded };
}
/**
* 保存登录状态到 state.json
* @param {import('playwright').BrowserContext} context
*/
async function saveState(context) {
const statePath = path.resolve(config.statePath);
logger.info(' → 正在保存 state.json...');
await context.storageState({ path: statePath });
logger.info(` → state.json 已保存到 ${statePath}`);
}
module.exports = {
launchBrowser,
createContext,
saveState,
};