fix proxy detect

This commit is contained in:
Yuriy Yuriev
2026-05-18 23:14:43 +07:00
parent 55b0ee4231
commit 9b246c5cf0
2 changed files with 87 additions and 19 deletions
+42
View File
@@ -104,6 +104,48 @@ class Proxy:
return None
async def detect_proxy_type(
ip: str,
port: str,
login: Optional[str] = None,
password: Optional[str] = None,
timeout: float = 5.0,
test_url: str = "http://api.ipify.org"
) -> Optional[ProxyType]:
"""
Определяет тип прокси подключением.
Пробует SOCKS5 → SOCKS4 → HTTP. Возвращает первый рабочий или None.
"""
import aiohttp
candidates = [
(ProxyType.SOCKS5, f"socks5://{ip}:{port}"),
(ProxyType.SOCKS4, f"socks4://{ip}:{port}"),
(ProxyType.HTTP, f"http://{ip}:{port}"),
]
auth = aiohttp.BasicAuth(login, password) if login and password else None
for proxy_type, proxy_url in candidates:
try:
connector = aiohttp.TCPConnector(ssl=False)
async with aiohttp.ClientSession(connector=connector) as session:
async with session.get(
test_url,
proxy=proxy_url,
proxy_auth=auth,
timeout=aiohttp.ClientTimeout(total=timeout),
) as resp:
if resp.status == 200:
logger.info(f"Proxy {ip}:{port} detected as {proxy_type.value}")
return proxy_type
except Exception:
pass
logger.warning(f"Proxy {ip}:{port} — type not detected")
return None
class ProxyManager:
"""
Менеджер прокси с поддержкой SOCKS5 и HTTP.
+45 -19
View File
@@ -12,6 +12,7 @@ from dataclasses import dataclass
from camoufox import DefaultAddons
from camoufox.async_api import AsyncCamoufox
from camoufox.exceptions import InvalidIP
from config.settings import settings
from managers.proxy_manager import ProxyManager, Proxy, ProxyType
@@ -20,23 +21,43 @@ from services.socks5_to_http_proxy import Socks5ProxyPool
logger = logging.getLogger(__name__)
def _patch_camoufox():
"""Патчит camoufox.utils.generate_fingerprint чтобы убирать screen constraint при ошибке."""
import camoufox.utils as _cu
_orig = _cu.generate_fingerprint
_socks5_real_ip: Optional[str] = None
def _patched(**config):
def _patch_camoufox():
"""Патчит camoufox чтобы:
1. Убирать screen constraint из generate_fingerprint при ошибке
2. Возвращать реальный IP SOCKS5 прокси вместо попытки запроса через туннель
"""
import camoufox.utils as _cu
import camoufox.ip as _ci
# Патч 1: generate_fingerprint — убираем screen при ошибке
_orig_gf = _cu.generate_fingerprint
def _patched_gf(**config):
try:
return _orig(**config)
return _orig_gf(**config)
except ValueError:
config.pop("screen", None)
try:
return _orig(**config)
return _orig_gf(**config)
except ValueError:
minimal = {k: v for k, v in config.items() if k == "locale"}
return _orig(**minimal)
return _orig_gf(**minimal)
_cu.generate_fingerprint = _patched
_cu.generate_fingerprint = _patched_gf
# Патч 2: public_ip — возвращаем реальный IP прокси вместо HTTP-запроса через туннель
_orig_ip = _ci.public_ip
def _patched_ip(proxy_string: str) -> str:
global _socks5_real_ip
if _socks5_real_ip and "127.0.0.1" in str(proxy_string):
return _socks5_real_ip
return _orig_ip(proxy_string)
_ci.public_ip = _patched_ip
_patch_camoufox()
@@ -101,20 +122,25 @@ class BrowserService:
if self.proxy_manager.has_proxies():
proxy = await self.proxy_manager.acquire_proxy(timeout=30)
socks5_locale = None
global _socks5_real_ip
proxy_locale = None
if proxy and proxy.proxy_type in [ProxyType.SOCKS5, ProxyType.SOCKS4]:
proxy_config = await self.socks5_pool.get_proxy_config(proxy)
use_socks5 = True
# При SOCKS5 camoufox видит 127.0.0.1 → geoip берёт IP сервера → ru-Cyrl-RU
# Делаем lookup по реальному IP прокси сами и передаём чистый locale
real_ip = proxy.id.split("://")[-1].split(":")[0]
socks5_locale = _locale_for_ip(real_ip)
logger.info(f"Using SOCKS5 tunnel for: {proxy.id} locale={socks5_locale}")
_socks5_real_ip = real_ip
proxy_locale = _locale_for_ip(real_ip)
logger.info(f"Using SOCKS5 tunnel for: {proxy.id} locale={proxy_locale}")
elif proxy:
proxy_config = proxy.proxy_config
logger.info(f"Using HTTP proxy: {proxy.id}")
real_ip = proxy.id.split("://")[-1].split(":")[0]
_socks5_real_ip = real_ip
proxy_locale = _locale_for_ip(real_ip)
logger.info(f"Using HTTP proxy: {proxy.id} locale={proxy_locale}")
else:
proxy_config = None
_socks5_real_ip = None
logger.info("Direct connection")
if proxy_config:
@@ -125,8 +151,8 @@ class BrowserService:
exclude_addons=[DefaultAddons.UBO],
proxy=proxy_config,
)
if socks5_locale:
camoufox_kwargs["locale"] = socks5_locale
if proxy_locale:
camoufox_kwargs["locale"] = proxy_locale
async with AsyncCamoufox(**camoufox_kwargs) as browser:
result = await self._browse_page(
browser, url,
@@ -152,8 +178,8 @@ class BrowserService:
return result
except ValueError as e:
logger.warning(f"Visit attempt {attempt + 1} fingerprint error, retrying with new proxy: {e}")
except (ValueError, InvalidIP) as e:
logger.warning(f"Visit attempt {attempt + 1} proxy error, retrying: {e}")
if proxy:
await self.proxy_manager.release_proxy(proxy, success=False)
if use_socks5: