Skip to main content

Undetect browser SDK for Python with built-in captcha solving via funsolver.com

Project description

FunBrowser

PyPI - Version Python Versions License

Undetect / anti-detect browser SDK for Python. Drives real Chrome through the DevTools Protocol with built-in stealth patches, customisable browser fingerprints (UA, GPU, screen, timezone, CPU cores, …), full proxy support, human-like input timing, browser-pool / context-pool farming, an optional local web panel, and automatic captcha solving for Cloudflare Turnstile, reCAPTCHA v2 / v3, hCaptcha, FunCaptcha, and GeeTest through funsolver.com.

Built for web scraping, browser automation, and bypassing antibot services (Cloudflare, DataDome, PerimeterX, Akamai) without the Selenium / Playwright leaks that get scripts flagged.

pip install funbrowser              # core: stealth + automation + solver
pip install funbrowser[panel]       # + local web panel for the pool
pip install funbrowser[tls]         # + browser-grade TLS impersonation

Quick start

import asyncio
import funbrowser

async def main():
    async with await funbrowser.start(headless=True) as browser:
        tab = await browser.get("https://example.com")
        print(await tab.evaluate("document.title"))
        # → Example Domain
        print(await tab.evaluate("navigator.userAgent"))
        # → Mozilla/5.0 ... Chrome/... — no "HeadlessChrome"

asyncio.run(main())
# Full automation: stealth + proxy + auto-solve captchas + humanly input
async with await funbrowser.start(
    headless=True,
    proxy="user:pass@us-1.proxy.io:8080",     # any common format works
    api_key="fs_xxx",                         # funsolver.com key
    humanly=True,                             # Bezier mouse + typing rhythm
    fingerprint=funbrowser.presets.windows_11_nvidia_rtx_4070(),
) as browser:
    tab = await browser.get("https://target-with-captcha.com")
    # captchas auto-solve in the background
    await tab.fill("#email", "alice@example.com")
    await tab.click("button[type=submit]")

Features

Stealth (passes 25/25 standard antidetect probes)

  • navigator.webdriver → undefined, with native toString camouflage
  • UA + Client Hints with HeadlessChrome stripped
  • chrome.runtime, plugins, languages, permissions consistency
  • Real GPU for WebGL (--use-gl=angle, not SwiftShader)
  • Canvas + audio readout noise to break fingerprint tracking
  • WebRTC IP leak blocked (flag-level + SDP filter)
  • iframe stealth propagation
  • Geo auto-couples timezone + locale to proxy exit IP
uv run python examples/detect_check.py      # self-audit

Fingerprint customisation

17 ready presets (Windows × NVIDIA / Intel / AMD, macOS Apple Silicon / Intel, Linux, plus 4 Android mobile) + arbitrary custom Fingerprint(...).

from funbrowser import Fingerprint, presets

fp = presets.macos_apple_silicon_m3_pro().merge(
    Fingerprint(timezone="Asia/Tokyo", languages=("ja-JP", "ja", "en"))
)
async with await funbrowser.start(fingerprint=fp) as browser:
    ...

Humanly mode (Bezier-curve mouse + typing rhythm)

async with await funbrowser.start(humanly=True) as browser:
    await tab.click("button")        # cursor curves toward target
    await tab.type("#email", "ada")  # per-keystroke random delay

Presets: humanly.FAST, humanly.DEFAULT, humanly.CAREFUL, plus arbitrary custom HumanBehavior(...).

Captcha auto-solve

Paste a funsolver.com API key. Five captcha families detected on-page and solved automatically:

API method Page integration
Cloudflare Turnstile solve_turnstile .cf-turnstile widgets
reCAPTCHA v2 (+ Enterprise) solve_recaptcha_v2 .g-recaptcha widgets
reCAPTCHA v3 (+ Enterprise) solve_recaptcha_v3 hooks grecaptcha.execute()
hCaptcha solve_hcaptcha .h-captcha widgets
FunCaptcha / Arkose solve_funcaptcha [data-pkey] elements
GeeTest v3 + v4 solve_geetest hooks initGeetest / initGeetest4

Proxies (every format)

host:port, host:port:user:pass, user:pass@host:port, host:port@user:pass, socks5://..., chrome URL form — all auto-parsed. HTTP/HTTPS auth flows through CDP automatically.

Persistent profiles

from funbrowser import Profile

alice = Profile.ensure("alice")   # ./funbrowser_profiles/alice
async with await funbrowser.start(user_data_dir=alice) as browser:
    # cookies + localStorage + login state persist between runs
    ...

Browser farming — BrowserPool and ContextPool

from funbrowser import BrowserPool, ContextPool

# Process pool — full Chrome per slot (max isolation)
async with BrowserPool(
    size=5,
    proxies=["proxy1:8080", "proxy2:8080", "proxy3:8080"],
    headless=True,
    mini=True,
) as pool:
    async def scrape(browser):
        tab = await browser.get("https://example.com")
        return await tab.evaluate("document.title")

    results = await pool.run_all([scrape] * 100)

# Context pool — 1 Chrome + N isolated contexts (~7-10x less RAM)
async with ContextPool(size=10, headless=True, mini=True) as pool:
    async def scrape(ctx):
        tab = await ctx.get("https://example.com")
        return await tab.evaluate("document.title")

    results = await pool.run_all([scrape] * 100)

