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.22.tar.gz (81.4 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.22-py3-none-any.whl (104.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: funbrowser-0.1.22.tar.gz
  • Upload date:
  • Size: 81.4 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.22.tar.gz
Algorithm Hash digest
SHA256 0a7cc6f5c93ea7bf5a880299bbd87c09da1b7d4bd486925cba891e04f31af479
MD5 a33b788dc66ffc168150f096cb4971c4
BLAKE2b-256 0d106b47427d6f95e016619948930b4fe1ce94687e72f88305ce203d843e54ea

See more details on using hashes here.

Provenance

The following attestation bundles were made for funbrowser-0.1.22.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.22-py3-none-any.whl.

File metadata

  • Download URL: funbrowser-0.1.22-py3-none-any.whl
  • Upload date:
  • Size: 104.0 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.22-py3-none-any.whl
Algorithm Hash digest
SHA256 561b5ca1bd99e222f5ae510a04df9c5214ce94aa041a13effad24eb549d913e8
MD5 4e6368fc68dbed57efa96730b6270310
BLAKE2b-256 393847f7e832554d3f8f652e5eb86b246005926e2cfef11a7118df87c542ee3a

See more details on using hashes here.

Provenance

The following attestation bundles were made for funbrowser-0.1.22-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