browser-stealth 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. browser_stealth/__init__.py +127 -0
  2. browser_stealth/antidetect/__init__.py +43 -0
  3. browser_stealth/antidetect/_mobile_scripts.py +3 -0
  4. browser_stealth/antidetect/antidetect.py +3 -0
  5. browser_stealth/antidetect/antidetect_scripts.py +3 -0
  6. browser_stealth/antidetect/config.py +495 -0
  7. browser_stealth/antidetect/core.py +527 -0
  8. browser_stealth/antidetect/mobile.py +177 -0
  9. browser_stealth/antidetect/scripts.py +594 -0
  10. browser_stealth/bidi/__init__.py +25 -0
  11. browser_stealth/bidi/antidetect.py +78 -0
  12. browser_stealth/bidi/client.py +481 -0
  13. browser_stealth/bidi/exceptions.py +43 -0
  14. browser_stealth/bidi/session.py +304 -0
  15. browser_stealth/concurrency/__init__.py +29 -0
  16. browser_stealth/concurrency/base.py +63 -0
  17. browser_stealth/concurrency/limiter.py +118 -0
  18. browser_stealth/concurrency/metrics.py +67 -0
  19. browser_stealth/concurrency/models.py +41 -0
  20. browser_stealth/concurrency/pool.py +142 -0
  21. browser_stealth/concurrency/queues.py +422 -0
  22. browser_stealth/concurrency/reaper.py +395 -0
  23. browser_stealth/crypto.py +64 -0
  24. browser_stealth/exceptions.py +41 -0
  25. browser_stealth/fingerprint/__init__.py +23 -0
  26. browser_stealth/fingerprint/database.py +155 -0
  27. browser_stealth/fingerprint/external.py +131 -0
  28. browser_stealth/fingerprint/models.py +226 -0
  29. browser_stealth/fingerprint/procedural.py +190 -0
  30. browser_stealth/fingerprint/synthesizer.py +145 -0
  31. browser_stealth/fs.py +91 -0
  32. browser_stealth/humanize/__init__.py +81 -0
  33. browser_stealth/humanize/_actions_helpers.py +625 -0
  34. browser_stealth/humanize/_mobile_scripts.py +177 -0
  35. browser_stealth/humanize/actions.py +550 -0
  36. browser_stealth/humanize/antidetect.py +20 -0
  37. browser_stealth/humanize/antidetect_scripts.py +18 -0
  38. browser_stealth/humanize/behavior.py +300 -0
  39. browser_stealth/humanize/config.py +6 -0
  40. browser_stealth/humanize/consent.py +97 -0
  41. browser_stealth/humanize/math_utils.py +685 -0
  42. browser_stealth/humanize/search.py +176 -0
  43. browser_stealth/humanize/touch.py +336 -0
  44. browser_stealth/humanize/turnstile.py +411 -0
  45. browser_stealth/humanize/warmer.py +606 -0
  46. browser_stealth/launchers/__init__.py +7 -0
  47. browser_stealth/launchers/camoufox.py +61 -0
  48. browser_stealth/launchers/nodriver.py +259 -0
  49. browser_stealth/lifecycle.py +66 -0
  50. browser_stealth/logging.py +23 -0
  51. browser_stealth/plugin.py +69 -0
  52. browser_stealth/profiles/__init__.py +31 -0
  53. browser_stealth/profiles/adapters/__init__.py +23 -0
  54. browser_stealth/profiles/adapters/nodriver.py +150 -0
  55. browser_stealth/profiles/adapters/playwright.py +105 -0
  56. browser_stealth/profiles/adapters/selenium.py +86 -0
  57. browser_stealth/profiles/hygiene.py +254 -0
  58. browser_stealth/profiles/manager.py +233 -0
  59. browser_stealth/profiles/models.py +46 -0
  60. browser_stealth/profiles/storage.py +83 -0
  61. browser_stealth/proxy/__init__.py +79 -0
  62. browser_stealth/proxy/adapters.py +116 -0
  63. browser_stealth/proxy/cache.py +172 -0
  64. browser_stealth/proxy/extension.py +212 -0
  65. browser_stealth/proxy/models.py +108 -0
  66. browser_stealth/proxy/parser.py +130 -0
  67. browser_stealth/proxy/pool.py +287 -0
  68. browser_stealth/proxy/resolver.py +606 -0
  69. browser_stealth/proxy/storage.py +249 -0
  70. browser_stealth/proxy/tunnel.py +383 -0
  71. browser_stealth/py.typed +0 -0
  72. browser_stealth/testing/__init__.py +198 -0
  73. browser_stealth/testing/assertions.py +178 -0
  74. browser_stealth/testing/dom_models.py +162 -0
  75. browser_stealth/testing/dom_scripts.py +929 -0
  76. browser_stealth/testing/fixtures.py +126 -0
  77. browser_stealth/testing/mocks/__init__.py +26 -0
  78. browser_stealth/testing/mocks/dom.py +245 -0
  79. browser_stealth/testing/mocks/nodriver.py +154 -0
  80. browser_stealth/testing/mocks/playwright.py +197 -0
  81. browser_stealth/testing/mocks/selenium.py +199 -0
  82. browser_stealth/testing/recorder.py +443 -0
  83. browser_stealth/testing/server.py +318 -0
  84. browser_stealth/testing/session.py +201 -0
  85. browser_stealth/testing/snapshot.py +281 -0
  86. browser_stealth-0.1.0.dist-info/METADATA +151 -0
  87. browser_stealth-0.1.0.dist-info/RECORD +89 -0
  88. browser_stealth-0.1.0.dist-info/WHEEL +4 -0
  89. browser_stealth-0.1.0.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,127 @@
