Web scrapers face a frustrating reality every day. Modern websites deploy sophisticated anti-bot systems that detect and block automated browsers within seconds of the first request.
Standard automation tools leave obvious fingerprints everywhere. Selenium exposes the webdriver flag. Puppeteer leaks headless detection signals. Even stealth plugins cannot hide the underlying JavaScript modifications that fingerprinting services detect with ease.
Camoufox solves this problem at a fundamental level.
This Firefox-based anti-detect browser masks your scraper's identity at the C++ implementation layer. Websites simply cannot tell you're running automation code because the modifications happen before JavaScript ever executes.
In this guide, you'll learn how to install this powerful tool, configure fingerprint spoofing, handle proxies with automatic location matching, and build scrapers that bypass Cloudflare, DataDome, and other major web application firewalls.
What is This Anti-Detection Browser?
Camoufox is an open-source browser built on Firefox that masks device fingerprints and evades bot detection systems. It works by injecting realistic device characteristics directly into the browser's C++ code rather than through JavaScript patches that detection services easily identify.
The browser integrates seamlessly with Playwright's API. Any existing Playwright automation code works with only minor initialization changes. Your team won't need to learn an entirely new framework or rewrite existing scrapers from scratch.
Fingerprints rotate automatically using BrowserForge, a library that mimics the statistical distribution of device characteristics found in real-world traffic. The system spoofs navigator properties, screen dimensions, WebGL parameters, audio context, fonts, timezone, and dozens of other characteristics that fingerprinting services examine when evaluating requests.
Unlike stealth plugins that patch JavaScript after page load, this approach modifies the underlying Firefox source code itself. The result passes every major fingerprinting test including CreepJS, BrowserScan, and Fingerprint.com with flying colors. Testing shows consistent 70%+ scores on CreepJS while successfully spoofing all OS predictions.
The browser also runs faster and lighter than stock Firefox. Mozilla's telemetry services, themes, and bloatware are stripped out completely. Memory usage drops to around 200MB per instance compared to 400MB+ for standard Firefox. This efficiency matters when running multiple browser instances for large-scale scraping operations.
System Requirements and Prerequisites
Before installation, ensure your system meets these requirements:
- Python 3.8 or higher installed on your machine
- At least 500MB free disk space for the browser binary
- Linux, macOS, or Windows operating system
- pip package manager configured correctly
The browser binary downloads separately from the Python package. Plan for an additional 300-400MB download during the fetch step. A stable internet connection speeds up the initial setup considerably.
For Linux users, you may need to install additional dependencies for the browser to render correctly. On Ubuntu and Debian systems, the following packages are commonly required: libgtk-3-0, libasound2, and libdbus-glib-1-2.
Installing the Package
Installation requires three terminal commands that complete within minutes on most systems.
First, install the core Python package from PyPI:
pip install camoufox
For users who need proxy integration with automatic location detection, install the extended package with GeoIP support:
pip install -U camoufox[geoip]
The geoip extra installs an additional dataset that determines timezone, language, and coordinates based on IP addresses. This dataset adds roughly 50MB to your installation but proves invaluable for avoiding proxy detection on protected websites.
Finally, download the custom Firefox build:
camoufox fetch
This command retrieves the modified browser binary from the official servers. The download happens once. Future updates check for new versions automatically when you import the package in your scripts.
To verify everything installed correctly, run a quick test:
from camoufox.sync_api import Camoufox
with Camoufox() as browser:
page = browser.new_page()
page.goto("https://httpbin.org/headers")
print(page.content())
If the browser launches and returns the page content without errors, installation succeeded. You're ready to start building your first anti-detect scraper.
Basic Usage Patterns
The library provides both synchronous and asynchronous APIs depending on your application architecture and performance requirements.
Synchronous API for Simple Scripts
For straightforward scraping tasks, the synchronous API keeps code readable and easy to debug:
from camoufox.sync_api import Camoufox
with Camoufox(headless=True) as browser:
page = browser.new_page()
page.goto("https://example.com")
# Extract page title
title = page.locator("title").inner_text()
print(f"Page title: {title}")
# Get all links on the page
links = page.locator("a").all()
for link in links:
href = link.get_attribute("href")
print(href)
The context manager handles browser cleanup automatically when your code exits the with block. No manual cleanup code required. This prevents memory leaks that plague long-running scraping applications.
Asynchronous API for Concurrent Operations
When scraping multiple pages simultaneously, async mode prevents blocking and maximizes throughput:
from camoufox.async_api import AsyncCamoufox
import asyncio
async def scrape_page(browser, url):
page = await browser.new_page()
await page.goto(url)
content = await page.content()
await page.close()
return content
async def main():
urls = [
"https://example1.com",
"https://example2.com",
"https://example3.com"
]
async with AsyncCamoufox(headless=True) as browser:
tasks = [scrape_page(browser, url) for url in urls]
results = await asyncio.gather(*tasks)
for url, content in zip(urls, results):
print(f"Scraped {len(content)} characters from {url}")
asyncio.run(main())
Async mode utilizes system resources more efficiently for large-scale operations. Consider this approach when scraping hundreds or thousands of pages per session.
Configuring Fingerprint Settings
The browser generates realistic fingerprints automatically on each launch. You can also customize specific properties when your use case demands particular configurations.
Operating System Selection
Control which OS the fingerprint mimics:
from camoufox.sync_api import Camoufox
# Force Windows fingerprint for all requests
with Camoufox(os="windows") as browser:
page = browser.new_page()
# Randomly select from multiple options for variety
with Camoufox(os=["windows", "macos", "linux"]) as browser:
page = browser.new_page()
The OS setting determines which fonts load and which navigator properties get spoofed. Matching the OS to your target audience increases authenticity and reduces detection risk significantly.
Custom Configuration Properties
Override specific fingerprint values through the config parameter when you need precise control:
config = {
'window.outerHeight': 1056,
'window.outerWidth': 1920,
'window.innerHeight': 1008,
'window.innerWidth': 1920,
'navigator.userAgent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0',
'navigator.language': 'en-US',
'navigator.languages': ['en-US'],
'navigator.platform': 'Win32',
'navigator.hardwareConcurrency': 12,
}
with Camoufox(config=config, i_know_what_im_doing=True) as browser:
page = browser.new_page()
page.goto("https://browserleaks.com/javascript")
The i_know_what_im_doing flag suppresses warnings when overriding default configurations. Use this carefully since inconsistent settings can create detectable anomalies that sophisticated systems catch.
Screen Dimension Constraints
Limit the generated screen size to specific ranges for consistency:
from browserforge.fingerprints import Screen
constraints = Screen(max_width=1920, max_height=1080)
with Camoufox(screen=constraints) as browser:
page = browser.new_page()
This ensures the fingerprint matches common monitor resolutions found in real-world traffic data.
Proxy Integration with Automatic Location Matching
Proxy detection causes many scraping failures that frustrate developers. Websites compare your IP's geographic location against browser timezone and language settings. Mismatches trigger blocks immediately without any warning.
The GeoIP feature solves this problem automatically:
from camoufox.sync_api import Camoufox
proxy_config = {
'server': 'http://proxy.example.com:8080',
'username': 'user',
'password': 'pass'
}
with Camoufox(
proxy=proxy_config,
geoip=True,
headless=True
) as browser:
page = browser.new_page()
page.goto("https://whatismyipaddress.com")
When geoip=True, the browser detects your proxy's location and automatically configures matching timezone, language, and geolocation coordinates. WebRTC IP addresses also spoof to prevent leaks through that common detection vector.
For specific IP targeting, pass the address directly:
with Camoufox(
proxy=proxy_config,
geoip="203.0.113.50",
headless=True
) as browser:
page = browser.new_page()
Quality proxies significantly impact success rates. Residential proxies from providers like Roundproxies.com work well since they offer multiple proxy types including datacenter, ISP, and mobile options that integrate seamlessly with the GeoIP matching system.
Enabling Human-Like Mouse Movement
Anti-bot systems analyze mouse movement patterns extensively. Straight-line movements, instant teleportation between clicks, and mechanical timing patterns signal automation clearly to detection systems monitoring user interactions.
The humanize feature generates natural cursor trajectories:
from camoufox.sync_api import Camoufox
with Camoufox(humanize=True) as browser:
page = browser.new_page()
page.goto("https://example.com")
# Mouse now moves in curved, human-like paths
page.click("button#submit")
Control maximum movement duration for faster operation when speed matters:
with Camoufox(humanize=2.0) as browser:
# Maximum 2 seconds per cursor movement
page = browser.new_page()
The algorithm generates distance-aware trajectories with randomized acceleration curves that mimic actual user behavior convincingly.
Bypassing Cloudflare and Similar Protections
Cloudflare Turnstile presents a checkbox challenge that blocks most automated browsers. The anti-detect solution handles this through persistent sessions that remember previous successful verifications.
First, solve the challenge manually in visible mode:
from camoufox.sync_api import Camoufox
with Camoufox(
headless=False,
persistent_context=True,
user_data_dir='./browser_profile',
disable_coop=True,
window=(1280, 720)
) as browser:
page = browser.new_page()
page.goto("https://protected-site.com")
page.wait_for_timeout(5000)
page.mouse.click(210, 290)
page.wait_for_timeout(10000)
The disable_coop flag allows clicking elements inside cross-origin iframes like the Turnstile checkbox. Session cookies save to the specified directory for future use.
Subsequent runs reuse those cookies in headless mode automatically:
with Camoufox(
headless=True,
persistent_context=True,
user_data_dir='./browser_profile',
) as browser:
page = browser.new_page()
page.goto("https://protected-site.com")
# Previous challenge solution recognized
Headless Mode Options
Three headless configurations exist for different scenarios and detection environments.
Standard headless mode runs without any visible window:
with Camoufox(headless=True) as browser:
page = browser.new_page()
Virtual display mode on Linux creates a hidden display buffer using Xvfb:
with Camoufox(headless="virtual") as browser:
page = browser.new_page()
Virtual mode runs the browser with a real display context but no physical screen. Some sophisticated detection systems identify standard headless mode but miss virtual displays completely. This makes it ideal for production scraping on Linux servers.
Loading Browser Extensions
Firefox extensions add functionality to your scraping setup. Load custom addons by specifying their extracted folder paths:
addons = [
'/path/to/extension1',
'/path/to/extension2'
]
with Camoufox(addons=addons) as browser:
page = browser.new_page()
Extensions must be extracted folders, not .xpi files. Rename any .xpi file to .zip, extract it, then pass the resulting folder path. The browser automatically enables extensions in private browsing mode.
By default, uBlock Origin loads with custom privacy filters to block ads and tracking scripts that could interfere with your scraping operations.
Performance Optimization Tips
Speed up your automation with these configuration options.
Block image loading to reduce bandwidth and page load time significantly:
with Camoufox(block_images=True) as browser:
page = browser.new_page()
Disable WebGL when you don't need canvas or 3D rendering:
with Camoufox(block_webgl=True) as browser:
page = browser.new_page()
Block WebRTC entirely to prevent IP leaks without proxy spoofing:
with Camoufox(block_webrtc=True) as browser:
page = browser.new_page()
Keep cache disabled (the default) unless you need browser history navigation. Disabling cache reduces memory consumption during long scraping sessions.
Troubleshooting Common Problems
Browser fails to launch
Ensure you've downloaded the binary with the fetch command. Check for sufficient disk space and proper file permissions on Linux systems. On headless servers, verify that required system libraries are installed.
Website still blocks requests
Try these solutions in order: switch to virtual headless mode, enable human mouse movement, use residential proxies with GeoIP enabled, add random delays between page actions, and verify your proxy isn't on a blocklist maintained by anti-bot services.
Sessions don't persist between runs
Enable persistent context and specify a profile directory in your configuration parameters. Ensure the directory path exists and has write permissions.
Memory usage grows over time
Close pages explicitly when finished and consider running in batches rather than keeping one browser open indefinitely. The browser accumulates state over time that can cause memory bloat.
FAQ
Is this tool free to use?
Yes. The project is open-source under the MPL-2.0 license. All core features including fingerprint rotation, proxy support, and stealth patches come at no cost.
Does it work with existing Playwright code?
The library wraps Playwright's API directly. Existing scripts need only browser initialization changes to switch over seamlessly.
Which anti-bot systems does it bypass?
Testing shows success against CreepJS, DataDome, Cloudflare Turnstile and Interstitial, Imperva, reCAPTCHA v2/v3, Fingerprint.com, and most commercial WAFs. Results depend on proxy quality and proper configuration.
Can I run it in Docker containers?
Yes. The project includes a Dockerfile for containerized deployment. Build the image and mount volumes for output files. Docker deployments work well for scalable scraping infrastructure.
How frequently does it update?
The project tracks current Firefox releases. Updates ship through PyPI as new fingerprinting techniques emerge and Firefox versions change. Check the GitHub repository for release notes.
Next Steps
You now have the knowledge to build undetectable web scrapers using this powerful anti-detection browser.
Start with a simple test script using the synchronous API. Verify your fingerprint against BrowserScan or CreepJS before targeting protected sites. Understanding your fingerprint baseline helps diagnose issues when blocks occur.
For production deployments, combine residential proxies with GeoIP matching and persistent sessions for sites requiring authentication or challenge solving. Monitor success rates and adjust configurations based on target site behavior.
The official documentation at camoufox.com covers advanced topics including WebGL parameter spoofing, remote server mode for non-Python languages, and integration with crawling frameworks like Scrapy and Crawlee.