11
This commit is contained in:
121
scripts/nodejs/publish_browser.js
Normal file
121
scripts/nodejs/publish_browser.js
Normal file
@@ -0,0 +1,121 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* 发布用 Puppeteer 浏览器(按平台/账号隔离 userDataDir)
|
||||
*/
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const os = require("os");
|
||||
|
||||
const {
|
||||
COMMON_BROWSER_ARGS,
|
||||
BROWSER_IGNORE_DEFAULT_ARGS,
|
||||
STEALTH_INIT_SCRIPT,
|
||||
DEFAULT_USER_AGENT,
|
||||
} = require("./douyin_browser_constants.js");
|
||||
|
||||
const browsers = new Map();
|
||||
|
||||
function getRuntimeDataPath(...parts) {
|
||||
const base = process.env.AICLIENT_DATA_DIR || path.join(os.homedir(), ".aiclient");
|
||||
return path.join(base, ...parts);
|
||||
}
|
||||
|
||||
function getChromiumExecutablePath() {
|
||||
const fromEnv =
|
||||
process.env.AICLIENT_CHROMIUM_PATH || process.env.PUPPETEER_EXECUTABLE_PATH;
|
||||
if (fromEnv && fs.existsSync(fromEnv)) return fromEnv;
|
||||
const candidates = [];
|
||||
if (process.platform === "win32") {
|
||||
const pf = process.env.ProgramFiles || "C:\\Program Files";
|
||||
const local = process.env.LOCALAPPDATA || "";
|
||||
candidates.push(
|
||||
path.join(pf, "Google", "Chrome", "Application", "chrome.exe"),
|
||||
path.join(local, "Google", "Chrome", "Application", "chrome.exe"),
|
||||
path.join(pf, "Microsoft", "Edge", "Application", "msedge.exe"),
|
||||
);
|
||||
}
|
||||
return candidates.find((p) => p && fs.existsSync(p));
|
||||
}
|
||||
|
||||
function loadPuppeteer() {
|
||||
try {
|
||||
return require("puppeteer-core");
|
||||
} catch {
|
||||
return require("puppeteer");
|
||||
}
|
||||
}
|
||||
|
||||
function contextKey(platform, accountId) {
|
||||
return accountId ? `publish_${platform}_${accountId}` : `publish_${platform}`;
|
||||
}
|
||||
|
||||
function userDataDir(platform, accountId) {
|
||||
const sub = accountId ? `${platform}_${accountId}` : platform;
|
||||
return getRuntimeDataPath("browser-data", "publish", sub);
|
||||
}
|
||||
|
||||
function delay(ms) {
|
||||
return new Promise((r) => setTimeout(r, ms));
|
||||
}
|
||||
|
||||
async function getPublishBrowser(platform, accountId) {
|
||||
const key = contextKey(platform, accountId);
|
||||
const existing = browsers.get(key);
|
||||
if (existing && existing.isConnected()) {
|
||||
return existing;
|
||||
}
|
||||
const puppeteer = loadPuppeteer();
|
||||
const dir = userDataDir(platform, accountId);
|
||||
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
||||
const executablePath = getChromiumExecutablePath();
|
||||
if (!executablePath) {
|
||||
throw new Error(
|
||||
"未找到 Chrome/Edge,请安装浏览器或设置 AICLIENT_CHROMIUM_PATH",
|
||||
);
|
||||
}
|
||||
const browser = await puppeteer.launch({
|
||||
executablePath,
|
||||
headless: false,
|
||||
userDataDir: dir,
|
||||
args: COMMON_BROWSER_ARGS,
|
||||
ignoreDefaultArgs: BROWSER_IGNORE_DEFAULT_ARGS,
|
||||
defaultViewport: { width: 1280, height: 900 },
|
||||
});
|
||||
browser.on("disconnected", () => browsers.delete(key));
|
||||
browsers.set(key, browser);
|
||||
return browser;
|
||||
}
|
||||
|
||||
async function newPublishPage(platform, accountId, cookies) {
|
||||
const browser = await getPublishBrowser(platform, accountId);
|
||||
const page = await browser.newPage();
|
||||
await page.setUserAgent(DEFAULT_USER_AGENT);
|
||||
await page.evaluateOnNewDocument(STEALTH_INIT_SCRIPT);
|
||||
page.setDefaultNavigationTimeout(60000);
|
||||
page.setDefaultTimeout(60000);
|
||||
if (Array.isArray(cookies) && cookies.length) {
|
||||
try {
|
||||
await page.setCookie(...cookies);
|
||||
} catch (e) {
|
||||
console.warn("setCookie 失败:", e.message);
|
||||
}
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
const LOGIN_URLS = {
|
||||
douyin: "https://creator.douyin.com/",
|
||||
kuaishou: "https://cp.kuaishou.com/",
|
||||
shipin: "https://channels.weixin.qq.com/",
|
||||
xiaohongshu: "https://creator.xiaohongshu.com/",
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
delay,
|
||||
getPublishBrowser,
|
||||
newPublishPage,
|
||||
userDataDir,
|
||||
LOGIN_URLS,
|
||||
getChromiumExecutablePath,
|
||||
};
|
||||
Reference in New Issue
Block a user