feature!: перенимаем реализацию прохождения cf_turnstile у scrapling
https://github.com/D4Vinci/Scrapling BREAKING_CHANGES: клик отрабатывает, но прохода не случается
This commit is contained in:
1 parent
f2d4d441f4
commit
8f7645b2b9
11 files changed
+193
-30
No files matched your search
+31
-8
@@ -18,13 +18,32 @@ import time
|
||||
from pathlib import Path
|
||||
|
||||
import httpx
|
||||
from playwright.async_api import ProxySettings
|
||||
from patchright.async_api import ProxySettings
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
IPINFO_URL = "https://ipinfo.io/json"
|
||||
DEFAULT_CACHE_FILE = Path(__file__).resolve().parent.parent.parent / "extra" / "geoip_cache.json"
|
||||
DEFAULT_TTL = 24 * 3600 # прокси может сменить exit-IP — не кэшируем навечно
|
||||
DEFAULT_LOCALE = "en-US"
|
||||
|
||||
# Страна exit-IP -> основная локаль. Раньше это (как и timezone/geolocation) под капотом
|
||||
# делал Camoufox(geoip=True); теперь резолвим сами и прокидываем в browserforge (locale
|
||||
# согласованно выставляет navigator.language/languages и Accept-Language header) и в
|
||||
# launch-флаги Chromium --lang=/--accept-lang= (engine/browser_launch.py). Не более чем
|
||||
# точечная таблица под реально используемые прокси-гео — не претендует на полноту ISO-3166.
|
||||
_COUNTRY_LOCALE: dict[str, str] = {
|
||||
"RU": "ru-RU", "BY": "ru-BY", "KZ": "ru-KZ", "UA": "uk-UA",
|
||||
"US": "en-US", "GB": "en-GB", "CA": "en-CA", "AU": "en-AU", "IE": "en-IE", "IN": "en-IN",
|
||||
"DE": "de-DE", "AT": "de-AT", "CH": "de-CH",
|
||||
"FR": "fr-FR", "BE": "fr-BE",
|
||||
"ES": "es-ES", "MX": "es-MX", "AR": "es-AR",
|
||||
"IT": "it-IT", "PT": "pt-PT", "BR": "pt-BR", "NL": "nl-NL",
|
||||
"PL": "pl-PL", "CZ": "cs-CZ", "SK": "sk-SK", "RO": "ro-RO", "HU": "hu-HU",
|
||||
"SE": "sv-SE", "NO": "nb-NO", "FI": "fi-FI", "DK": "da-DK",
|
||||
"TR": "tr-TR", "GR": "el-GR",
|
||||
"CN": "zh-CN", "TW": "zh-TW", "JP": "ja-JP", "KR": "ko-KR",
|
||||
}
|
||||
|
||||
_cache_lock = asyncio.Lock()
|
||||
|
||||
@@ -59,14 +78,16 @@ async def resolve_geo(
|
||||
cache_file: Path = DEFAULT_CACHE_FILE,
|
||||
ttl: float = DEFAULT_TTL,
|
||||
) -> dict | None:
|
||||
"""Возвращает {"timezone_id", "geolocation": {"latitude", "longitude"}, "country", "ip"}
|
||||
"""Возвращает {"timezone_id", "geolocation": {"latitude", "longitude"}, "country", "ip", "locale"}
|
||||
по IP, который виден снаружи через прокси, или None, если резолв не удался и в кэше
|
||||
тоже ничего нет — в этом случае вызывающий код просто не переопределяет timezone/geolocation.
|
||||
тоже ничего нет — в этом случае вызывающий код просто не переопределяет timezone/geolocation/locale.
|
||||
|
||||
Язык (locale) сюда намеренно не подмешиваем: Accept-Language — это предпочтение пользователя,
|
||||
а не производная от геолокации IP, и его уже согласованно генерирует fingerprint (см.
|
||||
engine/fingerprint.py). Подменять его на "en-<COUNTRY>" было бы отдельным, никак не
|
||||
связанным с реальным поведением допущением."""
|
||||
"locale" — основная локаль страны exit-IP (см. _COUNTRY_LOCALE), с фолбэком DEFAULT_LOCALE
|
||||
для неизвестных/отсутствующих кодов страны. Реальный человек с российским прокси не сидит
|
||||
с английской раскладкой браузера, поэтому locale — такой же производный от IP сигнал, как
|
||||
timezone/geolocation, а не независимое "предпочтение пользователя". Прокидывается вызывающим
|
||||
кодом в browserforge (согласованно выставляет navigator.language/languages и Accept-Language,
|
||||
см. engine/fingerprint.py) и в launch-флаги Chromium (engine/browser_launch.py)."""
|
||||
key = proxy_settings_to_url(proxy)
|
||||
|
||||
async with _cache_lock:
|
||||
@@ -98,11 +119,13 @@ async def resolve_geo(
|
||||
except ValueError:
|
||||
geolocation = None
|
||||
|
||||
country = data.get("country") # "RU", "US", ...
|
||||
result = {
|
||||
"ip": data.get("ip"),
|
||||
"country": data.get("country"), # "RU", "US", ...
|
||||
"country": country,
|
||||
"timezone_id": data.get("timezone"),
|
||||
"geolocation": geolocation,
|
||||
"locale": _COUNTRY_LOCALE.get(country, DEFAULT_LOCALE),
|
||||
}
|
||||
|
||||
async with _cache_lock:
|
||||
|
||||
Reference in new issue
Block a user