Skip to content

kkb-98/synthetic-behavior

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

synthetic-behavior

Human behavior simulation library for browser automation. Generates realistic mouse movements (Bezier curves + Fitts' Law), keyboard input (WPM + typos), scroll patterns (easing curves), and human-like timing.

Framework-agnostic — works with Selenium, Playwright, Puppeteer, or any automation tool.

Install

pip install synthetic-behavior

Only dependency: numpy>=1.24

Quick Start

Mouse Movement

Generates curved paths with Bezier interpolation, Fitts' Law timing, jitter, and occasional overshoot.

from synthetic_behavior import MouseSimulator

mouse = MouseSimulator()
path = mouse.generate_path(100, 100, 500, 300)

len(path)    # 55 points (varies by distance)
path[0]      # (98.59, 97.16, 50.31)  — (x, y, delay_ms)
path[-1]     # (499.49, 299.09, 54.86)

Each point is (x, y, delay_ms). Total movement time follows Fitts' Law — longer distances take more time. The velocity profile is bell-shaped (minimum-jerk model): slow start, fast middle, slow end.

offset = mouse.click_offset(40, 40)  # gaussian offset from center
delay = mouse.hover_delay()           # delay before clicking (~80ms mean)

Keyboard Input

Generates keystroke events with realistic timing, shift handling, and occasional typos with backspace correction.

from synthetic_behavior import KeyboardSimulator

kb = KeyboardSimulator(wpm=60)
events = kb.generate_keystrokes("Hello")

len(events)  # 12 events
# [
#   {'key': 'Shift', 'type': 'keydown', 'delay_ms': 41},
#   {'key': 'H',     'type': 'keydown', 'delay_ms': 50},
#   {'key': 'H',     'type': 'keyup',   'delay_ms': 21},
#   {'key': 'Shift', 'type': 'keyup',   'delay_ms': 23},
#   {'key': 'e',     'type': 'keydown', 'delay_ms': 44},
#   {'key': 'e',     'type': 'keyup',   'delay_ms': 19},
#   ...
# ]

Typos are injected at ~3% rate by default, using nearby keys on a QWERTY layout, then corrected with Backspace.

Scroll

Generates scroll events with ease-in-out cubic easing and optional reading pauses.

from synthetic_behavior import ScrollSimulator

scroll = ScrollSimulator()
events = scroll.generate_scroll(0, 800)

len(events)  # 16 steps
events[0]    # {'delta_y': 1.0, 'delay_ms': 29.1}

Each event is {'delta_y': float, 'delay_ms': float}. The scroll accelerates then decelerates (ease-in-out). For long scrolls (>500px), there's a 30% chance of a reading pause mid-scroll.

Timing

from synthetic_behavior import TimingEngine

TimingEngine.wait_human(500, 2000)     # 1196.0 ms (gaussian, clamped)
TimingEngine.page_read_time(5000)      # 231700.6 ms (based on ~250 WPM)
TimingEngine.click_delay()             # 144.4 ms (delay before click)

API Reference

MouseSimulator(jitter_px=1.5, overshoot_prob=0.3, speed_factor=1.2)

Method Returns Description
generate_path(start_x, start_y, end_x, end_y, target_width=20) list[(x, y, delay_ms)] Bezier path with Fitts' Law timing
click_offset(target_width=20, target_height=20) (dx, dy) Gaussian offset from target center
hover_delay() float Pre-click hover delay in ms

KeyboardSimulator(wpm=60.0, typo_rate=0.03)

Method Returns Description
generate_keystrokes(text) list[dict] Keystroke events with timing

ScrollSimulator(speed=1.0)

Method Returns Description
generate_scroll(start_y, target_y) list[dict] Scroll events with easing

TimingEngine

Method Returns Description
wait_human(min_ms=500, max_ms=2000) float Human-like wait duration
page_read_time(content_length) float Estimated reading time in ms
click_delay() float Pre-click delay in ms

Integration Example

# Selenium
from synthetic_behavior import MouseSimulator, KeyboardSimulator
from selenium.webdriver.common.action_chains import ActionChains

mouse = MouseSimulator()
kb = KeyboardSimulator()

# Move mouse to element
path = mouse.generate_path(0, 0, elem.location['x'], elem.location['y'])
for x, y, delay in path:
    ActionChains(driver).move_by_offset(x, y).perform()
    time.sleep(delay / 1000)

# Type text
for event in kb.generate_keystrokes("search query"):
    if event['type'] == 'keydown':
        elem.send_keys(event['key'])
    time.sleep(event['delay_ms'] / 1000)

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages