优化代理和重试逻辑
This commit is contained in:
+26
-11
@@ -111,24 +111,29 @@ def verify_proxy_url(proxy_url: str, timeout: tuple = (4, 6)) -> tuple[bool, str
|
|||||||
"""
|
"""
|
||||||
验证代理是否可用。
|
验证代理是否可用。
|
||||||
|
|
||||||
|
验证优先级:
|
||||||
|
1. 斗鱼主站(最相关,能访问斗鱼才是最终目的)
|
||||||
|
2. myip(快速 IP 验证)
|
||||||
|
3. 百度 IP 查询(备用)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
(是否可用, 消息)
|
(是否可用, 消息)
|
||||||
"""
|
"""
|
||||||
proxies = {'http': proxy_url, 'https': proxy_url}
|
proxies = {'http': proxy_url, 'https': proxy_url}
|
||||||
targets = [
|
targets = [
|
||||||
'https://qifu-api.baidubce.com/ip/local/geo/v1/district',
|
('https://www.douyu.com', '斗鱼主站'),
|
||||||
'https://myip.ipip.net',
|
('https://myip.ipip.net', 'IP验证'),
|
||||||
'https://4.ipw.cn',
|
('https://qifu-api.baidubce.com/ip/local/geo/v1/district', '百度IP查询'),
|
||||||
]
|
]
|
||||||
|
|
||||||
for url in targets:
|
for url, label in targets:
|
||||||
try:
|
try:
|
||||||
response = requests.get(
|
response = requests.get(
|
||||||
url, proxies=proxies, timeout=timeout,
|
url, proxies=proxies, timeout=timeout,
|
||||||
headers={'User-Agent': 'Mozilla/5.0'},
|
headers={'User-Agent': 'Mozilla/5.0'},
|
||||||
)
|
)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
return True, f'代理可用: {url.split("/")[2]}'
|
return True, f'代理可用 → {label}'
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
err_msg = str(e)
|
err_msg = str(e)
|
||||||
if 'Tunnel connection failed' in err_msg or '503' in err_msg:
|
if 'Tunnel connection failed' in err_msg or '503' in err_msg:
|
||||||
@@ -137,7 +142,7 @@ def verify_proxy_url(proxy_url: str, timeout: tuple = (4, 6)) -> tuple[bool, str
|
|||||||
detail = '连接超时'
|
detail = '连接超时'
|
||||||
else:
|
else:
|
||||||
detail = type(e).__name__
|
detail = type(e).__name__
|
||||||
logger.debug(f"代理验证 {url} 失败: {detail}")
|
logger.debug(f"代理验证 {label} 失败: {detail}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
return False, '代理验证失败(所有目标不可达)'
|
return False, '代理验证失败(所有目标不可达)'
|
||||||
@@ -147,7 +152,7 @@ def resolve_working_proxy(
|
|||||||
api_url: str,
|
api_url: str,
|
||||||
whitelist_uid: str = "",
|
whitelist_uid: str = "",
|
||||||
whitelist_ukey: str = "",
|
whitelist_ukey: str = "",
|
||||||
max_attempts: int = 5,
|
max_attempts: int = 3,
|
||||||
log_func=None,
|
log_func=None,
|
||||||
) -> tuple[Optional[str], str]:
|
) -> tuple[Optional[str], str]:
|
||||||
"""
|
"""
|
||||||
@@ -157,7 +162,7 @@ def resolve_working_proxy(
|
|||||||
api_url: 代理API地址
|
api_url: 代理API地址
|
||||||
whitelist_uid: 白名单UID(启用白名单时传入)
|
whitelist_uid: 白名单UID(启用白名单时传入)
|
||||||
whitelist_ukey: 白名单UKEY
|
whitelist_ukey: 白名单UKEY
|
||||||
max_attempts: 最大尝试次数
|
max_attempts: 最大尝试次数(默认3次)
|
||||||
log_func: 日志回调函数 (level, message)
|
log_func: 日志回调函数 (level, message)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -170,8 +175,15 @@ def resolve_working_proxy(
|
|||||||
getattr(logger, level if level in ('info', 'warning', 'error', 'success') else 'info', logger.info)(msg)
|
getattr(logger, level if level in ('info', 'warning', 'error', 'success') else 'info', logger.info)(msg)
|
||||||
|
|
||||||
synced_whitelist = False
|
synced_whitelist = False
|
||||||
|
last_error = ""
|
||||||
|
|
||||||
for attempt in range(1, max_attempts + 1):
|
for attempt in range(1, max_attempts + 1):
|
||||||
|
# 重试之间增加退避延迟,避免代理API返回同一个不可用IP
|
||||||
|
if attempt > 1:
|
||||||
|
delay = min(attempt, 3) # 1s, 2s, 3s 上限
|
||||||
|
log('info', f'等待 {delay}s 后重试...')
|
||||||
|
time.sleep(delay)
|
||||||
|
|
||||||
log('info', f'代理预检 {attempt}/{max_attempts}: 正在获取代理')
|
log('info', f'代理预检 {attempt}/{max_attempts}: 正在获取代理')
|
||||||
try:
|
try:
|
||||||
response = requests.get(api_url, timeout=10)
|
response = requests.get(api_url, timeout=10)
|
||||||
@@ -186,6 +198,7 @@ def resolve_working_proxy(
|
|||||||
if ok:
|
if ok:
|
||||||
log('success', f'代理预检成功: {proxy_url}')
|
log('success', f'代理预检成功: {proxy_url}')
|
||||||
return proxy_url, msg
|
return proxy_url, msg
|
||||||
|
last_error = msg
|
||||||
log('warning', f'代理预检 {attempt}/{max_attempts}: {msg}')
|
log('warning', f'代理预检 {attempt}/{max_attempts}: {msg}')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -203,9 +216,11 @@ def resolve_working_proxy(
|
|||||||
continue
|
continue
|
||||||
return None, f'白名单同步失败: {sync_msg}'
|
return None, f'白名单同步失败: {sync_msg}'
|
||||||
|
|
||||||
log('warning', f'代理预检 {attempt}/{max_attempts}: 代理API响应无法解析: {text[:80]}')
|
last_error = f'代理API响应无法解析'
|
||||||
|
log('warning', f'代理预检 {attempt}/{max_attempts}: {last_error}: {text[:80]}')
|
||||||
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
log('warning', f'代理预检 {attempt}/{max_attempts}: 代理API请求失败: {exc}')
|
last_error = f'代理API请求失败: {exc}'
|
||||||
|
log('warning', f'代理预检 {attempt}/{max_attempts}: {last_error}')
|
||||||
|
|
||||||
return None, f'代理预检失败,已尝试 {max_attempts} 次'
|
return None, f'代理预检失败({max_attempts}次尝试均失败): {last_error}'
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ export default function LoginTasksPage() {
|
|||||||
ws.onclose = () => {
|
ws.onclose = () => {
|
||||||
wsRef.current = null;
|
wsRef.current = null;
|
||||||
setWsConnected(false);
|
setWsConnected(false);
|
||||||
|
setBatchId(null);
|
||||||
};
|
};
|
||||||
ws.onerror = () => {
|
ws.onerror = () => {
|
||||||
setWsConnected(false);
|
setWsConnected(false);
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ export default function ProxyPage() {
|
|||||||
};
|
};
|
||||||
ws.onclose = () => {
|
ws.onclose = () => {
|
||||||
wsRef.current = null;
|
wsRef.current = null;
|
||||||
|
setTesting(false);
|
||||||
|
setTestingWl(false);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -96,13 +98,6 @@ export default function ProxyPage() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// WebSocket 关闭后恢复按钮
|
|
||||||
useEffect(() => {
|
|
||||||
if (!wsRef.current) {
|
|
||||||
setTesting(false);
|
|
||||||
setTestingWl(false);
|
|
||||||
}
|
|
||||||
}, [logs.length === 0]);
|
|
||||||
|
|
||||||
const logColors: Record<string, string> = {
|
const logColors: Record<string, string> = {
|
||||||
error: '#ff4d4f',
|
error: '#ff4d4f',
|
||||||
|
|||||||
Reference in New Issue
Block a user