Undetectable browser automation library with stealth features, closed Shadow DOM access, and antibot bypass capabilities
Project description
🛡️ GDNox
Undetectable Browser Automation Library
Stealth browser automation with closed Shadow DOM access and antibot bypass capabilities
Features • Installation • Quick Start • Stealth Patches • Bypassed Antibots • API • 📚 Documentation
✨ Features
| Feature | Description |
|---|---|
| 🔌 Direct CDP | Pure Chrome DevTools Protocol - no WebDriver detection |
| 👻 Shadow DOM Access | Pierce closed Shadow Roots (impossible with Selenium/Playwright) |
| 🧠 Human Behavior | Bezier curve mouse movements, realistic typing delays |
| 🎭 Fingerprint Spoofing | Canvas, WebGL, AudioContext randomization |
| 📜 History Seeding | Pre-populate browsing history and cookies |
| 🌐 Proxy Support | Full proxy support with authentication |
| ⚡ Async First | Built on asyncio for high performance |
| 🔄 Auto OOP Iframe Handling | Automatically attach to cross-origin iframes |
📦 Installation
pip install gdnox
Or with Poetry:
poetry add gdnox
Requirements
- Python 3.10+
- Google Chrome or Chromium installed
🚀 Quick Start
import asyncio
from GDNox import Browser
async def main():
async with Browser() as browser:
tab = await browser.new_tab()
await tab.goto("https://example.com")
# Find elements - automatically pierces Shadow DOM!
element = await tab.find("h1")
print(await element.text())
# Human-like click
button = await tab.find("button")
await button.click() # Uses realistic mouse movement
# Take screenshot
await tab.screenshot("screenshot.png")
asyncio.run(main())
Clicking Cloudflare Turnstile
import asyncio
from GDNox import Browser
async def solve_turnstile():
async with Browser() as browser:
tab = await browser.new_tab()
await tab.goto("https://example.com/protected-page")
# Wait for iframe to load
await tab.sleep(3)
# GDNox automatically finds elements inside cross-origin iframes!
checkbox = await tab.find("input[type='checkbox']")
if checkbox:
await checkbox.click()
print("✅ Clicked Turnstile checkbox!")
asyncio.run(solve_turnstile())
🛡️ Stealth Patches
GDNox applies multiple patches to avoid bot detection:
Navigator Patches
| Patch | Description |
|---|---|
navigator.webdriver |
Removed/undefined (not false) |
navigator.plugins |
Spoofed with realistic Chrome plugins |
navigator.languages |
Configurable language array |
navigator.permissions |
Patched query() for notifications |
Browser Object Patches
| Patch | Description |
|---|---|
window.chrome |
Complete Chrome runtime object simulation |
chrome.runtime |
Mocked connect() and sendMessage() |
chrome.csi |
Mocked timing function |
chrome.loadTimes |
Mocked page timing function |
Fingerprint Randomization
| Patch | Description |
|---|---|
| Canvas | Noise injection on getImageData() and toDataURL() |
| WebGL | Spoofed UNMASKED_VENDOR_WEBGL and UNMASKED_RENDERER_WEBGL |
| WebGL2 | Same patches for WebGL2 context |
| Plugins Array | Realistic PDF plugins when empty |
Profile Seeding
| Feature | Description |
|---|---|
| Browser History | Pre-populated with ~40 popular sites (US + BR) |
| Cookies | Realistic tracking cookies for major sites |
| Local Storage | Pre-seeded storage for common sites |
Runtime Evasion
| Technique | Description |
|---|---|
| Isolated Worlds | JavaScript execution in isolated contexts |
| No Runtime.enable | Avoids detectable CDP domain activation |
| No Console.enable | Prevents console leak detection |
🎯 Bypassed Antibots
GDNox has been tested against the following antibot solutions:
| Antibot | Status | Notes |
|---|---|---|
| Cloudflare Turnstile | ✅ Bypassed | Full shadow DOM + iframe support |
| Cloudflare Challenge | ✅ Bypassed | Stealth patches pass checks |
| DataDome | ✅ Bypassed | Fingerprint randomization works |
| PerimeterX (HUMAN) | ✅ Bypassed | Human behavior simulation |
| Akamai Bot Manager | ✅ Bypassed | Sensor data passes validation |
| Kasada | ⚠️ Partial | May require additional configuration |
| Shape Security | ⚠️ Partial | Depends on site implementation |
| reCAPTCHA v2 | ⚠️ Detection only | Checkbox can be clicked, solving needs additional service |
| hCaptcha | ⚠️ Detection only | Same as reCAPTCHA |
Shadow Root Access
GDNox can access closed Shadow DOMs - something impossible with standard automation tools:
# This works even inside closed shadow roots!
checkbox = await tab.find("input[type='checkbox']")
How it works:
- Uses
DOM.getDocumentwithpierce: true - Automatically traverses all shadow roots
- Resolves elements via
DOM.resolveNodewithbackendNodeId
📖 API Reference
Browser
Browser(
chrome_path=None, # Path to Chrome (auto-detected)
headless=False, # Headless mode (not recommended for stealth)
user_data_dir=None, # Profile directory
proxy=None, # Proxy URL (http://user:pass@host:port)
extra_args=[], # Additional Chrome arguments
auto_seed=True, # Auto-seed history/cookies
)
Tab
await tab.goto(url, wait_until="load", timeout=30.0)
await tab.find(selector, timeout=5.0)
await tab.find_all(selector)
await tab.wait_for_selector(selector, visible=False, timeout=30.0)
await tab.wait_for_function(expression, timeout=30.0)
await tab.race(selectors=[], js_functions=[], timeout=30.0)
await tab.evaluate(expression)
await tab.screenshot(path)
await tab.content()
await tab.sleep(seconds)
Element
await element.click(human_like=True)
await element.type(text, human_like=True)
await element.text()
await element.inner_html()
await element.get_attribute(name)
await element.set_attribute(name, value)
await element.is_visible()
await element.scroll_into_view()
await element.focus()
Network Interception
network = tab.network
@network.on('request')
async def on_request(request):
print(f"Request: {request.url}")
@network.on('response')
async def on_response(response):
body = await response.body()
print(f"Response: {len(body)} bytes")
@network.intercept('*api.example.com*')
async def intercept_api(request):
if '/blocked' in request.url:
await request.abort()
else:
await request.continue_()
🔧 Advanced Usage
Custom Fingerprint
from GDNox import Browser
from GDNox.stealth import FingerprintSpoofer
async with Browser() as browser:
tab = await browser.new_tab()
# Custom WebGL fingerprint
spoofer = FingerprintSpoofer(
tab._cdp,
noise_level=5,
language="en-US",
webgl_config=("Intel Inc.", "Intel Iris OpenGL Engine"),
)
await spoofer.apply(tab._frame_id)
Human-like Mouse
from GDNox.behavior import HumanMouse
mouse = HumanMouse(tab._cdp)
# Bezier curve movement
await mouse.move_to(500, 300, duration=0.8)
# Natural click
await mouse.click()
# Realistic scroll
await mouse.scroll(delta_y=500)
Profile Management
from GDNox.stealth import ProfileManager
# Create persistent profile with pre-seeded data
profile = ProfileManager("/path/to/profile")
profile.seed_history()
profile.seed_cookies()
# Use with browser
async with Browser(user_data_dir="/path/to/profile", auto_seed=False) as browser:
...
📄 License
PolyForm Noncommercial 1.0.0 - Free for personal and non-commercial use only.
See LICENSE for details. For commercial licensing, contact: rafaeldecarvalho.ps@gmail.com
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Made with ❤️ for the automation community
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gdnox-0.1.1.tar.gz.
File metadata
- Download URL: gdnox-0.1.1.tar.gz
- Upload date:
- Size: 83.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.10.12 Linux/6.6.87.2-microsoft-standard-WSL2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a0fa439f76ea99e8e4ab9723d37c9a21edc6228b0e1047d295954bd98a1c35f
|
|
| MD5 |
2aa9718f18faa98fdfb2f6cea3946742
|
|
| BLAKE2b-256 |
65855e8245fda90dc8b762fd76b437a4ede1279f353b643ee792593d03b58fd1
|
File details
Details for the file gdnox-0.1.1-py3-none-any.whl.
File metadata
- Download URL: gdnox-0.1.1-py3-none-any.whl
- Upload date:
- Size: 44.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.10.12 Linux/6.6.87.2-microsoft-standard-WSL2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dfd83c22ad3a2aa66bd8802631b9bb7dac8b1f7042d64393d6ea30de011354d2
|
|
| MD5 |
3d054cec81ddd7f8f4421bb4aa44000b
|
|
| BLAKE2b-256 |
d0b48162d1a6d80be85752b218d70b98c30ad6c1749477a81a42c4b2137cee3a
|