import json import logging import time import requests logger = logging.getLogger(__name__) def get_proxy_from_api(api_url, max_retries=3, timeout=10): if not api_url: return None last_error = None for attempt in range(max_retries): try: resp = requests.get(api_url, timeout=timeout) resp.raise_for_status() content = resp.text.strip() if not content: raise ValueError("代理 API 返回空内容") try: data = resp.json() if "ip" in data and "port" in data: proxy_str = f"{data['ip']}:{data['port']}" else: proxy_str = content except json.JSONDecodeError: proxy_str = content if not proxy_str.startswith(("http://", "https://")): proxy_str = f"http://{proxy_str}" return {"server": proxy_str} except Exception as e: last_error = e if attempt < max_retries - 1: wait = 2 ** attempt logger.warning("获取代理失败 (第%s次): %s,%ss 后重试", attempt + 1, e, wait) time.sleep(wait) logger.error("获取代理失败,已重试%s次: %s", max_retries, last_error) return None def test_proxy_api(proxy_api): proxy = get_proxy_from_api(proxy_api, timeout=5) if not proxy: return {"status": "error", "message": "获取代理失败"} proxies = {"http": proxy["server"], "https": proxy["server"]} test_urls = [ "http://httpbin.org/ip", "https://api.ipify.org?format=json", ] last_err = None for test_url in test_urls: try: resp = requests.get(test_url, proxies=proxies, timeout=10) if resp.status_code == 200: try: data = resp.json() ip = data.get("origin") or data.get("ip", "unknown") except json.JSONDecodeError: ip = resp.text.strip()[:64] or "unknown" return {"status": "success", "ip": ip, "message": "代理可用"} except Exception as e: last_err = e return {"status": "error", "message": f"代理测试失败: {last_err}"}