🎯 A customizable, anti-detection cloud browser powered by self-developed Chromium designed for web crawlers and AI Agents.👉Try Now
Back to Blog

Undetected Fingerprint Browser for Python: Browser Use, Crawl4AI, Scrapling

Sophia Martinez
Sophia Martinez

Specialist in Anti-Bot Strategies

07-Jul-2026

TL;DR:

  • A local headless browser leaks its automation on three axes at once: the runtime, the fingerprint, and the exit IP. navigator.webdriver is true, the fingerprint carries headless defaults, and every request exits from your own address — anti-bot systems score all three.
  • Browser Use, Crawl4AI, and Scrapling all speak the Chrome DevTools Protocol, so they can drive a remote browser instead of a local one. Each accepts a cdp_url (or browser_ws_endpoint); point it at Scrapeless and the automation runs server-side.
  • Scrapeless Scraping Browser is an anti-detection cloud browser: real Chromium, a consistent per-session fingerprint, and residential egress in 195+ countries. The webdriver tell is gone and the exit IP reads clean, with no stealth patches to maintain.
  • The integration is one line per tool — the connection URL. You change where the browser comes from, not how your scraper is written.
  • The same WebSocket endpoint carries every option as a query parametertoken, sessionTTL, proxyCountry, fingerprint, profileId — so geo-targeting and profile reuse are URL changes, not code rewrites.
  • Free to start. New Scrapeless accounts include free Scraping Browser runtime — sign up at app.scrapeless.com.

Introduction: three Python scrapers, one undetected browser

Anti-bot systems no longer look at a single signal. A modern challenge scores the browser runtime, the fingerprint it presents, and the network path it arrives on — together, in one pass. A local headless Chromium fails all three: it announces automation through the navigator.webdriver property, it ships with headless-default fonts and canvas behavior, and it exits from a datacenter or home IP that reputation services already know.

Python has three popular ways to drive a browser — Browser Use style LLM agents, Crawl4AI's crawler, and Scrapling's fetchers — and each one, run locally, inherits the same three-axis problem. Patching stealth into a local browser means chasing Chrome releases and anti-bot updates by hand, forever.

There is a shorter path. All three tools connect to a browser over the Chrome DevTools Protocol, and CDP does not care whether that browser is on localhost or in the cloud. This guide wires each of the three to the Scrapeless Scraping Browser, so the runtime, fingerprint, and exit IP are handled server-side and your scraper code stays exactly as it is.


What leaks your fingerprint

A browser fingerprint is the set of signals a page can read without a login: the user agent, the WebDriver flag, canvas and WebGL rendering, installed fonts, timezone, language, and screen metrics. Automation frameworks perturb these in predictable ways — the W3C WebDriver specification requires conforming drivers to set navigator.webdriver, which is exactly the signal detection scripts read first.

Fixing this locally means overriding each signal to look consistent and human, then keeping those overrides current as Chromium and the detectors change. That is the maintenance treadmill the cloud browser removes: Scrapeless presents one coherent fingerprint per session, so the signals agree with each other and with a real Chrome profile.

Why Scrapeless Scraping Browser

Scrapeless Scraping Browser is a customizable, anti-detection cloud browser designed for web crawlers and AI agents. Because it speaks the Chrome DevTools Protocol, any CDP-capable Python tool connects to it unchanged. For the three tools in this guide it brings:

  • Real self-developed Chromium that executes JavaScript exactly like Chrome, so single-page apps and challenge interstitials resolve.
  • A consistent per-session fingerprint — no navigator.webdriver tell, no headless defaults leaking through.
  • Residential egress in 195+ countries, selected per session with a single proxyCountry value.
  • Session persistence through reusable profiles, so cookies and login state survive across runs.
  • One connection surface — every capability is a query parameter on the same WebSocket endpoint.

Get your API key on the free plan at app.scrapeless.com.


Prerequisites

  • Python 3.11 or newer (Browser Use needs 3.11+; Crawl4AI and Scrapling run on 3.10+)
  • A Scrapeless account and API key — sign up at app.scrapeless.com
  • The tool you want to wire up: browser-use, crawl4ai, or scrapling
  • Basic familiarity with the terminal and async Python

