diff --git a/src/main.py b/src/main.py index 54fce69..f9c97e3 100644 --- a/src/main.py +++ b/src/main.py @@ -1,17 +1,18 @@ +import json import uuid from datetime import datetime from pathlib import Path from typing import Annotated from urllib.parse import urlsplit -from browserforge.fingerprints import Screen from camoufox.async_api import AsyncCamoufox +from camoufox.fingerprints import generate_context_fingerprint from camoufox.utils import determine_ua_os from fastapi import Cookie from fastapi import FastAPI from fastapi import Request from fastapi import Response -from playwright.async_api import ViewportSize, ProxySettings +from playwright.async_api import ProxySettings from ua_parser import user_agent_parser from engine import actions @@ -33,6 +34,18 @@ def parse_proxy(proxy_url: str) -> ProxySettings: return settings +def load_or_create_identity(user_data_dir, os=None, ff_version=None, locale=None, time_zone=None) -> dict: + identity_file = user_data_dir / IDENTITY_FILE + + if identity_file.exists(): + return json.loads(identity_file.read_text()) + + # один вызов -> config (для браузера) + context_options/init_script (для контекста) + fp = generate_context_fingerprint(os=os, ff_version=ff_version, locale=locale, timezone=time_zone) + identity_file.write_text(json.dumps(fp)) + return fp + + app = FastAPI() @@ -47,8 +60,8 @@ _OS_MAP = {'win': 'windows', 'mac': 'macos', 'lin': 'linux'} def parse_os_and_ff(user_agent): os_name = _OS_MAP[determine_ua_os(user_agent)] parsed = user_agent_parser.ParseUserAgent(user_agent) - ff_version = int(parsed["major"]) if( - parsed.get("family") == "Firefox" and parsed.get("major") )else None + ff_version = int(parsed["major"]) if ( + parsed.get("family") == "Firefox" and parsed.get("major")) else None return os_name, ff_version @@ -81,24 +94,34 @@ async def solve( # proxy = ProxySettings(socks5://host:port, username, password) proxy = None - browser_options = {} - if payload.user_agent: - os, ff_version = parse_os_and_ff(payload.user_agent) - browser_options["os"] = os - browser_options["ff_version"] = ff_version - browser_options["config"] = {'navigator.UserAgent': payload.user_agent} - user_data_dir = Path(__file__).parent / f"../extra/user_data_dir/{session_id}" if not user_data_dir.exists(): user_data_dir.mkdir(parents=True) + browser_options = { + # "locale": payload.locale, + # "timezone": payload.time_zone + } + ctx_opts = {} + if payload.user_agent: + os, ff_version = parse_os_and_ff(payload.user_agent) + ctx_opts["config"] = {'navigator.UserAgent': payload.user_agent} + else: + os = ff_version = None + + config = load_or_create_identity(user_data_dir, os=os, ff_version=ff_version, **browser_options) + + ctx_opts = {**config["context_options"], **browser_options} async with AsyncCamoufox( persistent_context=True, user_data_dir=user_data_dir, proxy=proxy, window=scr_size, - **browser_options, + os=os, + ff_version=ff_version, + **ctx_opts, ) as camoufo: + await camoufo.add_init_script(config["init_script"]) page = camoufo.pages[0] if camoufo.pages else await camoufo.new_page() page.set_default_timeout(30_000) await page.goto(url=payload.url)