71 lines
1.9 KiB
JavaScript
Executable File
71 lines
1.9 KiB
JavaScript
Executable File
/**
|
||
* Real Browser 启动:puppeteer-real-browser(抗 Cloudflare Turnstile)
|
||
* 注意:不与 puppeteer-extra 混用在同一 Browser 实例
|
||
*/
|
||
const {
|
||
BASE_LAUNCH_ARGS,
|
||
resolveChromeExecutable,
|
||
} = require('./constants');
|
||
|
||
/** @type {boolean|null} */
|
||
let realBrowserModuleChecked = null;
|
||
|
||
/** @type {boolean} */
|
||
let realBrowserAvailable = false;
|
||
|
||
/**
|
||
* 检测 puppeteer-real-browser 是否已安装
|
||
* @returns {boolean}
|
||
*/
|
||
function isRealBrowserAvailable() {
|
||
if (realBrowserModuleChecked !== null) {
|
||
return realBrowserAvailable;
|
||
}
|
||
try {
|
||
require.resolve('puppeteer-real-browser');
|
||
realBrowserAvailable = true;
|
||
} catch (_) {
|
||
realBrowserAvailable = false;
|
||
}
|
||
realBrowserModuleChecked = true;
|
||
return realBrowserAvailable;
|
||
}
|
||
|
||
/**
|
||
* 启动 real profile Browser(headless:false + Xvfb + turnstile 内置点击)
|
||
* @param {string[]} [extraArgs]
|
||
* @returns {Promise<{ browser: import('puppeteer').Browser, page: import('puppeteer').Page }>}
|
||
*/
|
||
async function launchRealBrowser(extraArgs = []) {
|
||
if (!isRealBrowserAvailable()) {
|
||
throw new Error(
|
||
'puppeteer-real-browser 未安装。请在 puppeteer-api 目录执行: npm install [email protected]'
|
||
);
|
||
}
|
||
|
||
const { connect } = require('puppeteer-real-browser');
|
||
const chromePath = resolveChromeExecutable();
|
||
|
||
const result = await connect({
|
||
headless: false,
|
||
turnstile: true,
|
||
disableXvfb: false,
|
||
customConfig: { chromePath },
|
||
args: [...BASE_LAUNCH_ARGS, '--mute-audio', ...extraArgs],
|
||
});
|
||
|
||
const browser = result.browser;
|
||
const page = result.page;
|
||
|
||
if (!browser || !page) {
|
||
throw new Error('puppeteer-real-browser connect 未返回 browser/page');
|
||
}
|
||
|
||
return { browser, page };
|
||
}
|
||
|
||
module.exports = {
|
||
isRealBrowserAvailable,
|
||
launchRealBrowser,
|
||
};
|