The code below is verified against each library's current API (Browser(cdp_url=...), BrowserConfig(browser_mode="cdp", cdp_url=...), DynamicSession(cdp_url=...)). Running it end to end needs a live Scrapeless session, and the Browser Use example additionally needs an OpenAI API key for its language model — supply your own keys to execute each example.

The full connection details live in the Scraping Browser documentation.


The shared pattern: one CDP URL

Every integration below reduces to the same idea. Scrapeless is a CDP browser reachable at wss://browser.scrapeless.com/api/v2/browser, and its options ride as query parameters. Build that URL once, hand it to the tool's connection argument, and run your scraper as written.

python Copy
from urllib.parse import urlencode

params = {
    "token": "your_api_token_here",   # from app.scrapeless.com
    "sessionTTL": 900,                 # seconds the session stays alive
    "proxyCountry": "ANY",             # or an ISO code like "US", "DE", "JP"
}
cdp_url = f"wss://browser.scrapeless.com/api/v2/browser?{urlencode(params)}"

The parameters are consistent across all three tools:

Parameter Meaning
token your Scrapeless API key (required)
sessionTTL session lifetime
sessionName a label for the session
proxyCountry ISO country code or ANY
fingerprint URL-encoded JSON fingerprint object
profileId reuse a persistent profile across runs

Browser Use: an LLM agent on a clean browser

Browser Use drives a browser with a language model. Its Browser object accepts a cdp_url, so the entire change is to build the Scrapeless URL and pass it in — the Agent, its task, and its LLM stay the same.

Note: this example needs a live Scrapeless session and an OpenAI API key for agent.run(). Supply both to execute it.

python Copy
import asyncio, os
from urllib.parse import urlencode
from dotenv import load_dotenv
from browser_use import Agent, Browser, ChatOpenAI

def scrapeless_browser() -> Browser:
    params = {
        "token": os.environ["SCRAPELESS_API_KEY"],
        "sessionTTL": 900,
        "proxyCountry": "ANY",
    }
    ws = f"wss://browser.scrapeless.com/api/v2/browser?{urlencode(params)}"
    return Browser(cdp_url=ws)

async def main():
    load_dotenv()
    browser = scrapeless_browser()
    await browser.start()
    agent = Agent(
        task="Go to Google, search for 'Scrapeless', open the first result and return its title",
        llm=ChatOpenAI(model="gpt-4o"),
        browser=browser,
    )
    print(await agent.run())
    await browser.kill()

asyncio.run(main())

The agent now reasons and clicks against a cloud browser with a clean fingerprint and residential egress. You can watch the live session from the Scrapeless Dashboard.

Get your API key on the free plan: app.scrapeless.com

Crawl4AI: set the browser mode to CDP

Crawl4AI ships native CDP support, so no extra install is needed. Set browser_mode="cdp" on BrowserConfig and pass the Scrapeless URL as cdp_url. Note that Crawl4AI's integration expresses sessionTTL in milliseconds.

Note: this example needs a live Scrapeless session to execute against a real target. Add your API key to run it.

python Copy
import asyncio
from urllib.parse import urlencode
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig

async def main():
    params = {
        "token": "your_api_token_here",
        "sessionName": "Proxy Demo",
        "sessionTTL": 1000,       # milliseconds
        "proxyCountry": "ANY",
    }
    cdp_url = f"wss://browser.scrapeless.com/api/v2/browser?{urlencode(params)}"

    async with AsyncWebCrawler(
        config=BrowserConfig(headless=False, browser_mode="cdp", cdp_url=cdp_url)
    ) as crawler:
        result = await crawler.arun(
            url="https://www.scrapeless.com/en",
            config=CrawlerRunConfig(wait_for="css:.content", scan_full_page=True),
        )
        print(f"Status Code: {result.status_code}")
        print(f"Title: {result.metadata['title']}")

asyncio.run(main())

To send a custom fingerprint, JSON-encode a fingerprint object, URL-encode it, and pass it as the fingerprint parameter — the browser then presents that user agent, platform, screen, and localization consistently for the whole session.

Scrapling: a DynamicSession over the cloud browser

Scrapling gives you fast, adaptive parsing on top of a browser session. Its DynamicSession takes a cdp_url, and Scrapling's integration passes sessionTTL as a string of seconds. The session automatically handles reCAPTCHA, Cloudflare Turnstile, and AWS WAF challenges as part of rendering.

Note: this example needs a live Scrapeless session to execute. Add your API key to run it.