Memory comparison on the same 10-slot workload:

  • BrowserPool(size=10) → ~1.0 GB
  • ContextPool(size=10) → ~260 MB (one Chrome + 10 contexts)

mini=True mode

Curated set of Chrome flags that cut RAM / CPU / disk per browser (~50% lower RSS): site isolation off, background throttling, audio muted, extensions / sync / translate disabled, small disk caches, V8 heap cap. Combines with stealth — does not turn off the real GPU. Works on Browser, BrowserPool, and ContextPool alike.

TLS fingerprint impersonation (pip install funbrowser[tls])

Script-level HTTP that picks JA3/JA4 from real-browser profiles:

from funbrowser.tls import ImpersonatedHTTPClient

async with ImpersonatedHTTPClient(profile="chrome131") as http:
    r = await http.get("https://protected-api.com/endpoint")

23 supported profiles: chrome99..chrome133a, safari15..safari18, firefox133/135, Android variants. See docs/M10_M11_DESIGN.md for the deeper browser-traffic mitm proxy roadmap.

Local web panel (pip install funbrowser[panel])

from funbrowser import BrowserPool, Panel

async with BrowserPool(size=5) as pool:
    async with Panel(pool) as panel:
        print(panel.url)   # http://127.0.0.1:8765
        await long_running_task()

Black-and-white dashboard with: pool stats, FunSolver balance, browser fleet table (proxy / geo / fingerprint / open tabs / per-row goto + screenshot), activity log (panel actions + per-browser captcha solves), quick actions, and a script runner — upload an async def main(browser) script and run it on one browser or fan it out across the whole pool, with per-run stdout / return / traceback captured.

Documentation

Self-audit

uv run python examples/detect_check.py
[navigator.* basics]              9/9   PASS
[chrome runtime + iframe]         6/6   PASS
[stealth-detection probes]        5/5   PASS
[WebGL / canvas / audio]          4/4   PASS
[WebRTC IP leak]                  1/1   PASS

score:     25/25  (100%)

Roadmap

Milestone Status
M0 Bootstrap done
M1 CDP core + Tab API done
M2 Stealth Tier 1 + 2 done
M2.5 Fingerprint customisation done
M3 Solver bridge + Turnstile done
M4 reCAPTCHA / hCaptcha / FunCaptcha / GeeTest done
M5 Production hardening (proxies, profiles, retries, multi-tab) done
M5.5 DX Tier S (auto-wait + ElementHandle + cookies + block_urls) done
M5.5+ Humanly mode done
M5.5++ WebRTC + toString camouflage + geo auto-couple done
M5.5+++ Mobile presets + expanded catalog done
M5.6 BrowserPool done
M5.7 Web Panel (+ FunSolver balance + per-browser logs + scripts) done
M5.8 Mini mode done
M6 v0.1 release in progress
M10a TLS HTTP client (curl_cffi) done
M11-alt ContextPool (lightweight pool) done
M7 Fingerprint consistency (Tier 3) post-v0.1
M8 Real fingerprint pool (Tier 4) post-v0.1
M9 Deep WebGL / canvas / shader spoofing post-v0.1
M10b mitm proxy for Chrome traffic (production-grade) post-v0.1
M11 Browser fork (Camoufox / Chromium) post-v0.1
M12 Tauri UI for manual mode post-v0.1

Development

Uses uv for env + deps.

uv sync                              # install
uv run pytest -q                     # full test suite (173 tests)
uv run ruff check . && uv run ruff format --check .
uv run mypy funbrowser
uv run python examples/detect_check.py

Contributing

See CONTRIBUTING.md. Issues + PRs welcome.

License

MIT. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

funbrowser-0.1.17.tar.gz (77.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

funbrowser-0.1.17-py3-none-any.whl (99.2 kB view details)

Uploaded Python 3

File details

Details for the file funbrowser-0.1.17.tar.gz.

File metadata

  • Download URL: funbrowser-0.1.17.tar.gz
  • Upload date:
  • Size: 77.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for funbrowser-0.1.17.tar.gz
Algorithm Hash digest
SHA256 91e0a741796b2958c1bcf01b366d6e47ff8cfa1a2bd9fb7462476c19e1f13e9b
MD5 e5afdb5d7d6a32aba3c5e1f53a67f418
BLAKE2b-256 187d9ec01bb63fc7e39fdf082ecd830a39e08d25efe3d82fb1126aa64a60a6ea

See more details on using hashes here.

Provenance

The following attestation bundles were made for funbrowser-0.1.17.tar.gz:

Publisher: release.yml on WhyY0u/funBrowser

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file funbrowser-0.1.17-py3-none-any.whl.

File metadata

  • Download URL: funbrowser-0.1.17-py3-none-any.whl
  • Upload date:
  • Size: 99.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for funbrowser-0.1.17-py3-none-any.whl
Algorithm Hash digest
SHA256 88bba1c8a121048de2faf59f6a0c041e999eea82c4f8c42ce783295d13641c48
MD5 8f555c5dc8d5a21388c2a0eaabaf6c0e
BLAKE2b-256 9af81382c821992f1ed24c65bf52e1c3154de6eaaef1700573a7bfc1810582dc

See more details on using hashes here.

Provenance

The following attestation bundles were made for funbrowser-0.1.17-py3-none-any.whl:

Publisher: release.yml on WhyY0u/funBrowser

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page