feature!: перенимаем реализацию прохождения cf_turnstile у scrapling

https://github.com/D4Vinci/Scrapling

BREAKING_CHANGES: клик отрабатывает, но прохода не случается
This commit is contained in:
protokey committed 2026-09-23 11:21:18 +04:00
1 parent f2d4d441f4
commit 8f7645b2b9
11 files changed
+193 -30

No files matched your search

+25 -8
View File
@@ -11,10 +11,11 @@ from fastapi import Cookie
from fastapi import FastAPI
from fastapi import Request
from fastapi import Response
from playwright.async_api import ProxySettings
from playwright.async_api import async_playwright
from patchright.async_api import ProxySettings
from patchright.async_api import async_playwright
from engine import actions
from engine.browser_launch import HARMFUL_ARGS, launch_args, stealth_context_options
from engine.fingerprint import apply_fingerprint, context_options_for, load_or_create_fingerprint
from engine.geoip import resolve_geo
from engine.schemas import SolveRequest
@@ -77,9 +78,16 @@ async def solve(
if not user_data_dir.exists():
user_data_dir.mkdir(parents=True)
# geo — до создания fingerprint'а, чтобы производная от прокси locale (см. engine/geoip.py)
# попала в сам fingerprint, а не подменяла его задним числом
geo = await resolve_geo(proxy)
locale = geo.get("locale") if geo else None
fp_kwargs = {}
if payload.user_agent:
fp_kwargs["user_agent"] = payload.user_agent
if locale:
fp_kwargs["locale"] = locale
fingerprint = load_or_create_fingerprint(
user_data_dir,
# только нижняя граница: реалистичный монитор должен быть не меньше запрошенного окна,
@@ -89,24 +97,33 @@ async def solve(
**fp_kwargs,
)
ctx_kwargs = context_options_for(
fingerprint,
viewport={"width": scr_size[0], "height": scr_size[1]},
)
ctx_kwargs = {
# базовые анти-детект опции ниже — fingerprint накладывается поверх и выигрывает
# при конфликте по user_agent/viewport/device_scale_factor
**stealth_context_options(),
**context_options_for(
fingerprint,
viewport={"width": scr_size[0], "height": scr_size[1]},
),
}
geo = await resolve_geo(proxy)
permissions = ["notifications"]
if geo:
if geo.get("timezone_id"):
ctx_kwargs["timezone_id"] = geo["timezone_id"]
if geo.get("geolocation"):
ctx_kwargs["geolocation"] = geo["geolocation"]
ctx_kwargs["permissions"] = ["geolocation"]
permissions.append("geolocation")
ctx_kwargs["permissions"] = permissions
async with async_playwright() as p:
context = await p.chromium.launch_persistent_context(
user_data_dir=str(user_data_dir),
proxy=proxy,
headless=False,
channel="chrome",
args=launch_args(locale=locale),
ignore_default_args=HARMFUL_ARGS,
**ctx_kwargs,
)
try: