fix browser verification
This commit is contained in:
+115
-115
@@ -1,115 +1,115 @@
|
||||
import os from 'os';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { execSync } from 'child_process';
|
||||
|
||||
export function detectBrowser(preferredBrowser = 'auto') {
|
||||
const platform = os.platform();
|
||||
let browsers = {
|
||||
'chrome': null,
|
||||
'edge': null
|
||||
};
|
||||
|
||||
if (platform === 'win32') {
|
||||
browsers.chrome = findWindowsBrowser('Chrome');
|
||||
browsers.edge = findWindowsBrowser('Edge');
|
||||
} else if (platform === 'darwin') {
|
||||
browsers.chrome = findMacOSBrowser('Google Chrome');
|
||||
browsers.edge = findMacOSBrowser('Microsoft Edge');
|
||||
} else if (platform === 'linux') {
|
||||
browsers.chrome = findLinuxBrowser('google-chrome');
|
||||
|
||||
//Arch下AUR安装的chrome为google-chrome-stable
|
||||
if(browsers.chrome == null){
|
||||
browsers.chrome = findLinuxBrowser('google-chrome-stable');
|
||||
}
|
||||
|
||||
browsers.edge = findLinuxBrowser('microsoft-edge');
|
||||
}
|
||||
|
||||
if (preferredBrowser === 'auto' || preferredBrowser === undefined) {
|
||||
if (browsers.chrome) {
|
||||
return browsers.chrome;
|
||||
} else if (browsers.edge) {
|
||||
return browsers.edge;
|
||||
}
|
||||
} else if (browsers[preferredBrowser]) {
|
||||
console.log(`使用${preferredBrowser === 'chrome' ? 'Chrome' : 'Edge'}浏览器`);
|
||||
return browsers[preferredBrowser];
|
||||
}
|
||||
|
||||
console.error('未找到Chrome或Edge浏览器,请确保已安装其中之一');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function findWindowsBrowser(browserName) {
|
||||
const regKeys = {
|
||||
'Chrome': ['chrome.exe', 'Google\\Chrome'],
|
||||
'Edge': ['msedge.exe', 'Microsoft\\Edge']
|
||||
};
|
||||
const [exeName, folderName] = regKeys[browserName];
|
||||
|
||||
const regQuery = (key) => {
|
||||
try {
|
||||
return execSync(`reg query "${key}" /ve`).toString().trim().split('\r\n').pop().split(' ').pop();
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
let browserPath = regQuery(`HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\${exeName}`) ||
|
||||
regQuery(`HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\${exeName}`);
|
||||
|
||||
if (browserPath && fs.existsSync(browserPath)) {
|
||||
return browserPath;
|
||||
}
|
||||
|
||||
const commonPaths = [
|
||||
`C:\\Program Files\\${browserName}\\Application\\${exeName}`,
|
||||
`C:\\Program Files (x86)\\${browserName}\\Application\\${exeName}`,
|
||||
`C:\\Program Files (x86)\\Microsoft\\${browserName}\\Application\\${exeName}`,
|
||||
`${process.env.LOCALAPPDATA}\\${browserName}\\Application\\${exeName}`,
|
||||
`${process.env.USERPROFILE}\\AppData\\Local\\${browserName}\\Application\\${exeName}`,
|
||||
];
|
||||
|
||||
const foundPath = commonPaths.find(path => fs.existsSync(path));
|
||||
if (foundPath) {
|
||||
return foundPath;
|
||||
}
|
||||
|
||||
const userAppDataPath = process.env.LOCALAPPDATA || `${process.env.USERPROFILE}\\AppData\\Local`;
|
||||
const appDataPath = path.join(userAppDataPath, folderName, 'Application');
|
||||
|
||||
if (fs.existsSync(appDataPath)) {
|
||||
const files = fs.readdirSync(appDataPath);
|
||||
const exePath = files.find(file => file.toLowerCase() === exeName.toLowerCase());
|
||||
if (exePath) {
|
||||
return path.join(appDataPath, exePath);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function findMacOSBrowser(browserName) {
|
||||
const paths = [
|
||||
`/Applications/${browserName}.app/Contents/MacOS/${browserName}`,
|
||||
`${os.homedir()}/Applications/${browserName}.app/Contents/MacOS/${browserName}`,
|
||||
];
|
||||
|
||||
for (const path of paths) {
|
||||
if (fs.existsSync(path)) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function findLinuxBrowser(browserName) {
|
||||
try {
|
||||
return execSync(`which ${browserName}`).toString().trim();
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
import os from 'os';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import {execSync} from 'child_process';
|
||||
|
||||
export function detectBrowser(preferredBrowser = 'auto') {
|
||||
const platform = os.platform();
|
||||
let browsers = {
|
||||
'chrome': null,
|
||||
'edge': null
|
||||
};
|
||||
|
||||
if (platform === 'win32') {
|
||||
browsers.chrome = findWindowsBrowser('Chrome');
|
||||
browsers.edge = findWindowsBrowser('Edge');
|
||||
} else if (platform === 'darwin') {
|
||||
browsers.chrome = findMacOSBrowser('Google Chrome');
|
||||
browsers.edge = findMacOSBrowser('Microsoft Edge');
|
||||
} else if (platform === 'linux') {
|
||||
browsers.chrome = findLinuxBrowser('google-chrome');
|
||||
|
||||
//Arch下AUR安装的chrome为google-chrome-stable
|
||||
if (browsers.chrome == null) {
|
||||
browsers.chrome = findLinuxBrowser('google-chrome-stable');
|
||||
}
|
||||
|
||||
browsers.edge = findLinuxBrowser('microsoft-edge');
|
||||
}
|
||||
|
||||
if (preferredBrowser === 'auto' || preferredBrowser === undefined) {
|
||||
if (browsers.chrome) {
|
||||
return browsers.chrome;
|
||||
} else if (browsers.edge) {
|
||||
return browsers.edge;
|
||||
}
|
||||
} else if (browsers[preferredBrowser]) {
|
||||
console.log(`使用${preferredBrowser === 'chrome' ? 'Chrome' : 'Edge'}浏览器`);
|
||||
return browsers[preferredBrowser];
|
||||
}
|
||||
|
||||
console.error('未找到Chrome或Edge浏览器,请确保已安装其中之一');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function findWindowsBrowser(browserName) {
|
||||
const regKeys = {
|
||||
'Chrome': ['chrome.exe', 'Google\\Chrome'],
|
||||
'Edge': ['msedge.exe', 'Microsoft\\Edge']
|
||||
};
|
||||
const [exeName, folderName] = regKeys[browserName];
|
||||
|
||||
const regQuery = (key) => {
|
||||
try {
|
||||
return execSync(`reg query "${key}" /ve`).toString().trim().split('\r\n').pop().split(' ').pop();
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
let browserPath = regQuery(`HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\${exeName}`) ||
|
||||
regQuery(`HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\${exeName}`);
|
||||
|
||||
if (browserPath && fs.existsSync(browserPath)) {
|
||||
return browserPath;
|
||||
}
|
||||
|
||||
const commonPaths = [
|
||||
`C:\\Program Files\\${browserName}\\Application\\${exeName}`,
|
||||
`C:\\Program Files (x86)\\${browserName}\\Application\\${exeName}`,
|
||||
`C:\\Program Files (x86)\\Microsoft\\${browserName}\\Application\\${exeName}`,
|
||||
`${process.env.LOCALAPPDATA}\\${browserName}\\Application\\${exeName}`,
|
||||
`${process.env.USERPROFILE}\\AppData\\Local\\${browserName}\\Application\\${exeName}`,
|
||||
];
|
||||
|
||||
const foundPath = commonPaths.find(path => fs.existsSync(path));
|
||||
if (foundPath) {
|
||||
return foundPath;
|
||||
}
|
||||
|
||||
const userAppDataPath = process.env.LOCALAPPDATA || `${process.env.USERPROFILE}\\AppData\\Local`;
|
||||
const appDataPath = path.join(userAppDataPath, folderName, 'Application');
|
||||
|
||||
if (fs.existsSync(appDataPath)) {
|
||||
const files = fs.readdirSync(appDataPath);
|
||||
const exePath = files.find(file => file.toLowerCase() === exeName.toLowerCase());
|
||||
if (exePath) {
|
||||
return path.join(appDataPath, exePath);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function findMacOSBrowser(browserName) {
|
||||
const paths = [
|
||||
`/Applications/${browserName}.app/Contents/MacOS/${browserName}`,
|
||||
`${os.homedir()}/Applications/${browserName}.app/Contents/MacOS/${browserName}`,
|
||||
];
|
||||
|
||||
for (const path of paths) {
|
||||
if (fs.existsSync(path)) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function findLinuxBrowser(browserName) {
|
||||
try {
|
||||
return execSync(`which ${browserName}`).toString().trim();
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
/**
|
||||
* @param {Object} page - Puppeteer
|
||||
* @param {Object} options - 配置选项
|
||||
* @param {number} options.width - 视口宽度
|
||||
* @param {number} options.height - 视口高度
|
||||
* @param {number} options.deviceScaleFactor - 设备缩放因子
|
||||
* @param {boolean} options.isMobile - 模拟移动设备
|
||||
* @param {boolean} options.hasTouch - 支持触摸
|
||||
* @param {boolean} options.isLandscape - 横屏
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function fixBrowserDisplay(page, options = {}) {
|
||||
if (!page) {
|
||||
console.error('页面对象为空,无法修复显示');
|
||||
return;
|
||||
}
|
||||
|
||||
const defaultOptions = {
|
||||
width: 1280,
|
||||
height: 800,
|
||||
deviceScaleFactor: 1,
|
||||
isMobile: false,
|
||||
hasTouch: false,
|
||||
isLandscape: true
|
||||
};
|
||||
|
||||
const settings = {...defaultOptions, ...options};
|
||||
|
||||
try {
|
||||
// 设置视口大小和设备比例
|
||||
await page.setViewport({
|
||||
width: settings.width,
|
||||
height: settings.height,
|
||||
deviceScaleFactor: settings.deviceScaleFactor,
|
||||
isMobile: settings.isMobile,
|
||||
hasTouch: settings.hasTouch,
|
||||
isLandscape: settings.isLandscape
|
||||
});
|
||||
|
||||
// 尝试调整窗口大小
|
||||
const session = await page.target().createCDPSession();
|
||||
await session.send('Emulation.setDeviceMetricsOverride', {
|
||||
width: settings.width,
|
||||
height: settings.height,
|
||||
deviceScaleFactor: settings.deviceScaleFactor,
|
||||
mobile: settings.isMobile,
|
||||
screenWidth: settings.width,
|
||||
screenHeight: settings.height
|
||||
});
|
||||
|
||||
// 重置页面缩放
|
||||
await page.evaluate(() => {
|
||||
document.body.style.zoom = '100%';
|
||||
document.body.style.transform = 'scale(1)';
|
||||
document.body.style.transformOrigin = '0 0';
|
||||
|
||||
// 尝试修复可能存在的CSS
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.textContent = `
|
||||
html, body {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
overflow: auto !important;
|
||||
}
|
||||
|
||||
.container, .main, #app, #root {
|
||||
max-width: 100% !important;
|
||||
width: auto !important;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(styleElement);
|
||||
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('修复浏览器显示时出错:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调整CSS比例
|
||||
* @param {Object} page - Puppeteer
|
||||
* @param {number} scale - 缩放比例
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function adjustCssScaling(page, scale = 1) {
|
||||
if (!page) return;
|
||||
|
||||
try {
|
||||
await page.evaluate((scale) => {
|
||||
const styleElem = document.createElement('style');
|
||||
styleElem.id = 'puppeteer-display-fix';
|
||||
styleElem.textContent = `
|
||||
html {
|
||||
transform: scale(${scale});
|
||||
transform-origin: top left;
|
||||
width: ${100 / scale}% !important;
|
||||
height: ${100 / scale}% !important;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(styleElem);
|
||||
|
||||
// 重新计算布局
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
}, scale);
|
||||
} catch (error) {
|
||||
console.error('调整CSS比例时出错:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修复高DPI
|
||||
* @param {Object} page - Puppeteer
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function fixHighDpiDisplay(page) {
|
||||
if (!page) return;
|
||||
|
||||
try {
|
||||
// 检测设备像素比
|
||||
const devicePixelRatio = await page.evaluate(() => window.devicePixelRatio);
|
||||
|
||||
if (devicePixelRatio > 1) {
|
||||
await page.setViewport({
|
||||
width: 1280,
|
||||
height: 800,
|
||||
deviceScaleFactor: devicePixelRatio
|
||||
});
|
||||
|
||||
await page.evaluate((dpr) => {
|
||||
const meta = document.createElement('meta');
|
||||
meta.setAttribute('name', 'viewport');
|
||||
meta.setAttribute('content', `initial-scale=1, minimum-scale=1, maximum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi, user-scalable=no`);
|
||||
document.head.appendChild(meta);
|
||||
}, devicePixelRatio);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('修复高DPI显示时出错:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 完整浏览器显示优化
|
||||
* @param {Object} page - Puppeteer
|
||||
* @param {Object} options - 配置
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function optimizeBrowserDisplay(page, options = {}) {
|
||||
const defaultOptions = {
|
||||
width: 1280,
|
||||
height: 800,
|
||||
deviceScaleFactor: 1,
|
||||
cssScale: null,
|
||||
fixHighDpi: true,
|
||||
forceResize: true
|
||||
};
|
||||
|
||||
const config = {...defaultOptions, ...options};
|
||||
|
||||
try {
|
||||
// 基本显示修复
|
||||
await fixBrowserDisplay(page, {
|
||||
width: config.width,
|
||||
height: config.height,
|
||||
deviceScaleFactor: config.deviceScaleFactor
|
||||
});
|
||||
|
||||
// 修复高DPI显示
|
||||
if (config.fixHighDpi) {
|
||||
await fixHighDpiDisplay(page);
|
||||
}
|
||||
|
||||
if (config.cssScale !== null) {
|
||||
await adjustCssScaling(page, config.cssScale);
|
||||
}
|
||||
|
||||
// 如果强制调整窗口大小
|
||||
if (config.forceResize && !config.isHeadless) {
|
||||
try {
|
||||
const client = await page.target().createCDPSession();
|
||||
await client.send('Browser.getWindowForTarget');
|
||||
await client.send('Browser.setWindowBounds', {
|
||||
windowId: 1,
|
||||
bounds: {
|
||||
width: config.width,
|
||||
height: config.height
|
||||
}
|
||||
});
|
||||
} catch (resizeError) {
|
||||
// console.log('无法调整窗口大小:', resizeError.message);
|
||||
|
||||
try {
|
||||
await page.evaluate((width, height) => {
|
||||
window.resizeTo(width, height);
|
||||
}, config.width, config.height);
|
||||
} catch (altError) {
|
||||
console.log('失败:', altError.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('浏览器显示优化失败:', error);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,242 @@
|
||||
import * as docx from "docx";
|
||||
import cookie from "cookie";
|
||||
import fs from "fs";
|
||||
import {execSync} from "child_process";
|
||||
|
||||
function getGitRevision() {
|
||||
// get git revision and branch
|
||||
try {
|
||||
const revision = execSync("git rev-parse --short HEAD", {stdio: "pipe"}).toString().trim();
|
||||
const branch = execSync("git rev-parse --abbrev-ref HEAD", {stdio: "pipe"}).toString().trim();
|
||||
return {revision, branch};
|
||||
} catch (e) {
|
||||
return {revision: "unknown", branch: "unknown"};
|
||||
}
|
||||
}
|
||||
|
||||
// 创建目录
|
||||
function createDirectoryIfNotExists(dirPath) {
|
||||
if (!fs.existsSync(dirPath)) {
|
||||
fs.mkdirSync(dirPath, {recursive: true});
|
||||
}
|
||||
}
|
||||
|
||||
function extractCookie(cookies) {
|
||||
let jwtSession = null;
|
||||
let jwtToken = null;
|
||||
let ds = null;
|
||||
let dsr = null;
|
||||
let you_subscription = null;
|
||||
let youpro_subscription = null;
|
||||
|
||||
cookies = cookie.parse(cookies);
|
||||
if (cookies["stytch_session"]) jwtSession = cookies["stytch_session"];
|
||||
if (cookies["stytch_session_jwt"]) jwtToken = cookies["stytch_session_jwt"];
|
||||
if (cookies["DS"]) ds = cookies["DS"];
|
||||
if (cookies["DSR"]) dsr = cookies["DSR"];
|
||||
if (cookies["you_subscription"]) you_subscription = cookies["you_subscription"];
|
||||
if (cookies["youpro_subscription"]) youpro_subscription = cookies["youpro_subscription"];
|
||||
|
||||
return {jwtSession, jwtToken, ds, dsr, you_subscription, youpro_subscription};
|
||||
}
|
||||
|
||||
function getSessionCookie(jwtSession, jwtToken, ds, dsr, you_subscription, youpro_subscription) {
|
||||
let sessionCookie = [];
|
||||
|
||||
// 处理旧版 cookie
|
||||
if (jwtSession && jwtToken) {
|
||||
sessionCookie = [
|
||||
{
|
||||
name: "stytch_session",
|
||||
value: jwtSession,
|
||||
domain: "you.com",
|
||||
path: "/",
|
||||
expires: 1800000000,
|
||||
httpOnly: false,
|
||||
secure: true,
|
||||
sameSite: "Lax",
|
||||
},
|
||||
{
|
||||
name: "ydc_stytch_session",
|
||||
value: jwtSession,
|
||||
domain: "you.com",
|
||||
path: "/",
|
||||
expires: 1800000000,
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "Lax",
|
||||
},
|
||||
{
|
||||
name: "stytch_session_jwt",
|
||||
value: jwtToken,
|
||||
domain: "you.com",
|
||||
path: "/",
|
||||
expires: 1800000000,
|
||||
httpOnly: false,
|
||||
secure: true,
|
||||
sameSite: "Lax",
|
||||
},
|
||||
{
|
||||
name: "ydc_stytch_session_jwt",
|
||||
value: jwtToken,
|
||||
domain: "you.com",
|
||||
path: "/",
|
||||
expires: 1800000000,
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "Lax",
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
// 处理新版 cookie
|
||||
if (ds) {
|
||||
sessionCookie.push({
|
||||
name: "DS",
|
||||
value: ds,
|
||||
domain: "you.com",
|
||||
path: "/",
|
||||
expires: 1800000000,
|
||||
httpOnly: false,
|
||||
secure: true,
|
||||
sameSite: "Lax",
|
||||
});
|
||||
}
|
||||
if (dsr) {
|
||||
sessionCookie.push({
|
||||
name: "DSR",
|
||||
value: dsr,
|
||||
domain: "you.com",
|
||||
path: "/",
|
||||
expires: 1800000000,
|
||||
httpOnly: false,
|
||||
secure: true,
|
||||
sameSite: "Lax",
|
||||
});
|
||||
}
|
||||
|
||||
if (you_subscription) {
|
||||
sessionCookie.push({
|
||||
name: "you_subscription",
|
||||
value: you_subscription,
|
||||
domain: "you.com",
|
||||
path: "/",
|
||||
expires: 1800000000,
|
||||
httpOnly: false,
|
||||
secure: true,
|
||||
sameSite: "Lax",
|
||||
});
|
||||
}
|
||||
|
||||
if (youpro_subscription) {
|
||||
sessionCookie.push({
|
||||
name: "youpro_subscription",
|
||||
value: youpro_subscription,
|
||||
domain: "you.com",
|
||||
path: "/",
|
||||
expires: 1800000000,
|
||||
httpOnly: false,
|
||||
secure: true,
|
||||
sameSite: "Lax",
|
||||
});
|
||||
}
|
||||
|
||||
// 添加隐身模式 cookie(如果启用)
|
||||
if (process.env.INCOGNITO_MODE === "true") {
|
||||
sessionCookie.push({
|
||||
name: "incognito",
|
||||
value: "true",
|
||||
domain: "you.com",
|
||||
path: "/",
|
||||
expires: 1800000000,
|
||||
secure: true,
|
||||
});
|
||||
}
|
||||
return sessionCookie;
|
||||
}
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
function createDocx(content) {
|
||||
let paragraphs = [];
|
||||
content.split("\n").forEach((line) => {
|
||||
paragraphs.push(
|
||||
new docx.Paragraph({
|
||||
children: [new docx.TextRun(line)],
|
||||
})
|
||||
);
|
||||
});
|
||||
let doc = new docx.Document({
|
||||
sections: [
|
||||
{
|
||||
properties: {},
|
||||
children: paragraphs,
|
||||
},
|
||||
],
|
||||
});
|
||||
return docx.Packer.toBuffer(doc).then((buffer) => buffer);
|
||||
}
|
||||
|
||||
// eventStream util
|
||||
function createEvent(event, data) {
|
||||
// if data is object, stringify it
|
||||
if (typeof data === "object") {
|
||||
data = JSON.stringify(data);
|
||||
}
|
||||
return `event: ${event}\ndata: ${data}\n\n`;
|
||||
}
|
||||
|
||||
function extractPerplexityCookie(cookieString) {
|
||||
const cookies = cookie.parse(cookieString);
|
||||
return {
|
||||
sessionToken: cookies['__Secure-next-auth.session-token'],
|
||||
isIncognito: cookies['pplx.is-incognito'] === 'true'
|
||||
};
|
||||
}
|
||||
|
||||
function getPerplexitySessionCookie(extractedCookie) {
|
||||
let sessionCookie = [];
|
||||
|
||||
if (extractedCookie.sessionToken) {
|
||||
sessionCookie.push({
|
||||
name: "__Secure-next-auth.session-token",
|
||||
value: extractedCookie.sessionToken,
|
||||
domain: "www.perplexity.ai",
|
||||
path: "/",
|
||||
expires: 1800000000,
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "Lax",
|
||||
});
|
||||
}
|
||||
|
||||
// 添加无痕模式 cookie (如果启用)
|
||||
if (process.env.INCOGNITO_MODE === "true") {
|
||||
sessionCookie.push({
|
||||
name: "pplx.is-incognito",
|
||||
value: "true",
|
||||
domain: "www.perplexity.ai",
|
||||
path: "/",
|
||||
expires: 1800000000,
|
||||
httpOnly: false,
|
||||
secure: true,
|
||||
sameSite: "Lax",
|
||||
});
|
||||
}
|
||||
|
||||
return sessionCookie;
|
||||
}
|
||||
|
||||
export {
|
||||
createEvent,
|
||||
createDirectoryIfNotExists,
|
||||
sleep,
|
||||
extractCookie,
|
||||
getSessionCookie,
|
||||
createDocx,
|
||||
getGitRevision,
|
||||
extractPerplexityCookie,
|
||||
getPerplexitySessionCookie
|
||||
};
|
||||
@@ -0,0 +1,153 @@
|
||||
import {exec, execSync} from 'child_process';
|
||||
import {promisify} from 'util';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import os from 'os';
|
||||
import {fileURLToPath} from 'url';
|
||||
import {setupBrowserFingerprint} from './browserFingerprint.mjs';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const execPromise = promisify(exec);
|
||||
|
||||
/**
|
||||
* @param {string} userDataDir - 用户数据目录
|
||||
* @param {string} edgePath - Edge浏览器路径
|
||||
* @param {number} debugPort - 调试端口
|
||||
* @returns {Promise<object>} - browser和page
|
||||
*/
|
||||
export async function launchEdgeBrowser(userDataDir, edgePath, debugPort = 9222) {
|
||||
if (!fs.existsSync(userDataDir)) {
|
||||
fs.mkdirSync(userDataDir, {recursive: true});
|
||||
}
|
||||
|
||||
// 关闭可能的Edge进程
|
||||
try {
|
||||
if (os.platform() === 'win32') {
|
||||
await execPromise('taskkill /f /im msedge.exe').catch(() => {
|
||||
});
|
||||
} else if (os.platform() === 'darwin') {
|
||||
// macOS
|
||||
await execPromise('pkill -f "Microsoft Edge"').catch(() => {
|
||||
});
|
||||
} else {
|
||||
// Linux
|
||||
await execPromise('pkill -f "microsoft-edge"').catch(() => {
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
const remoteDebuggingPort = debugPort;
|
||||
let edgeProcess;
|
||||
|
||||
const args = [
|
||||
`--remote-debugging-port=${remoteDebuggingPort}`,
|
||||
`--user-data-dir="${userDataDir}"`,
|
||||
'--no-first-run',
|
||||
'--no-default-browser-check',
|
||||
'--disable-popup-blocking',
|
||||
'--disable-infobars',
|
||||
'--disable-translate',
|
||||
'--disable-sync',
|
||||
'--window-size=1280,850',
|
||||
'--force-device-scale-factor=1',
|
||||
'about:blank' // 打开空白页
|
||||
];
|
||||
|
||||
try {
|
||||
// 启动Edge浏览器
|
||||
const cmdArgs = args.join(' ');
|
||||
const cmd = `"${edgePath}" ${cmdArgs}`;
|
||||
edgeProcess = exec(cmd);
|
||||
|
||||
console.log(`等待Edge浏览器启动...`);
|
||||
await new Promise(resolve => setTimeout(resolve, 3000));
|
||||
|
||||
const puppeteer = await import('puppeteer-core');
|
||||
|
||||
// 连接到浏览器
|
||||
const browser = await puppeteer.connect({
|
||||
browserURL: `http://127.0.0.1:${remoteDebuggingPort}`,
|
||||
defaultViewport: {width: 1280, height: 850}
|
||||
});
|
||||
|
||||
// 获取第一个页面
|
||||
const pages = await browser.pages();
|
||||
let page = pages[0];
|
||||
if (!page) {
|
||||
page = await browser.newPage();
|
||||
}
|
||||
|
||||
const originalUserAgent = await page.evaluate(() => navigator.userAgent);
|
||||
// console.log(`Edge浏览器原始用户代理: ${originalUserAgent}`);
|
||||
|
||||
// 应用随机指纹
|
||||
const fingerprint = await setupBrowserFingerprint(page, 'edge');
|
||||
|
||||
// 验证指纹是否成功应用
|
||||
const newUserAgent = await page.evaluate(() => navigator.userAgent);
|
||||
// console.log(`Edge浏览器应用指纹后用户代理: ${newUserAgent}`);
|
||||
|
||||
if (!newUserAgent.includes('Edg')) {
|
||||
console.warn(`警告: 浏览器可能不是Edge。`);
|
||||
}
|
||||
|
||||
return {
|
||||
browser,
|
||||
page,
|
||||
process: edgeProcess,
|
||||
fingerprint: fingerprint
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`启动Edge浏览器失败:`, error);
|
||||
|
||||
if (edgeProcess) {
|
||||
try {
|
||||
edgeProcess.kill();
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找Edge浏览器路径
|
||||
* @returns {string|null}
|
||||
*/
|
||||
export function findEdgePath() {
|
||||
const platform = os.platform();
|
||||
|
||||
if (platform === 'win32') {
|
||||
const commonPaths = [
|
||||
`${process.env['ProgramFiles(x86)']}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
||||
`${process.env.ProgramFiles}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
||||
`${process.env.LOCALAPPDATA}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
||||
`C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe`,
|
||||
`C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe`
|
||||
];
|
||||
|
||||
for (const path of commonPaths) {
|
||||
if (fs.existsSync(path)) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
} else if (platform === 'darwin') {
|
||||
const macPath = '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge';
|
||||
if (fs.existsSync(macPath)) {
|
||||
return macPath;
|
||||
}
|
||||
} else {
|
||||
// Linux
|
||||
try {
|
||||
const {stdout} = execSync('which microsoft-edge');
|
||||
if (stdout && stdout.trim()) {
|
||||
return stdout.trim();
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user