Fingerprint Management & Session Persistence: Make Your Scraper Look Like a Returning Visitor

Why random fingerprints trigger reCAPTCHA Enterprise, and how fixed seeds with persistent contexts make your scraper look like a returning user.

16Yun Engineering TeamApr 13, 20262 min read

The Problem: Fresh Fingerprints Every Time Are Suspicious

CloakBrowser generates a random fingerprint seed on every launch by default — GPU model, hardware concurrency, screen dimensions are all new. This is fine for one-off scraping, but when you visit the same target repeatedly:

Same IP, same account, but a different browser fingerprint every time → the detection system sees multiple devices sharing one exit. Highly suspicious.

reCAPTCHA v3 Enterprise maintains a long-term behavioral profile of each user. A new fingerprint every visit = a new user every visit. Your accumulated trust score resets to zero.

Fixed Fingerprint Seeds

CloakBrowser supports deterministic fingerprints via --fingerprint:

from cloakbrowser import launch

# Fixed seed 12345 — identical fingerprint across launches
browser = launch(args=["--fingerprint=12345"])
import { launch } from 'cloakbrowser';
const browser = await launch({ args: ['--fingerprint=12345'] });

Seed Strategy Guide

ScenarioStrategyWhy
One-off bulk scrapeRandom seed (default)Fresh identity per task
Sites requiring loginFixed seed + persistent contextIdentity + session both persist
Multi-accountOne fixed seed per accountSimulate multiple devices
With dedicated proxyBind seed to proxy IPSame IP + same fingerprint = fixed device

Platform Fingerprint Override

CloakBrowser spoofs Linux to Windows by default. Override for cross-platform needs:

browser = launch(args=[
    "--fingerprint=12345",
    "--fingerprint-platform=macos",
])

Persistent Contexts: Login State That Survives Restarts

launch_persistent_context() preserves cookies, localStorage, and cache across sessions:

from cloakbrowser import launch_persistent_context

# First run — create and save profile
ctx = launch_persistent_context("./my-profile", headless=False)
page = ctx.new_page()
page.goto("https://example.com/login")
page.fill("#username", "myaccount")
page.fill("#password", "mypassword")
page.click("button[type=submit]")
# Scrape...
ctx.close()  # profile auto-saved

# Second run — cookies, localStorage restored
ctx = launch_persistent_context("./my-profile", headless=False)
page = ctx.new_page()
page.goto("https://example.com/dashboard")
# Already logged in!

Key use cases:

  • Authenticated scraping: Scheduled tasks resume login state automatically
  • Incognito detection bypass: Persistent contexts show as non-incognito
  • Chrome extensions: Extensions only work from a real user data directory
  • Natural browsing history: Cached fonts, Service Workers, IndexedDB accumulate over time

With 16Yun Dedicated Proxy

A dedicated proxy with a fixed exit IP + fixed fingerprint seed + persistent context = a convincing "office computer" in the detection system's eyes:

from cloakbrowser import launch_persistent_context

ctx = launch_persistent_context(
    "./my-profile",
    headless=False,
    proxy="http://user:pass@dedicated.16yun.cn:8888",
)

Storage Quota Tradeoff

CloakBrowser normalizes storage quota to pass FingerprintJS. This may cause BrowserScan's notPrivate check to flag incognito mode.

Quota SettingFingerprintJSBrowserScan notPrivate
Default (~500MB)✅ PASS⚠️ Flagged as incognito
--fingerprint-storage-quota=5000May trigger detection✅ Non-incognito

Use the default quota if the target runs FingerprintJS. Increase quota if the target cares more about incognito detection:

ctx = launch_persistent_context(
    "./my-profile",
    args=["--fingerprint-storage-quota=5000"],
)

Quick Context (No Persistence)

For one-off sessions without profile persistence:

from cloakbrowser import launch_context

context = launch_context(
    user_agent="Custom UA",
    viewport={"width": 1920, "height": 1080},
    locale="en-US",
    timezone="America/New_York",
)

page = context.new_page()
page.goto("https://example.com")
context.close()

Extra kwargs forward to Playwright's browser.new_context() — use storage_state, permissions, extra_http_headers, etc.

Save and Restore Session State

from cloakbrowser import launch_context

context = launch_context(storage_state="state.json")
page = context.new_page()
page.goto("https://example.com")
# ... interact ...

context.storage_state(path="state.json")
context.close()

Summary

TechniqueProblem SolvedCloakBrowser API
Fixed seedConsistent fingerprint = returning visitorargs=["--fingerprint=12345"]
Persistent contextLogin state, cookies, localStorage across restartslaunch_persistent_context("./profile")
Quota tuningBalance FingerprintJS vs BrowserScan detection--fingerprint-storage-quota=N
Proxy + fingerprint bindingSame IP + same fingerprint = maximum trustFixed proxy + fixed seed + persistent context

Need an enterprise proxy plan?

We can tailor architecture to your target domains, concurrency, and reliability goals.