优化代理
This commit is contained in:
+49
-30
@@ -16,7 +16,8 @@ class ProxyManager:
|
|||||||
|
|
||||||
def get_proxy(self) -> Optional[str]:
|
def get_proxy(self) -> Optional[str]:
|
||||||
"""
|
"""
|
||||||
从代理API获取代理IP
|
从代理API获取代理IP,支持API返回多个IP(多行格式),
|
||||||
|
逐一验证返回第一个可用的。
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
代理URL,格式: http://ip:port
|
代理URL,格式: http://ip:port
|
||||||
@@ -29,17 +30,29 @@ class ProxyManager:
|
|||||||
text = response.text.strip()
|
text = response.text.strip()
|
||||||
logger.debug(f"代理API响应: {text}")
|
logger.debug(f"代理API响应: {text}")
|
||||||
|
|
||||||
# 解析IP:Port格式
|
proxy_urls, _ = parse_proxy_response(text)
|
||||||
match = re.search(r'(\d+\.\d+\.\d+\.\d+):(\d+)', text)
|
|
||||||
if match:
|
if not proxy_urls:
|
||||||
ip = match.group(1)
|
logger.warning(f"无法解析代理地址: {text}")
|
||||||
port = match.group(2)
|
return None
|
||||||
proxy = f"http://{ip}:{port}"
|
|
||||||
|
if len(proxy_urls) == 1:
|
||||||
|
proxy = proxy_urls[0]
|
||||||
self.current_proxy = proxy
|
self.current_proxy = proxy
|
||||||
logger.info(f"获取到代理: {proxy}")
|
logger.info(f"获取到代理: {proxy}")
|
||||||
return proxy
|
return proxy
|
||||||
|
|
||||||
logger.warning(f"无法解析代理地址: {text}")
|
# 多个代理逐一验证,返回第一个可用的
|
||||||
|
logger.info(f"获取到 {len(proxy_urls)} 个代理,逐一验证")
|
||||||
|
for proxy in proxy_urls:
|
||||||
|
if self.verify_proxy(proxy):
|
||||||
|
self.current_proxy = proxy
|
||||||
|
logger.success(f"可用代理: {proxy}")
|
||||||
|
return proxy
|
||||||
|
logger.warning(f"代理 {proxy} 不可用,尝试下一个")
|
||||||
|
|
||||||
|
logger.warning("所有代理均不可用")
|
||||||
|
self.current_proxy = None
|
||||||
return None
|
return None
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -79,32 +92,35 @@ def get_proxy_manager(api_url: str = "") -> ProxyManager:
|
|||||||
return ProxyManager(api_url)
|
return ProxyManager(api_url)
|
||||||
|
|
||||||
|
|
||||||
def parse_proxy_response(text: str) -> tuple[Optional[str], Optional[str]]:
|
def parse_proxy_response(text: str) -> tuple[list[str], Optional[str]]:
|
||||||
"""
|
"""
|
||||||
解析代理API响应。
|
解析代理API响应,支持返回多个代理地址。
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
(proxy_url, whitelist_ip)
|
(proxy_urls, whitelist_ip)
|
||||||
- proxy_url: 解析到的代理地址(http://ip:port),无法解析时为 None
|
- proxy_urls: 解析到的所有代理地址列表(http://ip:port)
|
||||||
- whitelist_ip: 需要添加到白名单的IP(当API返回白名单错误时),无错误时为 None
|
- whitelist_ip: 需要添加到白名单的IP(当API返回白名单错误时),无错误时为 None
|
||||||
"""
|
"""
|
||||||
text = text.strip()
|
text = text.strip()
|
||||||
|
|
||||||
# 正常代理地址
|
# 白名单错误优先检测
|
||||||
match = re.search(r'(\d+\.\d+\.\d+\.\d+):(\d+)', text)
|
|
||||||
if match:
|
|
||||||
ip, port = match.group(1), match.group(2)
|
|
||||||
# 排除 "请先添加白名单:1.2.3.4" 中误匹配到 ip:port 的情况
|
|
||||||
if '白名单' not in text:
|
|
||||||
return f"http://{ip}:{port}", None
|
|
||||||
|
|
||||||
# 白名单错误:DB1.请先添加白名单:39.144.114.76
|
|
||||||
if '添加白名单' in text or '白名单' in text:
|
if '添加白名单' in text or '白名单' in text:
|
||||||
ip_match = re.search(r'(\d+\.\d+\.\d+\.\d+)', text)
|
ip_match = re.search(r'(\d+\.\d+\.\d+\.\d+)', text)
|
||||||
if ip_match:
|
if ip_match:
|
||||||
return None, ip_match.group(1)
|
return [], ip_match.group(1)
|
||||||
|
|
||||||
return None, None
|
# 解析所有 ip:port,支持多行格式
|
||||||
|
matches = re.findall(r'(\d+\.\d+\.\d+\.\d+):(\d+)', text)
|
||||||
|
proxies = []
|
||||||
|
for ip, port in matches:
|
||||||
|
# 排除白名单提示中误匹配的
|
||||||
|
proxy = f"http://{ip}:{port}"
|
||||||
|
proxies.append(proxy)
|
||||||
|
|
||||||
|
if proxies:
|
||||||
|
return proxies, None
|
||||||
|
|
||||||
|
return [], None
|
||||||
|
|
||||||
|
|
||||||
def verify_proxy_url(proxy_url: str, timeout: tuple = (4, 6)) -> tuple[bool, str]:
|
def verify_proxy_url(proxy_url: str, timeout: tuple = (4, 6)) -> tuple[bool, str]:
|
||||||
@@ -157,12 +173,13 @@ def resolve_working_proxy(
|
|||||||
) -> tuple[Optional[str], str]:
|
) -> tuple[Optional[str], str]:
|
||||||
"""
|
"""
|
||||||
从代理API获取可用代理,自动处理白名单同步。
|
从代理API获取可用代理,自动处理白名单同步。
|
||||||
|
支持API返回多个代理IP,逐一验证直到找到可用的。
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
api_url: 代理API地址
|
api_url: 代理API地址
|
||||||
whitelist_uid: 白名单UID(启用白名单时传入)
|
whitelist_uid: 白名单UID(启用白名单时传入)
|
||||||
whitelist_ukey: 白名单UKEY
|
whitelist_ukey: 白名单UKEY
|
||||||
max_attempts: 最大尝试次数(默认3次)
|
max_attempts: 最大获取尝试次数(默认3次)
|
||||||
log_func: 日志回调函数 (level, message)
|
log_func: 日志回调函数 (level, message)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -180,7 +197,7 @@ def resolve_working_proxy(
|
|||||||
for attempt in range(1, max_attempts + 1):
|
for attempt in range(1, max_attempts + 1):
|
||||||
# 重试之间增加退避延迟,避免代理API返回同一个不可用IP
|
# 重试之间增加退避延迟,避免代理API返回同一个不可用IP
|
||||||
if attempt > 1:
|
if attempt > 1:
|
||||||
delay = min(attempt, 3) # 1s, 2s, 3s 上限
|
delay = min(attempt, 3)
|
||||||
log('info', f'等待 {delay}s 后重试...')
|
log('info', f'等待 {delay}s 后重试...')
|
||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
|
|
||||||
@@ -190,16 +207,18 @@ def resolve_working_proxy(
|
|||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
text = response.text.strip()
|
text = response.text.strip()
|
||||||
|
|
||||||
proxy_url, whitelist_ip = parse_proxy_response(text)
|
proxy_urls, whitelist_ip = parse_proxy_response(text)
|
||||||
|
|
||||||
if proxy_url:
|
if proxy_urls:
|
||||||
# 验证代理
|
log('info', f'获取到 {len(proxy_urls)} 个代理,逐一验证')
|
||||||
|
for proxy_url in proxy_urls:
|
||||||
ok, msg = verify_proxy_url(proxy_url)
|
ok, msg = verify_proxy_url(proxy_url)
|
||||||
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'代理 {proxy_url} 不可用: {msg}')
|
||||||
log('warning', f'代理预检 {attempt}/{max_attempts}: {msg}')
|
last_error = f'共 {len(proxy_urls)} 个代理均不可用'
|
||||||
|
log('warning', f'代理预检 {attempt}/{max_attempts}: {last_error}')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# 代理API返回白名单错误
|
# 代理API返回白名单错误
|
||||||
|
|||||||
Reference in New Issue
Block a user