Spaces:
Sleeping
Sleeping
| """ | |
| Proxy Checker | |
| Проверяет работоспособность прокси перед использованием. | |
| """ | |
| import requests | |
| import time | |
| from typing import Optional, Dict, Any | |
| from dataclasses import dataclass | |
| import logging | |
| logger = logging.getLogger(__name__) | |
| class ProxyCheckResult: | |
| """Результат проверки прокси""" | |
| is_working: bool | |
| response_time: Optional[float] = None # в секундах | |
| ip_address: Optional[str] = None | |
| error: Optional[str] = None | |
| class ProxyChecker: | |
| """Проверка работоспособности прокси""" | |
| # URL для проверки (быстрый и надёжный) | |
| CHECK_URLS = [ | |
| 'https://api.ipify.org?format=json', # Возвращает IP | |
| 'https://httpbin.org/ip', # Альтернатива | |
| 'https://icanhazip.com', # Ещё одна альтернатива | |
| ] | |
| def __init__(self, timeout: int = 10): | |
| """ | |
| Args: | |
| timeout: Таймаут проверки в секундах | |
| """ | |
| self.timeout = timeout | |
| def check_proxy(self, proxy: str) -> ProxyCheckResult: | |
| """ | |
| Проверить работоспособность прокси | |
| Args: | |
| proxy: Прокси в формате: | |
| - "host:port" | |
| - "user:pass@host:port" | |
| - "http://host:port" | |
| - "http://user:pass@host:port" | |
| Returns: | |
| ProxyCheckResult с результатом проверки | |
| """ | |
| # Нормализуем формат прокси | |
| proxy_url = self._normalize_proxy(proxy) | |
| proxies = { | |
| 'http': proxy_url, | |
| 'https': proxy_url | |
| } | |
| # Пробуем несколько URL | |
| for check_url in self.CHECK_URLS: | |
| try: | |
| start_time = time.time() | |
| response = requests.get( | |
| check_url, | |
| proxies=proxies, | |
| timeout=self.timeout, | |
| headers={'User-Agent': 'Mozilla/5.0'} | |
| ) | |
| response_time = time.time() - start_time | |
| if response.status_code == 200: | |
| # Пытаемся извлечь IP | |
| ip_address = None | |
| try: | |
| if 'json' in response.headers.get('Content-Type', ''): | |
| data = response.json() | |
| ip_address = data.get('ip') or data.get('origin') | |
| else: | |
| ip_address = response.text.strip() | |
| except: | |
| pass | |
| logger.info(f"[Proxy] ✓ Working: {proxy} (IP: {ip_address}, {response_time:.2f}s)") | |
| return ProxyCheckResult( | |
| is_working=True, | |
| response_time=response_time, | |
| ip_address=ip_address | |
| ) | |
| except requests.exceptions.ProxyError as e: | |
| error = f"Proxy error: {str(e)}" | |
| logger.warning(f"[Proxy] ✗ {proxy}: {error}") | |
| return ProxyCheckResult(is_working=False, error=error) | |
| except requests.exceptions.Timeout: | |
| error = f"Timeout after {self.timeout}s" | |
| logger.warning(f"[Proxy] ✗ {proxy}: {error}") | |
| return ProxyCheckResult(is_working=False, error=error) | |
| except requests.exceptions.ConnectionError as e: | |
| error = f"Connection error: {str(e)}" | |
| logger.warning(f"[Proxy] ✗ {proxy}: {error}") | |
| return ProxyCheckResult(is_working=False, error=error) | |
| except Exception as e: | |
| # Пробуем следующий URL | |
| logger.debug(f"[Proxy] Check failed with {check_url}: {e}") | |
| continue | |
| # Все URL не сработали | |
| error = "All check URLs failed" | |
| logger.error(f"[Proxy] ✗ {proxy}: {error}") | |
| return ProxyCheckResult(is_working=False, error=error) | |
| def _normalize_proxy(self, proxy: str) -> str: | |
| """ | |
| Нормализовать формат прокси к http://... | |
| Args: | |
| proxy: Прокси в любом формате | |
| Returns: | |
| Прокси в формате http://... | |
| """ | |
| proxy = proxy.strip() | |
| # Уже в правильном формате | |
| if proxy.startswith('http://') or proxy.startswith('https://'): | |
| return proxy | |
| # Добавляем протокол | |
| return f'http://{proxy}' | |
| def check_proxy_list(self, proxies: list[str], | |
| max_workers: int = 5) -> Dict[str, ProxyCheckResult]: | |
| """ | |
| Проверить список прокси параллельно | |
| Args: | |
| proxies: Список прокси | |
| max_workers: Максимальное количество параллельных проверок | |
| Returns: | |
| Dict {proxy: ProxyCheckResult} | |
| """ | |
| from concurrent.futures import ThreadPoolExecutor, as_completed | |
| results = {} | |
| with ThreadPoolExecutor(max_workers=max_workers) as executor: | |
| future_to_proxy = { | |
| executor.submit(self.check_proxy, proxy): proxy | |
| for proxy in proxies | |
| } | |
| for future in as_completed(future_to_proxy): | |
| proxy = future_to_proxy[future] | |
| try: | |
| result = future.result() | |
| results[proxy] = result | |
| except Exception as e: | |
| logger.error(f"[Proxy] Error checking {proxy}: {e}") | |
| results[proxy] = ProxyCheckResult( | |
| is_working=False, | |
| error=str(e) | |
| ) | |
| return results | |
| def get_working_proxies(self, proxies: list[str], | |
| max_workers: int = 5) -> list[str]: | |
| """ | |
| Получить только рабочие прокси из списка | |
| Args: | |
| proxies: Список прокси для проверки | |
| max_workers: Максимальное количество параллельных проверок | |
| Returns: | |
| Список рабочих прокси | |
| """ | |
| results = self.check_proxy_list(proxies, max_workers) | |
| working = [ | |
| proxy for proxy, result in results.items() | |
| if result.is_working | |
| ] | |
| logger.info(f"[Proxy] Working: {len(working)}/{len(proxies)}") | |
| return working | |
| def check_proxy_cli(proxy: str, timeout: int = 10) -> bool: | |
| """ | |
| CLI функция для быстрой проверки прокси | |
| Args: | |
| proxy: Прокси для проверки | |
| timeout: Таймаут в секундах | |
| Returns: | |
| True если прокси работает | |
| """ | |
| checker = ProxyChecker(timeout=timeout) | |
| result = checker.check_proxy(proxy) | |
| if result.is_working: | |
| print(f"✓ Proxy is working") | |
| if result.ip_address: | |
| print(f" IP: {result.ip_address}") | |
| if result.response_time: | |
| print(f" Response time: {result.response_time:.2f}s") | |
| return True | |
| else: | |
| print(f"✗ Proxy is NOT working") | |
| if result.error: | |
| print(f" Error: {result.error}") | |
| return False | |
| if __name__ == '__main__': | |
| import sys | |
| if len(sys.argv) < 2: | |
| print("Usage: python -m autoreg.core.proxy_checker <proxy>") | |
| print("Example: python -m autoreg.core.proxy_checker user:pass@proxy.com:8080") | |
| sys.exit(1) | |
| proxy = sys.argv[1] | |
| timeout = int(sys.argv[2]) if len(sys.argv) > 2 else 10 | |
| success = check_proxy_cli(proxy, timeout) | |
| sys.exit(0 if success else 1) | |