1
+ """Next-generation browser antidetect, human-like behavior emulation, and profile warmer.
2
+
3
+ Библиотека глубокой маскировки и эмуляции поведения человека для nodriver, Playwright, Selenium и WebDriver BiDi.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from . import (
9
+ antidetect,
10
+ bidi,
11
+ concurrency,
12
+ fingerprint,
13
+ humanize,
14
+ launchers,
15
+ profiles,
16
+ proxy,
17
+ testing,
18
+ )
19
+ from .antidetect.config import AntidetectConfig
20
+ from .antidetect.core import (
21
+ ANTIDETECT_JS_SCRIPT,
22
+ apply_antidetect_nodriver,
23
+ apply_antidetect_playwright,
24
+ apply_antidetect_selenium,
25
+ get_browser_launch_args,
26
+ get_client_hints,
27
+ )
28
+ from .bidi.client import BiDiClient
29
+ from .bidi.session import BiDiSession, bidi_session
30
+ from .exceptions import BrowserStealthError, OptionalDependencyError
31
+ from .humanize.actions import (
32
+ TouchGestureGenerator,
33
+ TouchPoint,
34
+ async_click,
35
+ async_human_sleep,
36
+ async_move_mouse,
37
+ async_scroll_to,
38
+ async_touch_swipe,
39
+ async_touch_tap,
40
+ async_type_text,
41
+ click,
42
+ human_sleep,
43
+ move_mouse,
44
+ scroll_to,
45
+ type_text,
46
+ )
47
+ from .humanize.behavior import BehavioralProfile
48
+ from .humanize.math_utils import (
49
+ BezierCurveGenerator,
50
+ JitterDelayGenerator,
51
+ KeyboardTypoGenerator,
52
+ WindMouseGenerator,
53
+ )
54
+ from .humanize.turnstile import (
55
+ detect_cf_turnstile,
56
+ is_cf_turnstile_solved,
57
+ solve_cf_turnstile,
58
+ )
59
+ from .humanize.warmer import ProfileWarmer, SyncProfileWarmer
60
+ from .launchers import camoufox, nodriver
61
+ from .launchers.nodriver import close_tab, launch_nodriver, nodriver_session
62
+ from .profiles.manager import ProfileManager
63
+ from .profiles.models import BrowserProfile
64
+ from .proxy.models import ProxyConfig, ProxyHealthResult
65
+ from .proxy.parser import parse_proxy
66
+ from .proxy.pool import ProxyPool
67
+
68
+ __version__ = "0.1.0"
69
+
70
+ __all__ = [
71
+ "ANTIDETECT_JS_SCRIPT",
72
+ "AntidetectConfig",
73
+ "BehavioralProfile",
74
+ "BezierCurveGenerator",
75
+ "BiDiClient",
76
+ "BiDiSession",
77
+ "BrowserProfile",
78
+ "BrowserStealthError",
79
+ "JitterDelayGenerator",
80
+ "KeyboardTypoGenerator",
81
+ "OptionalDependencyError",
82
+ "ProfileManager",
83
+ "ProfileWarmer",
84
+ "ProxyConfig",
85
+ "ProxyHealthResult",
86
+ "ProxyPool",
87
+ "SyncProfileWarmer",
88
+ "TouchGestureGenerator",
89
+ "TouchPoint",
90
+ "WindMouseGenerator",
91
+ "antidetect",
92
+ "apply_antidetect_nodriver",
93
+ "apply_antidetect_playwright",
94
+ "apply_antidetect_selenium",
95
+ "async_click",
96
+ "async_human_sleep",
97
+ "async_move_mouse",
98
+ "async_scroll_to",
99
+ "async_touch_swipe",
100
+ "async_touch_tap",
101
+ "async_type_text",
102
+ "bidi",
103
+ "bidi_session",
104
+ "camoufox",
105
+ "click",
106
+ "close_tab",
107
+ "concurrency",
108
+ "detect_cf_turnstile",
109
+ "fingerprint",
110
+ "get_browser_launch_args",
111
+ "get_client_hints",
112
+ "human_sleep",
113
+ "humanize",
114
+ "is_cf_turnstile_solved",
115
+ "launch_nodriver",
116
+ "launchers",
117
+ "move_mouse",
118
+ "nodriver",
119
+ "nodriver_session",
120
+ "parse_proxy",
121
+ "profiles",
122
+ "proxy",
123
+ "scroll_to",
124
+ "solve_cf_turnstile",
125
+ "testing",
126
+ "type_text",
127
+ ]
@@ -0,0 +1,43 @@
1
+ """Подсистема антидетекта и маскировки браузерных сред."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from .config import AntidetectConfig
6
+ from .core import (
7
+ ANTIDETECT_JS_SCRIPT,
8
+ _ensure_nodriver,
9
+ _ensure_playwright,
10
+ _ensure_selenium,
11
+ apply_antidetect_nodriver,
12
+ apply_antidetect_playwright,
13
+ apply_antidetect_selenium,
14
+ extract_clearance_cookies,
15
+ get_browser_launch_args,
16
+ get_client_hints,
17
+ )
18
+ from .scripts import (
19
+ DEFAULT_DEVICE_MEMORY,
20
+ DEFAULT_HARDWARE_CONCURRENCY,
21
+ DEFAULT_WEBGL_RENDERER,
22
+ DEFAULT_WEBGL_VENDOR,
23
+ _get_antidetect_js,
24
+ )
25
+
26
+ __all__ = [
27
+ "ANTIDETECT_JS_SCRIPT",
28
+ "DEFAULT_DEVICE_MEMORY",
29
+ "DEFAULT_HARDWARE_CONCURRENCY",
30
+ "DEFAULT_WEBGL_RENDERER",
31
+ "DEFAULT_WEBGL_VENDOR",
32
+ "AntidetectConfig",
33
+ "_ensure_nodriver",
34
+ "_ensure_playwright",
35
+ "_ensure_selenium",
36
+ "_get_antidetect_js",
37
+ "apply_antidetect_nodriver",
38
+ "apply_antidetect_playwright",
39
+ "apply_antidetect_selenium",
40
+ "extract_clearance_cookies",
41
+ "get_browser_launch_args",
42
+ "get_client_hints",
43
+ ]
@@ -0,0 +1,3 @@
1
+ """Алиас для обратной совместимости."""
2
+
3
+ from .mobile import *
@@ -0,0 +1,3 @@
1
+ """Алиас для обратной совместимости."""
2
+
3
+ from .core import *
@@ -0,0 +1,3 @@
1
+ """Алиас для обратной совместимости."""
2
+
3
+ from .scripts import *
@@ -0,0 +1,495 @@
1
+ """Декларативная конфигурация антидетекта для браузерных движков."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Any, cast
6
+
7
+ if TYPE_CHECKING:
8
+ from browser_stealth.fingerprint.models import FingerprintProfile
9
+
10
+ from pydantic import BaseModel, ConfigDict, Field
11
+
12
+ from .scripts import (
13
+ DEFAULT_DEVICE_MEMORY,
14
+ DEFAULT_HARDWARE_CONCURRENCY,
15
+ DEFAULT_WEBGL_RENDERER,
16
+ DEFAULT_WEBGL_VENDOR,
17
+ )
18
+
19
+
20
+ class AntidetectConfig(BaseModel):
21
+ """Конфигурация параметров маскировки браузера (антидетект)."""
22
+
23
+ model_config = ConfigDict(arbitrary_types_allowed=True, validate_assignment=True)
24
+
25
+ webgl_vendor: str = Field(
26
+ default=DEFAULT_WEBGL_VENDOR,
27
+ description="Эмулируемый производитель WebGL.",
28
+ )
29
+ webgl_renderer: str = Field(
30
+ default=DEFAULT_WEBGL_RENDERER,
31
+ description="Эмулируемая видеокарта WebGL.",
32
+ )
33
+ hardware_concurrency: int = Field(
34
+ default=DEFAULT_HARDWARE_CONCURRENCY,
35
+ ge=1,
36
+ le=128,
37
+ description="Количество виртуальных ядер процессора.",
38
+ )
39
+ device_memory: int = Field(
40
+ default=DEFAULT_DEVICE_MEMORY,
41
+ ge=1,
42
+ le=128,
43
+ description="Объем оперативной памяти устройства в ГБ.",
44
+ )
45
+ stealth_minimal: bool = Field(
46
+ default=True,
47
+ description=(
48
+ "Если True, не накладывать синтетический шум на Canvas и не подменять WebGL, "
49
+ "сохраняя 100% консистентный отпечаток реального Chromium (рекомендуется для nodriver)."
50
+ ),
51
+ )
52
+ session_seed: str | int = Field(
53
+ default=1337,
54
+ description="Сид для детерминированного шума Canvas и AudioContext.",
55
+ )
56
+ client_hints: dict[str, Any] | None = Field(
57
+ default=None,
58
+ description="Параметры navigator.userAgentData (brands, platform, mobile).",
59
+ )
60
+ user_agent: str | None = Field(
61
+ default=None,
62
+ description="Пользовательская строка User-Agent для переопределения через CDP/HTTP.",
63
+ )
64
+ screen_width: int | None = Field(
65
+ default=None,
66
+ description="Эмулируемая ширина экрана (screen.width).",
67
+ )
68
+ screen_height: int | None = Field(
69
+ default=None,
70
+ description="Эмулируемая высота экрана (screen.height).",
71
+ )
72
+ screen_avail_height: int | None = Field(
73
+ default=None,
74
+ description="Эмулируемая доступная высота экрана за вычетом панели задач (screen.availHeight).",
75
+ )
76
+ device_pixel_ratio: float | None = Field(
77
+ default=None,
78
+ description="Эмулируемый коэффициент масштабирования (window.devicePixelRatio).",
79
+ )
80
+ media_devices: list[dict[str, Any]] | None = Field(
81
+ default=None,
82
+ description="Список эмулируемых медиа-устройств (микрофоны, динамики, веб-камеры).",
83
+ )
84
+ is_mobile: bool = Field(
85
+ default=False,
86
+ description="Флаг эмуляции мобильного устройства.",
87
+ )
88
+ has_touch: bool = Field(
89
+ default=False,
90
+ description="Флаг поддержки сенсорного ввода (Touch Events).",
91
+ )
92
+ max_touch_points: int = Field(
93
+ default=0,
94
+ ge=0,
95
+ le=20,
96
+ description="Максимальное количество точек касания (navigator.maxTouchPoints).",
97
+ )
98
+ is_ios: bool = Field(
99
+ default=False,
100
+ description="Флаг эмуляции iOS Safari (специфичные объекты window.safari, ApplePaySession).",
101
+ )
102
+ orientation: dict[str, Any] | None = Field(
103
+ default=None,
104
+ description="Параметры ориентации экрана (type, angle).",
105
+ )
106
+
107
+ @classmethod
108
+ def preset_stealth_nodriver(
109
+ cls,
110
+ *,
111
+ session_seed: str | int = 1337,
112
+ client_hints: dict[str, Any] | None = None,
113
+ user_agent: str | None = None,
114
+ ) -> AntidetectConfig:
115
+ """Рекомендуемый пресет для nodriver: zero-footprint (без синтетического шума Canvas/WebGL).
116
+
117
+ Args:
118
+ session_seed: Сид для детерминированного генератора псевдослучайных чисел.
119
+ client_hints: Опциональный словарь с параметрами Client Hints.
120
+ user_agent: Опциональная строка User-Agent.
121
+
122
+ Returns:
123
+ Экземпляр AntidetectConfig с конфигурацией zero-footprint.
124
+ """
125
+ return cls(
126
+ stealth_minimal=True,
127
+ session_seed=session_seed,
128
+ client_hints=client_hints,
129
+ user_agent=user_agent,
130
+ )
131
+
132
+ @classmethod
133
+ def preset_aggressive(
134
+ cls,
135
+ *,
136
+ webgl_vendor: str = DEFAULT_WEBGL_VENDOR,
137
+ webgl_renderer: str = DEFAULT_WEBGL_RENDERER,
138
+ hardware_concurrency: int = DEFAULT_HARDWARE_CONCURRENCY,
139
+ device_memory: int = DEFAULT_DEVICE_MEMORY,
140
+ session_seed: str | int = 1337,
141
+ client_hints: dict[str, Any] | None = None,
142
+ user_agent: str | None = None,
143
+ ) -> AntidetectConfig:
144
+ """Агрессивный пресет с рандомизацией Canvas/WebGL/Audio (для Playwright/Selenium в headless).
145
+
146
+ Args:
147
+ webgl_vendor: Эмулируемый производитель WebGL.
148
+ webgl_renderer: Эмулируемая видеокарта WebGL.
149
+ hardware_concurrency: Эмулируемое количество ядер CPU.
150
+ device_memory: Эмулируемый объем оперативной памяти в ГБ.
151
+ session_seed: Сид для рандомизации шума Canvas/Audio.
152
+ client_hints: Дополнительные параметры Client Hints.
153
+ user_agent: Опциональная строка User-Agent.
154
+
155
+ Returns:
156
+ Экземпляр AntidetectConfig с агрессивной рандомизацией.
157
+ """
158
+ return cls(
159
+ webgl_vendor=webgl_vendor,
160
+ webgl_renderer=webgl_renderer,
161
+ hardware_concurrency=hardware_concurrency,
162
+ device_memory=device_memory,
163
+ stealth_minimal=False,
164
+ session_seed=session_seed,
165
+ client_hints=client_hints,
166
+ user_agent=user_agent,
167
+ )
168
+
169
+ @classmethod
170
+ def preset_minimal(
171
+ cls,
172
+ *,
173
+ session_seed: str | int = 1337,
174
+ user_agent: str | None = None,
175
+ ) -> AntidetectConfig:
176
+ """Минимальный пресет: отключен шум, только базовая защита от утечек и скрытие webdriver.
177
+
178
+ Args:
179
+ session_seed: Сид для инициализации сессии.
180
+ user_agent: Опциональная строка User-Agent.
181
+
182
+ Returns:
183
+ Экземпляр AntidetectConfig с минимальной модификацией.
184
+ """
185
+ return cls(
186
+ stealth_minimal=True,
187
+ session_seed=session_seed,
188
+ user_agent=user_agent,
189
+ )
190
+
191
+ @classmethod
192
+ def preset_mobile_android(
193
+ cls,
194
+ *,
195
+ device: str = "pixel_8",
196
+ session_seed: str | int = 1337,
197
+ stealth_minimal: bool = True,
198
+ ) -> AntidetectConfig:
199
+ """Мобильный пресет для Android Chrome (Pixel 8, Pixel 7, Galaxy S24).
200
+
201
+ Args:
202
+ device: Идентификатор устройства ('pixel_8', 'pixel_7', 'galaxy_s24').
203
+ session_seed: Сид для детерминированного шума и генератора поведения.
204
+ stealth_minimal: Режим маскировки.
205
+
206
+ Returns:
207
+ Экземпляр AntidetectConfig для Android устройства.
208
+ """
209
+ device_lower = device.lower()
210
+ if device_lower == "pixel_7":
211
+ width, height = 412, 915
212
+ dpr = 2.625
213
+ ua = (
214
+ "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 "
215
+ "(KHTML, like Gecko) Chrome/128.0.0.0 Mobile Safari/537.36"
216
+ )
217
+ vendor = "ARM"
218
+ renderer = "Mali-G710"
219
+ elif device_lower in ("galaxy_s24", "s24"):
220
+ width, height = 360, 780
221
+ dpr = 3.0
222
+ ua = (
223
+ "Mozilla/5.0 (Linux; Android 14; SM-S921B) AppleWebKit/537.36 "
224
+ "(KHTML, like Gecko) Chrome/128.0.0.0 Mobile Safari/537.36"
225
+ )
226
+ vendor = "Qualcomm"
227
+ renderer = "Adreno (TM) 750"
228
+ else: # pixel_8 по умолчанию или generic
229
+ width, height = 412, 915
230
+ dpr = 2.625
231
+ ua = (
232
+ f"Mozilla/5.0 (Linux; Android 14; {'Pixel 8' if device_lower == 'pixel_8' else device}) "
233
+ "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Mobile Safari/537.36"
234
+ )
235
+ vendor = "ARM"
236
+ renderer = "Mali-G715 Immortalis MC11"
237
+
238
+ client_hints = {
239
+ "platform": "Android",
240
+ "mobile": True,
241
+ "brands": [
242
+ {"brand": "Chromium", "version": "128"},
243
+ {"brand": "Google Chrome", "version": "128"},
244
+ {"brand": "Not;A=Brand", "version": "24"},
245
+ ],
246
+ }
247
+
248
+ return cls(
249
+ user_agent=ua,
250
+ webgl_vendor=vendor,
251
+ webgl_renderer=renderer,
252
+ hardware_concurrency=8,
253
+ device_memory=8,
254
+ screen_width=width,
255
+ screen_height=height,
256
+ screen_avail_height=height,
257
+ device_pixel_ratio=dpr,
258
+ is_mobile=True,
259
+ has_touch=True,
260
+ max_touch_points=5,
261
+ is_ios=False,
262
+ orientation={"type": "portrait-primary", "angle": 0},
263
+ client_hints=client_hints,
264
+ stealth_minimal=stealth_minimal,
265
+ session_seed=session_seed,
266
+ )
267
+
268
+ @classmethod
269
+ def preset_mobile_ios(
270
+ cls,
271
+ *,
272
+ device: str = "iphone_15",
273
+ session_seed: str | int = 1337,
274
+ stealth_minimal: bool = True,
275
+ ) -> AntidetectConfig:
276
+ """Мобильный пресет для iOS Safari (iPhone 15, iPhone 14).
277
+
278
+ Args:
279
+ device: Идентификатор устройства ('iphone_15', 'iphone_14').
280
+ session_seed: Сид для детерминированного шума и генератора поведения.
281
+ stealth_minimal: Режим маскировки.
282
+
283
+ Returns:
284
+ Экземпляр AntidetectConfig для iOS Safari.
285
+ """
286
+ device_lower = device.lower()
287
+ if device_lower in ("iphone_14", "iphone14"):
288
+ width, height = 390, 844
289
+ dpr = 3.0
290
+ ua = (
291
+ "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) "
292
+ "AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1"
293
+ )
294
+ else: # iphone_15 по умолчанию или generic
295
+ width, height = 393, 852
296
+ dpr = 3.0
297
+ ua = (
298
+ f"Mozilla/5.0 ({'iPhone' if 'iphone' in device_lower else device}; CPU iPhone OS 17_5 like Mac OS X) "
299
+ "AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1"
300
+ )
301
+
302
+ client_hints = {
303
+ "platform": "iOS",
304
+ "mobile": True,
305
+ "brands": [],
306
+ }
307
+
308
+ return cls(
309
+ user_agent=ua,
310
+ webgl_vendor="Apple Inc.",
311
+ webgl_renderer="Apple GPU",
312
+ hardware_concurrency=6,
313
+ device_memory=6,
314
+ screen_width=width,
315
+ screen_height=height,
316
+ screen_avail_height=height,
317
+ device_pixel_ratio=dpr,
318
+ is_mobile=True,
319
+ has_touch=True,
320
+ max_touch_points=5,
321
+ is_ios=True,
322
+ orientation={"type": "portrait-primary", "angle": 0},
323
+ client_hints=client_hints,
324
+ stealth_minimal=stealth_minimal,
325
+ session_seed=session_seed,
326
+ )
327
+
328
+ @classmethod
329
+ def from_fingerprint(
330
+ cls,
331
+ profile: FingerprintProfile | Any,
332
+ *,
333
+ stealth_minimal: bool = True,
334
+ ) -> AntidetectConfig:
335
+ """Создает AntidetectConfig на основе объекта FingerprintProfile.
336
+
337
+ Args:
338
+ profile: Экземпляр FingerprintProfile.
339
+ stealth_minimal: Если True, не накладывать синтетический шум на Canvas.
340
+
341
+ Returns:
342
+ Сконфигурированный экземпляр AntidetectConfig.
343
+ """
344
+ res = profile.to_antidetect_config(stealth_minimal=stealth_minimal)
345
+ return cast(AntidetectConfig, res)
346
+
347
+ @classmethod
348
+ def from_seed(
349
+ cls,
350
+ seed: int | str,
351
+ *,
352
+ stealth_minimal: bool = True,
353
+ os_target: str = "windows",
354
+ locale: str = "ru-RU",
355
+ ) -> AntidetectConfig:
356
+ """Синтезирует детерминированную цифровую личность по сиду и возвращает AntidetectConfig.
357
+
358
+ Один и тот же сид всегда дает абсолютно идентичный и физически согласованный
359
+ отпечаток (видеокарта, процессор, память, геометрия экрана, панель задач).
360
+
361
+ Args:
362
+ seed: Сид профиля или имя учетной записи.
363
+ stealth_minimal: Если True, сохраняет чистый отпечаток без искажения Canvas.
364
+ os_target: Целевая ОС ('windows').
365
+ locale: Локаль ('ru-RU', 'en-US').
366
+
367
+ Returns:
368
+ Экземпляр AntidetectConfig.
369
+ """
370
+ from browser_stealth.fingerprint import FingerprintSynthesizer
371
+
372
+ fp = FingerprintSynthesizer(
373
+ mode="procedural", os_target=os_target, locale=locale
374
+ ).synthesize(seed)
375
+ return fp.to_antidetect_config(stealth_minimal=stealth_minimal)
376
+
377
+ @classmethod
378
+ def from_browserforge(
379
+ cls,
380
+ seed: int | str | None = None,
381
+ *,
382
+ browser: str = "chrome",
383
+ os: str = "windows",
384
+ stealth_minimal: bool = True,
385
+ ) -> AntidetectConfig:
386
+ """Генерирует отпечаток через байесовскую сеть browserforge (при наличии пакета).
387
+
388
+ Args:
389
+ seed: Опциональный сид для воспроизводимой детерминированной генерации.
390
+ browser: Эмулируемый браузер ('chrome').
391
+ os: Целевая ОС ('windows').
392
+ stealth_minimal: Режим маскировки.
393
+
394
+ Returns:
395
+ Экземпляр AntidetectConfig.
396
+ """
397
+ from browser_stealth.fingerprint import FingerprintSynthesizer
398
+
399
+ fp = FingerprintSynthesizer(mode="browserforge", os_target=os).synthesize(seed)
400
+ return fp.to_antidetect_config(stealth_minimal=stealth_minimal)
401
+
402
+ @classmethod
403
+ def from_procedural(
404
+ cls,
405
+ seed: int | str | None = None,
406
+ *,
407
+ stealth_minimal: bool = True,
408
+ os_target: str = "windows",
409
+ locale: str = "ru-RU",
410
+ ) -> AntidetectConfig:
411
+ """Синтезирует отпечаток через встроенный процедурный генератор.
412
+
413
+ Args:
414
+ seed: Опциональный сид.
415
+ stealth_minimal: Режим маскировки.
416
+ os_target: Целевая ОС.
417
+ locale: Локаль.
418
+
419
+ Returns:
420
+ Экземпляр AntidetectConfig.
421
+ """
422
+ from browser_stealth.fingerprint import FingerprintSynthesizer
423
+
424
+ fp = FingerprintSynthesizer(
425
+ mode="procedural", os_target=os_target, locale=locale
426
+ ).synthesize(seed)
427
+ return fp.to_antidetect_config(stealth_minimal=stealth_minimal)
428
+
429
+ def get_behavioral_profile(self) -> Any:
430
+ """Возвращает детерминированный биометрический профиль моторики на основе session_seed.
431
+
432
+ Returns:
433
+ Экземпляр BehavioralProfile.
434
+ """
435
+ from browser_stealth.humanize.behavior import BehavioralProfile
436
+
437
+ return BehavioralProfile.from_seed(self.session_seed)
438
+
439
+ def get_init_script(self) -> str:
440
+ """Генерирует JavaScript-скрипт антидетекта на основе настроек конфигурации.
441
+
442
+ Returns:
443
+ Строка исполняемого JavaScript-кода для инъекции в браузер.
444
+ """
445
+ from .scripts import _get_antidetect_js
446
+
447
+ return _get_antidetect_js(
448
+ webgl_vendor=self.webgl_vendor,
449
+ webgl_renderer=self.webgl_renderer,
450
+ hardware_concurrency=self.hardware_concurrency,
451
+ device_memory=self.device_memory,
452
+ stealth_minimal=self.stealth_minimal,
453
+ session_seed=self.session_seed,
454
+ client_hints=self.client_hints,
455
+ screen_width=self.screen_width,
456
+ screen_height=self.screen_height,
457
+ screen_avail_height=self.screen_avail_height,
458
+ device_pixel_ratio=self.device_pixel_ratio,
459
+ media_devices=self.media_devices,
460
+ is_mobile=self.is_mobile,
461
+ has_touch=self.has_touch,
462
+ max_touch_points=self.max_touch_points,
463
+ is_ios=self.is_ios,
464
+ orientation=self.orientation,
465
+ )
466
+
467
+ async def apply_to_nodriver(self, tab: Any) -> None:
468
+ """Применяет данную конфигурацию антидетекта к вкладке nodriver Tab.
469
+
470
+ Args:
471
+ tab: Экземпляр вкладки nodriver Tab.
472
+ """
473
+ from .core import apply_antidetect_nodriver
474
+
475
+ await apply_antidetect_nodriver(tab, config=self)
476
+
477
+ async def apply_to_playwright(self, target: Any) -> None:
478
+ """Применяет данную конфигурацию антидетекта к Playwright Page или BrowserContext.
479
+
480
+ Args:
481
+ target: Экземпляр Playwright BrowserContext или Page.
482
+ """
483
+ from .core import apply_antidetect_playwright
484
+
485
+ await apply_antidetect_playwright(target, config=self)
486
+
487
+ def apply_to_selenium(self, driver: Any) -> None:
488
+ """Применяет данную конфигурацию антидетекта к Selenium WebDriver.
489
+
490
+ Args:
491
+ driver: Экземпляр Selenium WebDriver.
492
+ """
493
+ from .core import apply_antidetect_selenium
494
+
495
+ apply_antidetect_selenium(driver, config=self)