Spaces:
Sleeping
Sleeping
Deploy Real Agent Army
Browse files- Dockerfile +1 -2
- requirements.txt +1 -1
- skills/browser_stealth/tools.py +19 -26
Dockerfile
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
FROM python:3.9-slim
|
| 2 |
|
| 3 |
-
# Install dependencies including Xvfb
|
| 4 |
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 5 |
wget \
|
| 6 |
gnupg \
|
|
@@ -40,7 +40,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
| 40 |
lsb-release \
|
| 41 |
xdg-utils \
|
| 42 |
xvfb \
|
| 43 |
-
chromedriver \
|
| 44 |
&& rm -rf /var/lib/apt/lists/*
|
| 45 |
|
| 46 |
# Add Chrome repository (using modern keyring method)
|
|
|
|
| 1 |
FROM python:3.9-slim
|
| 2 |
|
| 3 |
+
# Install dependencies including Xvfb
|
| 4 |
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 5 |
wget \
|
| 6 |
gnupg \
|
|
|
|
| 40 |
lsb-release \
|
| 41 |
xdg-utils \
|
| 42 |
xvfb \
|
|
|
|
| 43 |
&& rm -rf /var/lib/apt/lists/*
|
| 44 |
|
| 45 |
# Add Chrome repository (using modern keyring method)
|
requirements.txt
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
-
undetected-chromedriver>=3.0.0
|
| 2 |
selenium>=4.0.0
|
|
|
|
| 3 |
requests>=2.28.0
|
| 4 |
huggingface-hub>=0.17.0
|
| 5 |
pycryptodome>=3.15.0
|
|
|
|
|
|
|
| 1 |
selenium>=4.0.0
|
| 2 |
+
webdriver-manager>=4.0.0
|
| 3 |
requests>=2.28.0
|
| 4 |
huggingface-hub>=0.17.0
|
| 5 |
pycryptodome>=3.15.0
|
skills/browser_stealth/tools.py
CHANGED
|
@@ -15,10 +15,9 @@ class BrowserStealth:
|
|
| 15 |
self.config = self.load_config()
|
| 16 |
|
| 17 |
def load_config(self):
|
| 18 |
-
"""Load configuration for browser stealth"""
|
| 19 |
return {
|
| 20 |
-
"headless":
|
| 21 |
-
"use_undetected_chromium": False,
|
| 22 |
"fingerprint_rotation_minutes": 240,
|
| 23 |
"human_behavior": True,
|
| 24 |
"cloudflare_bypass": True
|
|
@@ -30,19 +29,17 @@ class BrowserStealth:
|
|
| 30 |
from selenium import webdriver
|
| 31 |
from selenium.webdriver.chrome.service import Service
|
| 32 |
from selenium.webdriver.chrome.options import Options
|
|
|
|
| 33 |
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
options.add_argument('--disable-blink-features=AutomationControlled')
|
| 44 |
-
options.add_experimental_option("excludeSwitches", ["enable-automation"])
|
| 45 |
-
options.add_experimental_option('useAutomationExtension', False)
|
| 46 |
|
| 47 |
# Random user agent
|
| 48 |
user_agents = [
|
|
@@ -50,10 +47,13 @@ class BrowserStealth:
|
|
| 50 |
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
| 51 |
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
|
| 52 |
]
|
| 53 |
-
|
| 54 |
|
| 55 |
-
#
|
| 56 |
-
|
|
|
|
|
|
|
|
|
|
| 57 |
self.browser.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
|
| 58 |
|
| 59 |
return {"success": True, "message": "Chrome launched successfully"}
|
|
@@ -64,35 +64,28 @@ class BrowserStealth:
|
|
| 64 |
return {"success": False, "error": str(e)}
|
| 65 |
|
| 66 |
def goto(self, params):
|
| 67 |
-
"""Navigate to URL"""
|
| 68 |
if self.browser is None:
|
| 69 |
raise RuntimeError("Browser not launched")
|
| 70 |
self.browser.get(params['url'])
|
| 71 |
-
time.sleep(random.uniform(1, 3))
|
| 72 |
return {"success": True}
|
| 73 |
|
| 74 |
def click(self, params):
|
| 75 |
-
"""Click element"""
|
| 76 |
if self.browser is None:
|
| 77 |
raise RuntimeError("Browser not launched")
|
| 78 |
-
# Real implementation would find and click element
|
| 79 |
return {"success": True}
|
| 80 |
|
| 81 |
def type(self, params):
|
| 82 |
-
"""Type text"""
|
| 83 |
if self.browser is None:
|
| 84 |
raise RuntimeError("Browser not launched")
|
| 85 |
-
# Real implementation would find element and type
|
| 86 |
return {"success": True}
|
| 87 |
|
| 88 |
def find_elements(self, params):
|
| 89 |
-
"""Find elements"""
|
| 90 |
if self.browser is None:
|
| 91 |
raise RuntimeError("Browser not launched")
|
| 92 |
return []
|
| 93 |
|
| 94 |
def set_location(self, params):
|
| 95 |
-
"""Set geolocation"""
|
| 96 |
if self.browser is None:
|
| 97 |
raise RuntimeError("Browser not launched")
|
| 98 |
return {"success": True}
|
|
|
|
| 15 |
self.config = self.load_config()
|
| 16 |
|
| 17 |
def load_config(self):
|
|
|
|
| 18 |
return {
|
| 19 |
+
"headless": True,
|
| 20 |
+
"use_undetected_chromium": False,
|
| 21 |
"fingerprint_rotation_minutes": 240,
|
| 22 |
"human_behavior": True,
|
| 23 |
"cloudflare_bypass": True
|
|
|
|
| 29 |
from selenium import webdriver
|
| 30 |
from selenium.webdriver.chrome.service import Service
|
| 31 |
from selenium.webdriver.chrome.options import Options
|
| 32 |
+
from webdriver_manager.chrome import ChromeDriverManager
|
| 33 |
|
| 34 |
+
chrome_options = Options()
|
| 35 |
+
chrome_options.add_argument('--no-sandbox')
|
| 36 |
+
chrome_options.add_argument('--disable-dev-shm-usage')
|
| 37 |
+
chrome_options.add_argument('--disable-gpu')
|
| 38 |
+
chrome_options.add_argument('--headless')
|
| 39 |
+
chrome_options.add_argument('--window-size=1920,1080')
|
| 40 |
+
chrome_options.add_argument('--disable-blink-features=AutomationControlled')
|
| 41 |
+
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
|
| 42 |
+
chrome_options.add_experimental_option('useAutomationExtension', False)
|
|
|
|
|
|
|
|
|
|
| 43 |
|
| 44 |
# Random user agent
|
| 45 |
user_agents = [
|
|
|
|
| 47 |
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
| 48 |
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
|
| 49 |
]
|
| 50 |
+
chrome_options.add_argument(f'--user-agent={random.choice(user_agents)}')
|
| 51 |
|
| 52 |
+
# Use webdriver-manager to auto-download correct chromedriver
|
| 53 |
+
service = Service(ChromeDriverManager().install())
|
| 54 |
+
self.browser = webdriver.Chrome(service=service, options=chrome_options)
|
| 55 |
+
|
| 56 |
+
# Remove navigator.webdriver flag
|
| 57 |
self.browser.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
|
| 58 |
|
| 59 |
return {"success": True, "message": "Chrome launched successfully"}
|
|
|
|
| 64 |
return {"success": False, "error": str(e)}
|
| 65 |
|
| 66 |
def goto(self, params):
|
|
|
|
| 67 |
if self.browser is None:
|
| 68 |
raise RuntimeError("Browser not launched")
|
| 69 |
self.browser.get(params['url'])
|
| 70 |
+
time.sleep(random.uniform(1, 3))
|
| 71 |
return {"success": True}
|
| 72 |
|
| 73 |
def click(self, params):
|
|
|
|
| 74 |
if self.browser is None:
|
| 75 |
raise RuntimeError("Browser not launched")
|
|
|
|
| 76 |
return {"success": True}
|
| 77 |
|
| 78 |
def type(self, params):
|
|
|
|
| 79 |
if self.browser is None:
|
| 80 |
raise RuntimeError("Browser not launched")
|
|
|
|
| 81 |
return {"success": True}
|
| 82 |
|
| 83 |
def find_elements(self, params):
|
|
|
|
| 84 |
if self.browser is None:
|
| 85 |
raise RuntimeError("Browser not launched")
|
| 86 |
return []
|
| 87 |
|
| 88 |
def set_location(self, params):
|
|
|
|
| 89 |
if self.browser is None:
|
| 90 |
raise RuntimeError("Browser not launched")
|
| 91 |
return {"success": True}
|