修复需鉴权的socks5代理无法连接的问题

This commit is contained in:
foxhui
2025-11-24 00:55:56 +08:00
Unverified
parent da94db9181
commit 3bc03c6bd8
3 changed files with 57 additions and 9 deletions
+41 -9
View File
@@ -2,6 +2,7 @@ import puppeteer from 'puppeteer';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { anonymizeProxy, closeAnonymizedProxy } from 'proxy-chain';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
@@ -285,13 +286,32 @@ async function initBrowser(config) {
}
// 4. 代理配置
let proxyUrlForChrome = null;
if (chromeConfig.proxy && chromeConfig.proxy.enable) {
const { type, host, port } = chromeConfig.proxy;
const proxyUrl = type === 'socks5' ? `socks5://${host}:${port}` : `${host}:${port}`;
args.push(`--proxy-server=${proxyUrl}`);
// 禁用 QUIC (HTTP3) 以确保代理兼容性
args.push('--disable-quic');
console.log(`>>> [Browser] 代理配置: ${type}://${host}:${port}`);
const { type, host, port, user, passwd } = chromeConfig.proxy;
// 特殊处理 SOCKS5 + Auth (Chrome 原生不支持)
if (type === 'socks5' && user && passwd) {
try {
const upstreamUrl = `socks5://${user}:${passwd}@${host}:${port}`;
console.log(`>>> [Browser] 检测到 SOCKS5 认证代理,正在创建本地桥接...`);
// 创建本地中间代理 (无认证 -> 有认证)
proxyUrlForChrome = await anonymizeProxy(upstreamUrl);
console.log(`>>> [Browser] 本地桥接已建立: ${proxyUrlForChrome} -> ${host}:${port}`);
args.push(`--proxy-server=${proxyUrlForChrome}`);
args.push('--disable-quic');
} catch (e) {
console.error('>>> [Error] 代理桥接创建失败:', e);
throw e;
}
} else {
// 常规 HTTP 代理或无认证 SOCKS5
const proxyUrl = type === 'socks5' ? `socks5://${host}:${port}` : `${host}:${port}`;
args.push(`--proxy-server=${proxyUrl}`);
args.push('--disable-quic');
console.log(`>>> [Browser] 代理配置: ${type}://${host}:${port}`);
}
}
const browser = await puppeteer.launch({
@@ -307,13 +327,13 @@ async function initBrowser(config) {
const pages = await browser.pages();
const page = pages[0];
// 5. 代理认证
if (chromeConfig.proxy && chromeConfig.proxy.enable && chromeConfig.proxy.user) {
// 5. 代理认证 (仅当未使用 proxy-chain 桥接时)
if (chromeConfig.proxy && chromeConfig.proxy.enable && chromeConfig.proxy.user && !proxyUrlForChrome) {
await page.authenticate({
username: chromeConfig.proxy.user,
password: chromeConfig.proxy.passwd
});
console.log('>>> [Browser] 代理认证: 已设置');
console.log('>>> [Browser] 代理认证: 已设置 (HTTP Basic Auth)');
}
// 隐藏 WebDriver 特征
@@ -359,6 +379,18 @@ async function initBrowser(config) {
console.log('>>> [Browser] 浏览器初始化完成,系统就绪');
// 注册清理钩子:浏览器关闭时关闭代理服务器
if (proxyUrlForChrome) {
browser.on('disconnected', async () => {
console.log('>>> [Browser] 浏览器断开,正在清理代理桥接...');
try {
await closeAnonymizedProxy(proxyUrlForChrome, true);
} catch (e) {
console.error('>>> [Warn] 代理清理失败:', e.message);
}
});
}
return { browser, page, client, width, height };
}
+1
View File
@@ -8,6 +8,7 @@
"dependencies": {
"got-scraping": "^4.1.2",
"js-yaml": "^4.1.1",
"proxy-chain": "^2.6.0",
"puppeteer": "^24.31.0",
"sharp": "^0.34.5"
}
+15
View File
@@ -14,6 +14,9 @@ importers:
js-yaml:
specifier: ^4.1.1
version: 4.1.1
proxy-chain:
specifier: ^2.6.0
version: 2.6.0
puppeteer:
specifier: ^24.31.0
version: 24.31.0
@@ -610,6 +613,10 @@ packages:
resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==}
engines: {node: '>= 14'}
proxy-chain@2.6.0:
resolution: {integrity: sha512-+NpVKSk68j8sQJG2tBbFuJxMzKTlqeCXXFbqvlyiFhnmxdcYJSv4XZzUSIfwIUwR3D0T8fEJqrA4C7yykU40Pw==}
engines: {node: '>=14'}
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
@@ -1300,6 +1307,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
proxy-chain@2.6.0:
dependencies:
socks: 2.8.7
socks-proxy-agent: 8.0.5
tslib: 2.8.1
transitivePeerDependencies:
- supports-color
proxy-from-env@1.1.0: {}
pump@3.0.3: