Human Behavior Simulation: Bypass Behavioral Detection with humanize=True
Bézier mouse curves, per-character typing, realistic scrolling — how humanize=True makes your scraper pass BrowserScan and behavioral analysis.
Behavioral Detection: The Second Wall After Fingerprinting
Browser fingerprinting tells detection services "what device you are," but it doesn't tell them "whether you're human." Behavioral detection fills that gap by analyzing mouse movement, keyboard input, and scroll patterns.
| Behavior | Bot | Human |
|---|---|---|
| Mouse movement | Instant teleport | Bézier curves with acceleration and overshoot |
| Click position | Perfect center of button | Scattered within button area |
| Typing | All chars at same interval | Per-character with variable speed, occasional typos |
| Scrolling | Instant jump | Acceleration → cruise → deceleration micro-steps |
| Idle pauses | None | Thinking pauses, occasional idle micro-movements |
Services like BrowserScan, DataDome, and deviceandbrowserinfo.com specialize in analyzing these behaviors. Perfect fingerprints mean nothing if your mouse teleports to every button.
humanize=True: One Flag to Fix It
CloakBrowser's humanize=True intercepts all Playwright interaction calls and replaces them with human-like equivalents:
from cloakbrowser import launch
browser = launch(humanize=True)
page = browser.new_page()
page.goto("https://example.com")
# All operations are now humanized
page.locator("#email").fill("user@example.com") # per-character typing
page.locator("button[type=submit]").click() # Bézier curve path
import { launch } from 'cloakbrowser';
const browser = await launch({ humanize: true });
Behavioral Changes
| Interaction | Stock Playwright | humanize=True |
|---|---|---|
| Mouse move | Instant teleport | Bézier curve with easing and overshoot |
| Click | Instant | Random offset within target + hold duration |
| fill() | Instant value set | Character-by-character with pauses |
| Scroll | Jump step | Micro-steps: accelerate → cruise → decelerate |
| Keyboard | Instant fill | Per-character timing with occasional typos |
Verified Results
deviceandbrowserinfo.com checks 24 behavioral signals. CloakBrowser + humanize=True passes all 24:
from cloakbrowser import launch
browser = launch(headless=False, humanize=True)
page = browser.new_page()
page.goto("https://example.com")
page.wait_for_timeout(5000)
# Result: 24/24 signals pass — "You are human!"
browser.close()
| Detection Service | Stock Playwright | CloakBrowser + humanize |
|---|---|---|
| deviceandbrowserinfo.com | ❌ Bot detected | ✅ You are human! |
| bot.incolumitas.com | 13 fails | 1 fail (WEBDRIVER spec only) |
| BrowserScan | Automation detected | Normal |
| reCAPTCHA v3 interaction score | 0.1 (bot) | 0.9 (human) |
Presets and Custom Configuration
Presets
# Default — normal speed
browser = launch(humanize=True)
# Careful — slower, more deliberate
browser = launch(humanize=True, human_preset="careful")
Custom Parameters
browser = launch(humanize=True, human_config={
"mistype_chance": 0.05, # 5% typo rate (auto-corrected)
"typing_delay": 100, # ms per character
"idle_between_actions": True, # micro-movements between actions
"idle_between_duration": [0.3, 0.8], # idle range (seconds)
})
const browser = await launch({
humanize: true,
humanConfig: {
mistype_chance: 0.05,
typing_delay: 100,
idle_between_actions: true,
idle_between_duration: [0.3, 0.8],
}
});
Parameter Reference
| Parameter | Default | Effect |
|---|---|---|
mistype_chance | 0.02 | Typo probability (0-1), auto-backspace and retype |
typing_delay | 50-200ms | Per-character interval (fixed value or range) |
idle_between_actions | false | Micro-movements between actions |
idle_between_duration | [0.5, 1.5] | Idle duration range (seconds) |
Important Limitations
Not all Playwright methods go through the humanize pipeline.
✅ Humanized Methods
page.click(selector),page.type(selector, text),page.hover(selector)page.fill(selector, text),page.select_option()page.mouse.*,page.keyboard.*page.locator(selector).click(),.fill(),.type(),.hover()page.evaluate()is unaffected (keeps raw behavior)
❌ Methods That Bypass Humanize
page.query_selector() returns ElementHandle objects that bypass all humanize patches:
# ❌ Avoid — ElementHandle skips humanize
element = page.query_selector("#email")
element.click() # instant teleport, no Bézier curve
element.type("text") # instant, no per-character timing
# ✅ Recommended — Locator API goes through humanize
page.locator("#email").click() # Bézier curve
page.locator("#email").fill("text") # per-character
Always prefer
locatoroverquery_selector. The former goes through the full humanize pipeline; the latter bypasses all patches.
When You Need Raw Speed
If a specific action doesn't need humanization (e.g., bulk data export):
page._original.click("#export-button") # skip humanize
Synergy with Proxies
Behavioral detection also analyzes network patterns — are request intervals uniform (bot) or random (human)?
The full stack: CloakBrowser + humanize + 16Yun residential proxy:
from cloakbrowser import launch
browser = launch(
proxy="http://user:pass@proxy.16yun.cn:8888",
geoip=True,
headless=False,
humanize=True,
human_preset="careful",
)
page = browser.new_page()
page.goto("https://example.com")
page.locator("#search").fill("data scraping")
page.locator(".search-btn").click()
page.wait_for_timeout(2000)
# A human pauses 1-3 seconds to "read" results
page.locator(".result-item").first().click()
Add randomized delays between requests rather than fixed intervals to further mimic human browsing behavior.
Need an enterprise proxy plan?
We can tailor architecture to your target domains, concurrency, and reliability goals.