unrealon 1.1.6__py3-none-any.whl → 2.0.5__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.
- {unrealon-1.1.6.dist-info/licenses → unrealon-2.0.5.dist-info}/LICENSE +1 -1
- unrealon-2.0.5.dist-info/METADATA +491 -0
- unrealon-2.0.5.dist-info/RECORD +128 -0
- {unrealon-1.1.6.dist-info → unrealon-2.0.5.dist-info}/WHEEL +2 -1
- unrealon-2.0.5.dist-info/entry_points.txt +3 -0
- unrealon-2.0.5.dist-info/top_level.txt +3 -0
- unrealon_browser/__init__.py +5 -6
- unrealon_browser/cli/browser_cli.py +18 -9
- unrealon_browser/cli/interactive_mode.py +13 -4
- unrealon_browser/core/browser_manager.py +29 -16
- unrealon_browser/dto/__init__.py +21 -0
- unrealon_browser/dto/bot_detection.py +175 -0
- unrealon_browser/dto/models/config.py +9 -3
- unrealon_browser/managers/__init__.py +1 -1
- unrealon_browser/managers/logger_bridge.py +1 -4
- unrealon_browser/stealth/__init__.py +27 -0
- unrealon_browser/stealth/bypass_techniques.pyc +0 -0
- unrealon_browser/stealth/manager.pyc +0 -0
- unrealon_browser/stealth/nodriver_stealth.pyc +0 -0
- unrealon_browser/stealth/playwright_stealth.pyc +0 -0
- unrealon_browser/stealth/scanner_tester.pyc +0 -0
- unrealon_browser/stealth/undetected_chrome.pyc +0 -0
- unrealon_core/__init__.py +172 -0
- unrealon_core/config/__init__.py +16 -0
- unrealon_core/config/environment.py +151 -0
- unrealon_core/config/urls.py +94 -0
- unrealon_core/enums/__init__.py +24 -0
- unrealon_core/enums/status.py +216 -0
- unrealon_core/enums/types.py +240 -0
- unrealon_core/error_handling/__init__.py +45 -0
- unrealon_core/error_handling/circuit_breaker.py +292 -0
- unrealon_core/error_handling/error_context.py +324 -0
- unrealon_core/error_handling/recovery.py +371 -0
- unrealon_core/error_handling/retry.py +268 -0
- unrealon_core/exceptions/__init__.py +46 -0
- unrealon_core/exceptions/base.py +292 -0
- unrealon_core/exceptions/communication.py +22 -0
- unrealon_core/exceptions/driver.py +11 -0
- unrealon_core/exceptions/proxy.py +11 -0
- unrealon_core/exceptions/task.py +12 -0
- unrealon_core/exceptions/validation.py +17 -0
- unrealon_core/models/__init__.py +79 -0
- unrealon_core/models/arq_context.py +252 -0
- unrealon_core/models/arq_responses.py +125 -0
- unrealon_core/models/base.py +291 -0
- unrealon_core/models/bridge_stats.py +58 -0
- unrealon_core/models/communication.py +39 -0
- unrealon_core/models/connection_stats.py +47 -0
- unrealon_core/models/driver.py +30 -0
- unrealon_core/models/driver_details.py +98 -0
- unrealon_core/models/logging.py +28 -0
- unrealon_core/models/task.py +21 -0
- unrealon_core/models/typed_responses.py +210 -0
- unrealon_core/models/websocket/__init__.py +91 -0
- unrealon_core/models/websocket/base.py +49 -0
- unrealon_core/models/websocket/config.py +200 -0
- unrealon_core/models/websocket/driver.py +215 -0
- unrealon_core/models/websocket/errors.py +138 -0
- unrealon_core/models/websocket/heartbeat.py +100 -0
- unrealon_core/models/websocket/logging.py +261 -0
- unrealon_core/models/websocket/proxy.py +496 -0
- unrealon_core/models/websocket/tasks.py +275 -0
- unrealon_core/models/websocket/utils.py +153 -0
- unrealon_core/models/websocket_session.py +144 -0
- unrealon_core/monitoring/__init__.py +43 -0
- unrealon_core/monitoring/alerts.py +398 -0
- unrealon_core/monitoring/dashboard.py +307 -0
- unrealon_core/monitoring/health_check.py +354 -0
- unrealon_core/monitoring/metrics.py +352 -0
- unrealon_core/utils/__init__.py +11 -0
- unrealon_core/utils/time.py +61 -0
- unrealon_core/version.py +219 -0
- unrealon_driver/__init__.py +90 -51
- unrealon_driver/core_module/__init__.py +34 -0
- unrealon_driver/core_module/base.py +184 -0
- unrealon_driver/core_module/config.py +30 -0
- unrealon_driver/core_module/event_manager.py +127 -0
- unrealon_driver/core_module/protocols.py +98 -0
- unrealon_driver/core_module/registry.py +146 -0
- unrealon_driver/decorators/__init__.py +15 -0
- unrealon_driver/decorators/retry.py +117 -0
- unrealon_driver/decorators/schedule.py +137 -0
- unrealon_driver/decorators/task.py +61 -0
- unrealon_driver/decorators/timing.py +132 -0
- unrealon_driver/driver/__init__.py +20 -0
- unrealon_driver/driver/communication/__init__.py +10 -0
- unrealon_driver/driver/communication/session.py +203 -0
- unrealon_driver/driver/communication/websocket_client.py +205 -0
- unrealon_driver/driver/core/__init__.py +10 -0
- unrealon_driver/driver/core/config.py +175 -0
- unrealon_driver/driver/core/driver.py +221 -0
- unrealon_driver/driver/factory/__init__.py +9 -0
- unrealon_driver/driver/factory/manager_factory.py +130 -0
- unrealon_driver/driver/lifecycle/__init__.py +11 -0
- unrealon_driver/driver/lifecycle/daemon.py +76 -0
- unrealon_driver/driver/lifecycle/initialization.py +97 -0
- unrealon_driver/driver/lifecycle/shutdown.py +48 -0
- unrealon_driver/driver/monitoring/__init__.py +9 -0
- unrealon_driver/driver/monitoring/health.py +63 -0
- unrealon_driver/driver/utilities/__init__.py +10 -0
- unrealon_driver/driver/utilities/logging.py +51 -0
- unrealon_driver/driver/utilities/serialization.py +61 -0
- unrealon_driver/managers/__init__.py +32 -0
- unrealon_driver/managers/base.py +174 -0
- unrealon_driver/managers/browser.py +98 -0
- unrealon_driver/managers/cache.py +116 -0
- unrealon_driver/managers/http.py +107 -0
- unrealon_driver/managers/logger.py +286 -0
- unrealon_driver/managers/proxy.py +99 -0
- unrealon_driver/managers/registry.py +87 -0
- unrealon_driver/managers/threading.py +54 -0
- unrealon_driver/managers/update.py +107 -0
- unrealon_driver/utils/__init__.py +9 -0
- unrealon_driver/utils/time.py +10 -0
- unrealon-1.1.6.dist-info/METADATA +0 -625
- unrealon-1.1.6.dist-info/RECORD +0 -55
- unrealon-1.1.6.dist-info/entry_points.txt +0 -9
- unrealon_browser/managers/stealth.py +0 -388
- unrealon_driver/README.md +0 -0
- unrealon_driver/exceptions.py +0 -33
- unrealon_driver/html_analyzer/__init__.py +0 -32
- unrealon_driver/html_analyzer/cleaner.py +0 -657
- unrealon_driver/html_analyzer/config.py +0 -64
- unrealon_driver/html_analyzer/manager.py +0 -247
- unrealon_driver/html_analyzer/models.py +0 -115
- unrealon_driver/html_analyzer/websocket_analyzer.py +0 -157
- unrealon_driver/models/__init__.py +0 -31
- unrealon_driver/models/websocket.py +0 -98
- unrealon_driver/parser/__init__.py +0 -36
- unrealon_driver/parser/cli_manager.py +0 -142
- unrealon_driver/parser/daemon_manager.py +0 -403
- unrealon_driver/parser/managers/__init__.py +0 -25
- unrealon_driver/parser/managers/config.py +0 -293
- unrealon_driver/parser/managers/error.py +0 -412
- unrealon_driver/parser/managers/result.py +0 -321
- unrealon_driver/parser/parser_manager.py +0 -458
- unrealon_driver/smart_logging/__init__.py +0 -24
- unrealon_driver/smart_logging/models.py +0 -44
- unrealon_driver/smart_logging/smart_logger.py +0 -406
- unrealon_driver/smart_logging/unified_logger.py +0 -525
- unrealon_driver/websocket/__init__.py +0 -31
- unrealon_driver/websocket/client.py +0 -249
- unrealon_driver/websocket/config.py +0 -188
- unrealon_driver/websocket/manager.py +0 -90
|
@@ -1,388 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Stealth Manager - Anti-detection system for browser automation
|
|
3
|
-
Layer 1: Advanced stealth capabilities inspired by unrealparser
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import logging
|
|
7
|
-
import asyncio
|
|
8
|
-
from typing import Dict, Any, Optional, List
|
|
9
|
-
from playwright.async_api import Page, BrowserContext
|
|
10
|
-
|
|
11
|
-
# CRITICAL REQUIREMENTS COMPLIANCE - NO INLINE IMPORTS!
|
|
12
|
-
from playwright_stealth import stealth, Stealth
|
|
13
|
-
|
|
14
|
-
logger = logging.getLogger(__name__)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class StealthManager:
|
|
18
|
-
"""
|
|
19
|
-
Advanced anti-detection system for browser automation
|
|
20
|
-
|
|
21
|
-
Layer 1: Stealth capabilities
|
|
22
|
-
- Playwright-stealth integration
|
|
23
|
-
- WebDriver property removal
|
|
24
|
-
- Bot detection testing
|
|
25
|
-
- Stealth arguments optimization
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
def __init__(self, logger_bridge=None):
|
|
29
|
-
"""Initialize stealth manager"""
|
|
30
|
-
self.stealth_applied = False
|
|
31
|
-
self.test_results: Optional[Dict[str, Any]] = None
|
|
32
|
-
self.logger_bridge = logger_bridge
|
|
33
|
-
|
|
34
|
-
def get_stealth_args(self) -> List[str]:
|
|
35
|
-
"""
|
|
36
|
-
Get browser launch arguments for stealth mode
|
|
37
|
-
Based on unrealparser's proven stealth arguments
|
|
38
|
-
"""
|
|
39
|
-
return [
|
|
40
|
-
# Minimal stealth arguments from working unrealparser code
|
|
41
|
-
"--disable-blink-features=AutomationControlled", # Remove navigator.webdriver
|
|
42
|
-
"--no-sandbox", # Required for container environments
|
|
43
|
-
"--disable-dev-shm-usage", # Fix memory issues in containers
|
|
44
|
-
# Additional safe arguments for better stealth
|
|
45
|
-
"--disable-extensions",
|
|
46
|
-
"--no-first-run",
|
|
47
|
-
"--no-default-browser-check",
|
|
48
|
-
]
|
|
49
|
-
|
|
50
|
-
# private warpper for logger with if self.logger_bridge
|
|
51
|
-
def _logger(self, message: str, level: str = "info") -> None:
|
|
52
|
-
if self.logger_bridge:
|
|
53
|
-
if level == "info":
|
|
54
|
-
self.logger_bridge.log_info(message)
|
|
55
|
-
elif level == "error":
|
|
56
|
-
self.logger_bridge.log_error(message)
|
|
57
|
-
elif level == "warning":
|
|
58
|
-
self.logger_bridge.log_warning(message)
|
|
59
|
-
else:
|
|
60
|
-
self.logger_bridge.log_info(message)
|
|
61
|
-
else:
|
|
62
|
-
if level == "info":
|
|
63
|
-
logger.info(message)
|
|
64
|
-
elif level == "error":
|
|
65
|
-
logger.error(message)
|
|
66
|
-
elif level == "warning":
|
|
67
|
-
logger.warning(message)
|
|
68
|
-
else:
|
|
69
|
-
logger.info(message)
|
|
70
|
-
|
|
71
|
-
async def apply_stealth(self, page: Page) -> bool:
|
|
72
|
-
"""
|
|
73
|
-
Apply stealth measures to page
|
|
74
|
-
Combines multiple anti-detection techniques
|
|
75
|
-
"""
|
|
76
|
-
try:
|
|
77
|
-
self._logger("🥷 Applying stealth measures...", "info")
|
|
78
|
-
|
|
79
|
-
# 1. Apply playwright-stealth if available
|
|
80
|
-
stealth_applied = await self._apply_playwright_stealth(page)
|
|
81
|
-
|
|
82
|
-
# 2. Remove webdriver property
|
|
83
|
-
await self._remove_webdriver_property(page)
|
|
84
|
-
|
|
85
|
-
# 3. Apply additional stealth scripts
|
|
86
|
-
await self._apply_custom_stealth_scripts(page)
|
|
87
|
-
|
|
88
|
-
# 4. Set realistic properties
|
|
89
|
-
await self._set_realistic_properties(page)
|
|
90
|
-
|
|
91
|
-
self.stealth_applied = True
|
|
92
|
-
self._logger("✅ Stealth measures applied successfully", "info")
|
|
93
|
-
|
|
94
|
-
return True
|
|
95
|
-
|
|
96
|
-
except Exception as e:
|
|
97
|
-
self._logger(f"❌ Failed to apply stealth measures: {e}", "error")
|
|
98
|
-
self.stealth_applied = False
|
|
99
|
-
return False
|
|
100
|
-
|
|
101
|
-
async def _apply_playwright_stealth(self, page: Page) -> bool:
|
|
102
|
-
"""Apply playwright-stealth with custom config"""
|
|
103
|
-
try:
|
|
104
|
-
# 🔥 WEBDRIVER ONLY CONFIG: Only remove webdriver, nothing else!
|
|
105
|
-
stealth_config = Stealth(
|
|
106
|
-
navigator_webdriver=True, # ONLY webdriver removal
|
|
107
|
-
chrome_runtime=False, # DISABLE - we do it ourselves
|
|
108
|
-
navigator_languages=False, # DISABLE - we do it ourselves
|
|
109
|
-
navigator_permissions=False, # DISABLE - we do it ourselves
|
|
110
|
-
navigator_plugins=False, # DISABLE - we do it ourselves
|
|
111
|
-
webgl_vendor=False, # DISABLE - we do it ourselves
|
|
112
|
-
chrome_app=False, # DISABLE
|
|
113
|
-
chrome_csi=False, # DISABLE
|
|
114
|
-
chrome_load_times=False, # DISABLE
|
|
115
|
-
iframe_content_window=False, # DISABLE
|
|
116
|
-
media_codecs=False, # DISABLE
|
|
117
|
-
navigator_user_agent=False, # DISABLE
|
|
118
|
-
navigator_vendor=False, # DISABLE
|
|
119
|
-
navigator_platform=False, # DISABLE
|
|
120
|
-
hairline=False, # DISABLE
|
|
121
|
-
sec_ch_ua=False, # DISABLE
|
|
122
|
-
navigator_hardware_concurrency=False, # DISABLE
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
await stealth(page, config=stealth_config)
|
|
126
|
-
self._logger("✅ Playwright-stealth applied with CUSTOM config", "info")
|
|
127
|
-
return True
|
|
128
|
-
except Exception as e:
|
|
129
|
-
self._logger(f"❌ playwright-stealth failed: {e}", "error")
|
|
130
|
-
return False
|
|
131
|
-
|
|
132
|
-
async def _remove_webdriver_property(self, page: Page) -> None:
|
|
133
|
-
"""Remove navigator.webdriver property - HANDLED BY PLAYWRIGHT-STEALTH"""
|
|
134
|
-
# 🔥 REDUNDANT: playwright-stealth already does this with webdriver=True
|
|
135
|
-
self._logger("✅ WebDriver property removal handled by playwright-stealth", "info")
|
|
136
|
-
|
|
137
|
-
async def _apply_custom_stealth_scripts(self, page: Page) -> None:
|
|
138
|
-
"""Apply custom stealth scripts"""
|
|
139
|
-
# Create proper chrome object (bot.sannysoft.com expects this!)
|
|
140
|
-
chrome_runtime_script = """
|
|
141
|
-
// Create realistic window.chrome object
|
|
142
|
-
if (!window.chrome) {
|
|
143
|
-
window.chrome = {
|
|
144
|
-
app: {
|
|
145
|
-
isInstalled: false,
|
|
146
|
-
},
|
|
147
|
-
runtime: {
|
|
148
|
-
onConnect: {
|
|
149
|
-
addListener: function() {},
|
|
150
|
-
hasListener: function() { return false; },
|
|
151
|
-
removeListener: function() {},
|
|
152
|
-
},
|
|
153
|
-
onMessage: {
|
|
154
|
-
addListener: function() {},
|
|
155
|
-
hasListener: function() { return false; },
|
|
156
|
-
removeListener: function() {},
|
|
157
|
-
},
|
|
158
|
-
connect: function() { return {}; },
|
|
159
|
-
sendMessage: function() {},
|
|
160
|
-
},
|
|
161
|
-
storage: {
|
|
162
|
-
local: {
|
|
163
|
-
get: function() {},
|
|
164
|
-
set: function() {},
|
|
165
|
-
remove: function() {},
|
|
166
|
-
clear: function() {},
|
|
167
|
-
},
|
|
168
|
-
sync: {
|
|
169
|
-
get: function() {},
|
|
170
|
-
set: function() {},
|
|
171
|
-
remove: function() {},
|
|
172
|
-
clear: function() {},
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
tabs: {
|
|
176
|
-
create: function() {},
|
|
177
|
-
query: function() {},
|
|
178
|
-
update: function() {},
|
|
179
|
-
},
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
"""
|
|
183
|
-
await page.add_init_script(chrome_runtime_script)
|
|
184
|
-
|
|
185
|
-
# Override permissions
|
|
186
|
-
permissions_script = """
|
|
187
|
-
const originalQuery = window.navigator.permissions.query;
|
|
188
|
-
window.navigator.permissions.query = (parameters) => (
|
|
189
|
-
parameters.name === 'notifications' ?
|
|
190
|
-
Promise.resolve({ state: Notification.permission }) :
|
|
191
|
-
originalQuery(parameters)
|
|
192
|
-
);
|
|
193
|
-
"""
|
|
194
|
-
await page.add_init_script(permissions_script)
|
|
195
|
-
|
|
196
|
-
self._logger("✅ Custom stealth scripts applied", "info")
|
|
197
|
-
|
|
198
|
-
async def _set_realistic_properties(self, page: Page) -> None:
|
|
199
|
-
"""Set realistic browser properties"""
|
|
200
|
-
realistic_script = """
|
|
201
|
-
// Set realistic hardwareConcurrency
|
|
202
|
-
Object.defineProperty(navigator, 'hardwareConcurrency', {
|
|
203
|
-
get: () => 4,
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
// Set realistic deviceMemory
|
|
207
|
-
Object.defineProperty(navigator, 'deviceMemory', {
|
|
208
|
-
get: () => 8,
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
// Set realistic connection
|
|
212
|
-
Object.defineProperty(navigator, 'connection', {
|
|
213
|
-
get: () => ({
|
|
214
|
-
effectiveType: '4g',
|
|
215
|
-
rtt: 50,
|
|
216
|
-
downlink: 10,
|
|
217
|
-
}),
|
|
218
|
-
});
|
|
219
|
-
"""
|
|
220
|
-
await page.add_init_script(realistic_script)
|
|
221
|
-
self._logger("✅ Realistic properties set", "info")
|
|
222
|
-
|
|
223
|
-
async def test_stealth_on_sannysoft(self, browser_manager) -> Dict[str, Any]:
|
|
224
|
-
"""
|
|
225
|
-
Test stealth effectiveness on bot.sannysoft.com
|
|
226
|
-
Based on unrealparser's stealth testing approach
|
|
227
|
-
"""
|
|
228
|
-
if not browser_manager or not browser_manager.page:
|
|
229
|
-
return {
|
|
230
|
-
"success": False,
|
|
231
|
-
"error": "Browser manager or page not available",
|
|
232
|
-
"skipped": True,
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
try:
|
|
236
|
-
self._logger("🧪 Testing stealth on bot.sannysoft.com...", "info")
|
|
237
|
-
|
|
238
|
-
# Navigate to test page
|
|
239
|
-
test_url = "https://bot.sannysoft.com/"
|
|
240
|
-
result = await browser_manager.navigate_async(test_url, wait_for="body")
|
|
241
|
-
|
|
242
|
-
if not result["success"]:
|
|
243
|
-
return {
|
|
244
|
-
"success": False,
|
|
245
|
-
"error": f"Failed to load test page: {result['error']}",
|
|
246
|
-
"skipped": False,
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
# Wait for page to fully load
|
|
250
|
-
await asyncio.sleep(3)
|
|
251
|
-
|
|
252
|
-
# Extract test results
|
|
253
|
-
page_content = await browser_manager.get_page_content_async()
|
|
254
|
-
if not page_content:
|
|
255
|
-
return {
|
|
256
|
-
"success": False,
|
|
257
|
-
"error": "Failed to get page content",
|
|
258
|
-
"skipped": False,
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
# Parse results using simple text analysis
|
|
262
|
-
test_results = await self._parse_sannysoft_results(page_content)
|
|
263
|
-
|
|
264
|
-
# Store results
|
|
265
|
-
self.test_results = test_results
|
|
266
|
-
|
|
267
|
-
self._logger("✅ Stealth test completed", "info")
|
|
268
|
-
self._logger(f" Detection score: {test_results.get('detection_score', 'Unknown')}", "info")
|
|
269
|
-
self._logger(f"Tests passed: {test_results.get('tests_passed', 0)}/{test_results.get('total_tests', 0)}")
|
|
270
|
-
|
|
271
|
-
return {
|
|
272
|
-
"success": True,
|
|
273
|
-
"results": test_results,
|
|
274
|
-
"error": None,
|
|
275
|
-
"skipped": False,
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
except Exception as e:
|
|
279
|
-
self._logger(f"❌ Stealth test failed: {e}", "error")
|
|
280
|
-
return {
|
|
281
|
-
"success": False,
|
|
282
|
-
"error": str(e),
|
|
283
|
-
"skipped": False,
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
async def _parse_sannysoft_results(self, content: str) -> Dict[str, Any]:
|
|
287
|
-
"""Parse sannysoft test results from page content"""
|
|
288
|
-
results = {
|
|
289
|
-
"webdriver_detected": "webdriver" in content.lower(),
|
|
290
|
-
"chrome_detected": "chrome" in content.lower(),
|
|
291
|
-
"permissions_detected": "permissions" in content.lower(),
|
|
292
|
-
"plugins_detected": "plugins" in content.lower(),
|
|
293
|
-
"languages_detected": "languages" in content.lower(),
|
|
294
|
-
"total_tests": 0,
|
|
295
|
-
"tests_passed": 0,
|
|
296
|
-
"detection_score": "Unknown",
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
# Count basic detection indicators
|
|
300
|
-
detection_indicators = [
|
|
301
|
-
results["webdriver_detected"],
|
|
302
|
-
results["chrome_detected"],
|
|
303
|
-
results["permissions_detected"],
|
|
304
|
-
results["plugins_detected"],
|
|
305
|
-
results["languages_detected"],
|
|
306
|
-
]
|
|
307
|
-
|
|
308
|
-
results["total_tests"] = len(detection_indicators)
|
|
309
|
-
results["tests_passed"] = len([x for x in detection_indicators if not x])
|
|
310
|
-
|
|
311
|
-
# Calculate detection score
|
|
312
|
-
if results["total_tests"] > 0:
|
|
313
|
-
pass_rate = results["tests_passed"] / results["total_tests"]
|
|
314
|
-
if pass_rate >= 0.8:
|
|
315
|
-
results["detection_score"] = "Excellent"
|
|
316
|
-
elif pass_rate >= 0.6:
|
|
317
|
-
results["detection_score"] = "Good"
|
|
318
|
-
elif pass_rate >= 0.4:
|
|
319
|
-
results["detection_score"] = "Fair"
|
|
320
|
-
else:
|
|
321
|
-
results["detection_score"] = "Poor"
|
|
322
|
-
|
|
323
|
-
return results
|
|
324
|
-
|
|
325
|
-
def get_stealth_status(self) -> Dict[str, Any]:
|
|
326
|
-
"""Get current stealth status and test results"""
|
|
327
|
-
return {
|
|
328
|
-
"stealth_applied": self.stealth_applied,
|
|
329
|
-
"test_results": self.test_results,
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
def print_stealth_status(self) -> None:
|
|
333
|
-
"""Print current stealth status"""
|
|
334
|
-
status = self.get_stealth_status()
|
|
335
|
-
|
|
336
|
-
self._logger("\n🥷 Stealth Status:", "info")
|
|
337
|
-
self._logger(f"Applied: {status['stealth_applied']}", "info")
|
|
338
|
-
|
|
339
|
-
if status["test_results"]:
|
|
340
|
-
results = status["test_results"]
|
|
341
|
-
self._logger(f" Last test score: {results.get('detection_score', 'Unknown')}", "info")
|
|
342
|
-
self._logger(f"Tests passed: {results.get('tests_passed', 0)}/{results.get('total_tests', 0)}")
|
|
343
|
-
|
|
344
|
-
async def apply_stealth_to_context(self, context: BrowserContext) -> bool:
|
|
345
|
-
"""Apply stealth measures to entire browser context"""
|
|
346
|
-
try:
|
|
347
|
-
self._logger("🥷 Applying stealth to browser context...", "info")
|
|
348
|
-
|
|
349
|
-
# SIMPLE OLD STYLE SCRIPT - exactly like working unrealparser!
|
|
350
|
-
stealth_script = """
|
|
351
|
-
if (navigator.webdriver !== undefined) {
|
|
352
|
-
delete Object.getPrototypeOf(navigator).webdriver;
|
|
353
|
-
}
|
|
354
|
-
"""
|
|
355
|
-
|
|
356
|
-
await context.add_init_script(stealth_script)
|
|
357
|
-
self._logger("✅ Context stealth script applied", "info")
|
|
358
|
-
|
|
359
|
-
return True
|
|
360
|
-
|
|
361
|
-
except Exception as e:
|
|
362
|
-
self._logger(f"❌ Failed to apply context stealth: {e}", "error")
|
|
363
|
-
return False
|
|
364
|
-
|
|
365
|
-
async def apply_webdriver_removal(self, context) -> bool:
|
|
366
|
-
"""
|
|
367
|
-
Remove navigator.webdriver property from context - OLD STYLE method like unrealparser
|
|
368
|
-
|
|
369
|
-
Args:
|
|
370
|
-
context: Playwright browser context
|
|
371
|
-
|
|
372
|
-
Returns:
|
|
373
|
-
True if successful, False otherwise
|
|
374
|
-
"""
|
|
375
|
-
try:
|
|
376
|
-
# Remove navigator.webdriver property before page creation - EXACTLY like old unrealparser
|
|
377
|
-
await context.add_init_script(
|
|
378
|
-
"""
|
|
379
|
-
if (navigator.webdriver !== undefined) {
|
|
380
|
-
delete Object.getPrototypeOf(navigator).webdriver;
|
|
381
|
-
}
|
|
382
|
-
"""
|
|
383
|
-
)
|
|
384
|
-
self._logger("✅ Webdriver removal script applied (OLD STYLE)", "info")
|
|
385
|
-
return True
|
|
386
|
-
except Exception as e:
|
|
387
|
-
self._logger(f"❌ Error applying webdriver removal: {e}", "error")
|
|
388
|
-
return False
|
unrealon_driver/README.md
DELETED
|
File without changes
|
unrealon_driver/exceptions.py
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
UnrealOn Driver exceptions
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class ParserError(Exception):
|
|
7
|
-
"""Base exception for parser errors"""
|
|
8
|
-
|
|
9
|
-
pass
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class BrowserError(ParserError):
|
|
13
|
-
"""Browser-related errors"""
|
|
14
|
-
|
|
15
|
-
pass
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class HTMLCleaningError(ParserError):
|
|
19
|
-
"""HTML cleaning errors"""
|
|
20
|
-
|
|
21
|
-
pass
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class ConfigurationError(ParserError):
|
|
25
|
-
"""Configuration errors"""
|
|
26
|
-
|
|
27
|
-
pass
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class ConnectionError(ParserError):
|
|
31
|
-
"""Connection errors"""
|
|
32
|
-
|
|
33
|
-
pass
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
HTML Analyzer module for unrealon_driver.
|
|
3
|
-
|
|
4
|
-
Provides intelligent HTML processing, cleaning, and analysis with WebSocket communication.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from .manager import HTMLAnalyzer, create_html_analyzer
|
|
8
|
-
from .config import HTMLAnalyzerConfig, HTMLCleaningConfig
|
|
9
|
-
from .cleaner import HTMLCleaner, HTMLCleaningStats
|
|
10
|
-
from .websocket_analyzer import WebSocketHTMLAnalyzer
|
|
11
|
-
from .models import HTMLAnalysisResult, HTMLParseResult, HTMLAnalyzerStats, HTMLAnalysisRequest, HTMLParseRequest, HTMLAnalyzerError, HTMLCleaningError, HTMLAnalysisError, WebSocketAnalysisError
|
|
12
|
-
|
|
13
|
-
__all__ = [
|
|
14
|
-
"HTMLAnalyzer",
|
|
15
|
-
"HTMLAnalyzerConfig",
|
|
16
|
-
"HTMLCleaningConfig",
|
|
17
|
-
"HTMLCleaningStats",
|
|
18
|
-
"HTMLCleaner",
|
|
19
|
-
"WebSocketHTMLAnalyzer",
|
|
20
|
-
"create_html_analyzer",
|
|
21
|
-
# Models
|
|
22
|
-
"HTMLAnalysisResult",
|
|
23
|
-
"HTMLParseResult",
|
|
24
|
-
"HTMLAnalyzerStats",
|
|
25
|
-
"HTMLAnalysisRequest",
|
|
26
|
-
"HTMLParseRequest",
|
|
27
|
-
# Exceptions
|
|
28
|
-
"HTMLAnalyzerError",
|
|
29
|
-
"HTMLCleaningError",
|
|
30
|
-
"HTMLAnalysisError",
|
|
31
|
-
"WebSocketAnalysisError",
|
|
32
|
-
]
|