同步更新:重构路由、服务模块,更新前端构建
This commit is contained in:
77
services/proxy.py
Normal file
77
services/proxy.py
Normal file
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import time
|
||||
from typing import Optional
|
||||
|
||||
import requests
|
||||
|
||||
from app_logger import get_logger
|
||||
|
||||
logger = get_logger("proxy")
|
||||
|
||||
|
||||
def validate_ip_port(ip_port_str: str) -> bool:
|
||||
"""验证IP:PORT格式是否有效(含范围校验)。"""
|
||||
pattern = re.compile(r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}):(\d{1,5})$")
|
||||
match = pattern.match(ip_port_str or "")
|
||||
if not match:
|
||||
return False
|
||||
|
||||
for i in range(1, 5):
|
||||
octet = int(match.group(i))
|
||||
if octet < 0 or octet > 255:
|
||||
return False
|
||||
|
||||
port = int(match.group(5))
|
||||
return 1 <= port <= 65535
|
||||
|
||||
|
||||
def get_proxy_from_api(api_url: str, max_retries: int = 3) -> Optional[str]:
|
||||
"""从API获取代理IP(支持重试)。"""
|
||||
ip_port_pattern = re.compile(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{1,5}$")
|
||||
max_retries = max(1, int(max_retries or 1))
|
||||
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
response = requests.get(api_url, timeout=10)
|
||||
if response.status_code == 200:
|
||||
text = response.text.strip()
|
||||
|
||||
# 尝试解析JSON响应
|
||||
try:
|
||||
import json
|
||||
|
||||
data = json.loads(text)
|
||||
if isinstance(data, dict):
|
||||
if data.get("status") not in (200, 0, None):
|
||||
error_msg = data.get("msg", data.get("message", "未知错误"))
|
||||
logger.warning(f"代理API返回错误: {error_msg} (尝试 {attempt + 1}/{max_retries})")
|
||||
if attempt < max_retries - 1:
|
||||
time.sleep(1)
|
||||
continue
|
||||
ip_port = data.get("ip") or data.get("proxy") or data.get("data")
|
||||
if ip_port:
|
||||
text = str(ip_port).strip()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if ip_port_pattern.match(text) and validate_ip_port(text):
|
||||
proxy_server = f"http://{text}"
|
||||
logger.info(f"获取代理成功: {proxy_server} (尝试 {attempt + 1}/{max_retries})")
|
||||
return proxy_server
|
||||
|
||||
logger.warning(f"代理格式或范围无效: {text[:50]} (尝试 {attempt + 1}/{max_retries})")
|
||||
else:
|
||||
logger.warning(f"获取代理失败: HTTP {response.status_code} (尝试 {attempt + 1}/{max_retries})")
|
||||
except Exception as e:
|
||||
logger.warning(f"获取代理异常: {str(e)} (尝试 {attempt + 1}/{max_retries})")
|
||||
|
||||
if attempt < max_retries - 1:
|
||||
time.sleep(1)
|
||||
|
||||
logger.warning(f"获取代理失败,已重试 {max_retries} 次,将不使用代理继续")
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user