Files
links/patches/puppeteer-api/lib/constants.js
T

153 lines
5.5 KiB
JavaScript
Raw Normal View History

2026-06-20 04:47:34 +08:00
/**
* puppeteer-api 共享常量与 Chrome 启动环境工具
*/
const fs = require('fs');
const path = require('path');
const puppeteer = require('puppeteer-extra');
const DEFAULT_CHROME_EXECUTABLE = '/www/wwwroot/puppeteer-api/.cache/puppeteer/chrome/linux-149.0.7827.22/chrome-linux64/chrome';
const DEFAULT_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
const BASE_LAUNCH_ARGS = [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--disable-gpu',
'--disable-extensions',
'--disable-background-networking',
'--disable-software-rasterizer',
'--no-first-run',
'--no-default-browser-check',
'--disable-breakpad',
'--disable-crash-reporter',
];
const RUNTIME_DIR = path.join(__dirname, '..', '.runtime');
function ensureRuntimeSubdir(name) {
const dir = path.join(RUNTIME_DIR, name);
fs.mkdirSync(dir, { recursive: true, mode: 0o777 });
return dir;
}
function resolveChromeExecutable() {
const candidates = [
process.env.PUPPETEER_EXECUTABLE_PATH,
process.env.CHROME_EXECUTABLE,
DEFAULT_CHROME_EXECUTABLE,
].filter(Boolean);
for (const candidate of candidates) {
if (fs.existsSync(candidate)) {
return candidate;
}
}
try {
const bundled = puppeteer.executablePath();
if (bundled && fs.existsSync(bundled)) {
return bundled;
}
} catch (_) {
/* ignore */
2026-06-20 04:47:34 +08:00
}
return candidates[0] || DEFAULT_CHROME_EXECUTABLE;
}
function buildBrowserLaunchEnv() {
const env = { ...process.env };
delete env.DBUS_SESSION_BUS_ADDRESS;
delete env.DBUS_SYSTEM_BUS_ADDRESS;
const xdgRuntime = ensureRuntimeSubdir('xdg-runtime');
env.XDG_RUNTIME_DIR = xdgRuntime;
env.XDG_CONFIG_HOME = ensureRuntimeSubdir('xdg-config');
env.XDG_CACHE_HOME = ensureRuntimeSubdir('xdg-cache');
env.TMPDIR = ensureRuntimeSubdir('tmp');
return env;
}
function assertChromeExecutable() {
const executablePath = resolveChromeExecutable();
if (!fs.existsSync(executablePath)) {
throw new Error(
`Chrome 可执行文件不存在: ${executablePath}。请在 puppeteer-api 目录执行: npx puppeteer browsers install chrome`
);
}
return executablePath;
}
const MAX_CONCURRENT_BROWSERS = Math.max(1, parseInt(process.env.MAX_CONCURRENT_BROWSERS || '4', 10));
const MAX_CONCURRENT_BROWSERS_REAL = Math.max(1, parseInt(process.env.MAX_CONCURRENT_BROWSERS_REAL || '2', 10));
const QUEUE_TIMEOUT_MS = Math.max(5000, parseInt(process.env.QUEUE_TIMEOUT_MS || '120000', 10));
const API_INTERCEPT_TIMEOUT_MS = Math.max(10000, parseInt(process.env.API_INTERCEPT_TIMEOUT_MS || '60000', 10));
2026-06-20 04:47:34 +08:00
const API_INTERCEPT_TIMEOUT_REAL_MS = Math.max(
API_INTERCEPT_TIMEOUT_MS,
parseInt(process.env.API_INTERCEPT_TIMEOUT_REAL_MS || '90000', 10)
);
const NAVIGATION_TIMEOUT_MS = Math.max(15000, parseInt(process.env.NAVIGATION_TIMEOUT_MS || '60000', 10));
/** rebrowser-puppeteer-core / puppeteer-core 仅支持 load|domcontentloaded|networkidle0|networkidle2,不支持 commit */
const ALLOWED_NAVIGATION_WAIT_UNTIL = ['load', 'domcontentloaded', 'networkidle0', 'networkidle2'];
function resolveNavigationWaitUntil() {
const raw = (process.env.NAVIGATION_WAIT_UNTIL || 'domcontentloaded').trim();
if (ALLOWED_NAVIGATION_WAIT_UNTIL.includes(raw)) {
return raw;
}
if (raw === 'commit') {
console.warn('[constants] NAVIGATION_WAIT_UNTIL=commit 不被当前 Puppeteer 支持,已降级为 domcontentloaded');
return 'domcontentloaded';
}
console.warn(`[constants] 未知 NAVIGATION_WAIT_UNTIL=${raw},已降级为 domcontentloaded`);
return 'domcontentloaded';
}
const NAVIGATION_WAIT_UNTIL = resolveNavigationWaitUntil();
const NAVIGATION_MAX_RETRIES = Math.max(0, parseInt(process.env.NAVIGATION_MAX_RETRIES || '1', 10));
const PAGE_DEFAULT_TIMEOUT_MS = Math.max(15000, parseInt(process.env.PAGE_DEFAULT_TIMEOUT_MS || '30000', 10));
2026-06-20 04:47:34 +08:00
const CAPTCHA_PROVIDER = (process.env.CAPTCHA_PROVIDER || 'capsolver').toLowerCase();
const CAPTCHA_API_KEY = process.env.CAPTCHA_API_KEY || '';
const CAPTCHA_MAX_WAIT_MS = Math.max(30000, parseInt(process.env.CAPTCHA_MAX_WAIT_MS || '120000', 10));
const SESSION_TTL_MS = Math.max(60000, parseInt(process.env.SESSION_TTL_MS || '7200000', 10));
const PERSIST_BROWSER_PROFILE = process.env.PERSIST_BROWSER_PROFILE !== '0';
const PROFILE_MAX_AGE_MS = Math.max(0, parseInt(process.env.PROFILE_MAX_AGE_MS || String(7 * 24 * 3600 * 1000), 10));
const POOL_IDLE_MS = Math.max(60000, parseInt(process.env.POOL_IDLE_MS || '300000', 10));
const MAX_POOLED_BROWSERS = Math.max(0, parseInt(process.env.MAX_POOLED_BROWSERS || '4', 10));
const POOL_ENABLED = process.env.POOL_ENABLED !== '0' && MAX_POOLED_BROWSERS > 0;
2026-06-20 04:47:34 +08:00
module.exports = {
DEFAULT_CHROME_EXECUTABLE,
DEFAULT_UA,
BASE_LAUNCH_ARGS,
RUNTIME_DIR,
ensureRuntimeSubdir,
resolveChromeExecutable,
buildBrowserLaunchEnv,
assertChromeExecutable,
MAX_CONCURRENT_BROWSERS,
MAX_CONCURRENT_BROWSERS_REAL,
QUEUE_TIMEOUT_MS,
API_INTERCEPT_TIMEOUT_MS,
API_INTERCEPT_TIMEOUT_REAL_MS,
NAVIGATION_TIMEOUT_MS,
NAVIGATION_WAIT_UNTIL,
NAVIGATION_MAX_RETRIES,
PAGE_DEFAULT_TIMEOUT_MS,
2026-06-20 04:47:34 +08:00
CAPTCHA_PROVIDER,
CAPTCHA_API_KEY,
CAPTCHA_MAX_WAIT_MS,
SESSION_TTL_MS,
PERSIST_BROWSER_PROFILE,
PROFILE_MAX_AGE_MS,
POOL_IDLE_MS,
MAX_POOLED_BROWSERS,
POOL_ENABLED,
2026-06-20 04:47:34 +08:00
};