python Copy
import os
from urllib.parse import urlencode
from dotenv import load_dotenv
from scrapling.fetchers import DynamicSession

load_dotenv()
config = {
    "token": os.environ["SCRAPELESS_API_KEY"],
    "sessionName": "scrapling-session",
    "sessionTTL": "300",           # seconds, as a string
    "proxyCountry": "ANY",
    "sessionRecording": "false",
}
ws = f"wss://browser.scrapeless.com/api/v2/browser?{urlencode(config)}"

with DynamicSession(cdp_url=ws, disable_resources=True) as s:
    page = s.fetch("https://httpbin.org/headers", network_idle=True)
    print(f"Content length: {len(page.body)}")
    print(page.json())

Scrapeless renders the page on a clean browser; Scrapling parses the returned DOM with its selectors. The division of labor is the point — you keep Scrapling's extraction API and swap only the browser underneath.


What you get back

Across all three tools the behavior is the same in the ways that matter:

  • The navigator.webdriver signal is absent — the cloud browser does not announce automation, so the first detection check reads like a real Chrome.
  • The exit IP matches proxyCountry — geo-gated pages and prices resolve as a local visitor sees them; ANY lets Scrapeless choose.
  • JavaScript executes fully — client-rendered lists and challenge interstitials attach before you read the DOM.
  • sessionTTL units differ by tool — seconds for Browser Use and Scrapling, milliseconds for Crawl4AI. Match the tool's own convention, not a shared constant.
  • Fields can be absent — treat any parsed value as nullable, since page structure and conditional sections vary by target.

Conclusion: pick the tool, keep the browser

The three tools cover different jobs — an LLM agent, a crawler, and an adaptive parser — but they share one anti-detection browser. Whichever you reach for, the integration is a single connection URL: build wss://browser.scrapeless.com/api/v2/browser with your token and options, hand it to the tool's cdp_url, and let Scrapeless carry the runtime, fingerprint, and residential egress.

For more on choosing an egress path for a scraper, see the difference between a VPS and a proxy, and compare plans on the Scrapeless pricing page. Pin proxyCountry to a residential region, match each tool's sessionTTL unit, and treat absent fields as nullable.


Ready to Build Your Undetected Scraping Pipeline?

Join our community to claim a free plan and connect with developers wiring Python scrapers to cloud browsers: Discord · Telegram.

Sign up at app.scrapeless.com for free Scraping Browser runtime and point Browser Use, Crawl4AI, or Scrapling at the cloud browser your targets can't fingerprint.


FAQ

Q: Do I have to rewrite my scraper to use Scrapeless?
No. All three tools already connect to a browser over CDP. You change the connection target — the cdp_url or WebSocket endpoint — and keep your agent, crawler, or parser code as written.

Q: Why not just run a local headless browser?
A local browser runs on your own IP, announces automation through navigator.webdriver, and needs you to maintain stealth patches as Chromium and anti-bot systems change. The cloud browser presents a consistent fingerprint and residential egress with no upkeep.

Q: Do I need a separate proxy?
No. Residential egress is built into the session — set proxyCountry to a region or ANY. There is no separate proxy to configure.

Q: Is sessionTTL in seconds or milliseconds?
It depends on the tool's integration: seconds for Browser Use and Scrapling (Scrapling passes it as a string), milliseconds for Crawl4AI. Use each tool's own convention.

Q: Does it handle Cloudflare and CAPTCHAs?
The cloud browser handles common challenge types — the Cloudflare interstitial, Cloudflare Turnstile, reCAPTCHA, and AWS WAF — as part of rendering on a clean residential IP. Pin proxyCountry to a residential region for the best result.

Q: Which of the three tools should I use?
Browser Use for LLM-driven agents that decide their own steps, Crawl4AI for structured crawling and content extraction, and Scrapling for fast adaptive parsing of a fetched page. They share the same Scrapeless browser, so you can switch without changing your connection approach.

At Scrapeless, we only access publicly available data while strictly complying with applicable laws, regulations, and website privacy policies. The content in this blog is for demonstration purposes only and does not involve any illegal or infringing activities. We make no guarantees and disclaim all liability for the use of information from this blog or third-party links. Before engaging in any scraping activities, consult your legal advisor and review the target website's terms of service or obtain the necessary permissions.

Most Popular Articles

Catalogue