Human Emulation
Overview
Human Emulation is an advanced feature that enables human-like interaction with web pages through sophisticated mouse movement and keyboard input synthesis. This technology helps bypass anti-bot detection systems by generating biometrically accurate user behavior patterns.
Key Advantages
- Human-like Behavior: Generates natural mouse movements and typing patterns with realistic acceleration, deceleration, and physiologically accurate trajectories
- Anti-Detection: Bypasses sophisticated bot detection systems through low-level CDP control, eliminating robotic patterns
- Flexible Integration: Works seamlessly with Playwright, Puppeteer, and Selenium
Available CDP Methods
The human emulation layer provides the following CDP actions:
Human.click
- Performs human-like mouse clicksHuman.moveTo
- Moves mouse cursor naturally to coordinatesHuman.type
- Types text with realistic typing patterns and speedHuman.scroll
- Scrolls page with smooth, natural motion
Examples
Complete Search Automation
- Python
- JavaScript
import asyncio
async def search_example(page):
# Create CDP session for human-like actions
client = await page.context.new_cdp_session(page)
await page.goto("https://duckduckgo.com", wait_until="load")
# Wait for search input to be ready
await page.wait_for_selector('input[name="q"]')
# Get search box coordinates
search_box = await page.locator('input[name="q"]').bounding_box()
x = search_box["x"] + search_box["width"] / 2
y = search_box["y"] + search_box["height"] / 2
# Click on search box with human-like precision
await client.send("Human.click", {"x": x, "y": y, "button": "left"})
# Type search query
await client.send("Human.type", {"text": "Surfsky cloud browser"})
# Get submit button coordinates
click_box = await page.locator('button[type="submit"]').bounding_box()
x = click_box["x"] + click_box["width"] / 2
y = click_box["y"] + click_box["height"] / 2
# Move mouse naturally to submit button
await client.send("Human.moveTo", {"x": x, "y": y})
# Click submit button
await client.send("Human.click", {"x": x, "y": y, "button": "left"})
# Wait for results to load
await page.wait_for_selector(".results")
# Scroll down naturally
await client.send("Human.scroll", {"deltaY": 500, "duration": 1.5})
async function searchExample(page) {
// Create CDP session for human-like actions
const client = await page.context().newCDPSession(page);
await page.goto("https://duckduckgo.com", { waitUntil: "load" });
// Wait for search input to be ready
await page.waitForSelector('input[name="q"]');
// Get search box coordinates
const searchBox = await page.locator('input[name="q"]').boundingBox();
const x = searchBox.x + searchBox.width / 2;
const y = searchBox.y + searchBox.height / 2;
// Click on search box with human-like precision
await client.send("Human.click", { x, y, button: "left" });
// Type search query
await client.send("Human.type", { text: "Surfsky cloud browser" });
// Get submit button coordinates
const clickBox = await page.locator('button[type="submit"]').boundingBox();
const btnX = clickBox.x + clickBox.width / 2;
const btnY = clickBox.y + clickBox.height / 2;
// Move mouse naturally to submit button
await client.send("Human.moveTo", { x: btnX, y: btnY });
// Click submit button
await client.send("Human.click", { x: btnX, y: btnY, button: "left" });
// Wait for results to load
await page.waitForSelector(".results");
// Scroll down naturally
await client.send("Human.scroll", { deltaY: 500, duration: 1.5 });
}
Form Filling with Natural Behavior
- Python
- JavaScript
async def fill_form_naturally(page, client):
# Form fields with typing speeds
fields = [
{"selector": "#name", "text": "John Smith", "wpm": 70},
{"selector": "#email", "text": "[email protected]", "wpm": 60},
{"selector": "#message", "text": "This is a test message", "wpm": 80}
]
for field in fields:
# Get element position
element = await page.locator(field["selector"]).bounding_box()
x = element["x"] + element["width"] / 2
y = element["y"] + element["height"] / 2
# Move to field
await client.send("Human.moveTo", {"x": x, "y": y})
# Click to focus
await client.send("Human.click", {
"x": x,
"y": y,
"button": "left"
})
# Type with specified speed
await client.send("Human.type", {
"text": field["text"],
"wpm": field["wpm"]
})
# Natural pause between fields
await asyncio.sleep(0.5)
async function fillFormNaturally(page, client) {
// Form fields with typing speeds
const fields = [
{ selector: "#name", text: "John Smith", wpm: 70 },
{ selector: "#email", text: "[email protected]", wpm: 60 },
{ selector: "#message", text: "This is a test message", wpm: 80 },
];
for (const field of fields) {
// Get element position
const element = await page.locator(field.selector).boundingBox();
const x = element.x + element.width / 2;
const y = element.y + element.height / 2;
// Move to field
await client.send("Human.moveTo", { x, y });
// Click to focus
await client.send("Human.click", {
x,
y,
button: "left",
});
// Type with specified speed
await client.send("Human.type", {
text: field.text,
wpm: field.wpm,
});
// Natural pause between fields
await page.waitForTimeout(500);
}
}
Scrolling and Navigation
- Python
- JavaScript
async def navigate_page(page, client):
# Smooth scroll down
await client.send("Human.scroll", {
"deltaY": 300,
"duration": 1.0 # 1 second smooth scroll
})
# Scroll to element
element = await page.locator(".target-section").bounding_box()
current_position = await page.evaluate("window.pageYOffset")
scroll_distance = element["y"] - current_position - 100 # 100px offset
await client.send("Human.scroll", {
"deltaY": scroll_distance,
"duration": 2.0 # 2 second smooth scroll
})
async function navigatePage(page, client) {
// Smooth scroll down
await client.send("Human.scroll", {
deltaY: 300,
duration: 1.0, // 1 second smooth scroll
});
// Scroll to element
const element = await page.locator(".target-section").boundingBox();
const currentPosition = await page.evaluate("window.pageYOffset");
const scrollDistance = element.y - currentPosition - 100; // 100px offset
await client.send("Human.scroll", {
deltaY: scrollDistance,
duration: 2.0, // 2 second smooth scroll
});
}
CDP Action Parameters
- Python
- JavaScript
# Human.click parameters
await client.send("Human.click", {
# Either x,y coordinates OR selector is required
"x": 100, # X coordinate
"y": 200, # Y coordinate
# OR
"selector": "button.submit", # CSS selector (alternative to x,y)
"button": "left", # "left", "right", or "middle"
})
# Human.moveTo parameters
await client.send("Human.moveTo", {
# Either x,y coordinates OR selector is required
"x": 300, # Target X coordinate
"y": 400, # Target Y coordinate
# OR
"selector": "#target-element", # CSS selector (alternative to x,y)
"duration": 0.8, # Optional: movement duration in seconds
})
# Human.type parameters
await client.send("Human.type", {
"text": "Hello World", # Text to type
"wpm": 60, # Optional: Words per minute (typing speed)
"typoRate": 0.02, # Optional: typo probability (default: 0)
})
# Human.scroll parameters
await client.send("Human.scroll", {
"deltaY": 500, # Vertical scroll distance (positive = down)
"deltaX": 0, # Optional: horizontal scroll distance
"duration": 1.5, # Scroll animation duration in seconds
})
// Human.click parameters
await client.send("Human.click", {
// Either x,y coordinates OR selector is required
x: 100, // X coordinate
y: 200, // Y coordinate
// OR
selector: "button.submit", // CSS selector (alternative to x,y)
button: "left", // "left", "right", or "middle"
});
// Human.moveTo parameters
await client.send("Human.moveTo", {
// Either x,y coordinates OR selector is required
x: 300, // Target X coordinate
y: 400, // Target Y coordinate
// OR
selector: "#target-element", // CSS selector (alternative to x,y)
duration: 0.8, // Optional: movement duration in seconds
});
// Human.type parameters
await client.send("Human.type", {
text: "Hello World", // Text to type
wpm: 60, // Optional: Words per minute (typing speed)
typoRate: 0.02, // Optional: typo probability (default: 0)
});
// Human.scroll parameters
await client.send("Human.scroll", {
deltaY: 500, // Vertical scroll distance (positive = down)
deltaX: 0, // Optional: horizontal scroll distance
duration: 1.5, // Scroll animation duration in seconds
});
Direct Selector Usage
Instead of calculating coordinates, you can use CSS selectors directly with Human.click
and Human.moveTo
:
- Python
- JavaScript
# Click using CSS selector
await client.send("Human.click", {
"selector": "button[type='submit']"
})
# Move to element using CSS selector
await client.send("Human.moveTo", {
"selector": "#menu-item"
})
# Click with additional options
await client.send("Human.click", {
"selector": "button.primary-btn",
"button": "left"
})
# Move to element with duration
await client.send("Human.moveTo", {
"selector": "a.nav-link",
"duration": 0.8
})
// Click using CSS selector
await client.send("Human.click", {
selector: 'button[type="submit"]',
});
// Move to element using CSS selector
await client.send("Human.moveTo", {
selector: "#menu-item",
});
// Click with additional options
await client.send("Human.click", {
selector: "button.primary-btn",
button: "left",
});
// Move to element with duration
await client.send("Human.moveTo", {
selector: "a.nav-link",
duration: 0.8,
});