Skip to main content

Phantomime

PyPI version License: MIT Python >=3.10

Phantomime is a humanized Playwright browser with full anti-fingerprinting and real Chrome TLS impersonation via curl-cffi. It mimics human behavior at every layer — mouse movement, typing, scrolling, idle activity — while spoofing the browser's hardware and software fingerprint so that automated sessions are indistinguishable from real users.


Features

  • Canvas / WebGL fingerprint noise — deterministic per-session LCG, no canvas mutation
  • TLS fingerprint — Chrome 124+ via curl-cffi, bidirectional cookie sync with Playwright
  • Human mouse movement — cubic Bézier paths, overshooting, micro-tremor, Gaussian jitter
  • Human typing — QWERTY typos with autocorrect, frustration errors, log-normal delays
  • Scroll with inertia — progressive acceleration, matches browser physics
  • Idle behavior — random moves, scrolls, hover clusters, micro-tremor
  • 6 hardware profiles — Windows / macOS / Linux, OS-aware selection
  • navigator / screen coherence — platform, languages, plugins, Client Hints, battery, fonts
  • Network jitter — simulated via context-level route interception (covers Service Workers)
  • Session warmup & history — visit referrer sites before the target
  • Swarm execution — run_swarm (asyncio) and run_swarm_multiprocess (multiprocessing)

Installation

pip install phantomime
playwright install chromium

To use your system Chrome instead of Playwright's Chromium (better TLS):

pip install phantomime
# No playwright install needed

Quick start

import asyncio
from phantomime import HumanBrowser

async def main():
    async with HumanBrowser(profile_dir="./my_profile", headless=True) as browser:
        await browser.goto("https://example.com")
        title = await browser.get_title()
        print(title)

asyncio.run(main())

HumanBrowser parameters

Parameter Type Default Description
profile_dir str | Path "./hb_profile" Persistent profile directory. Its name seeds the fingerprint.
headless bool False Headless mode via --headless=new (preserves GPU pipeline).
locale str "es-ES" Browser locale — affects navigator.languages and Accept-Language.
timezone str "Europe/Madrid" Timezone ID. Match with your proxy IP.
proxy dict None {"server": "http://host:port", "username": "u", "password": "p"}
slow_mo float 0.0 Extra delay (ms) between Playwright actions.
fixed_profile bool False Always use profile 0 (reproducible fingerprint).
os_aware_profile bool True Pick a hardware profile matching the host OS.
disable_service_workers bool False Disable Service Workers in Chromium.
typo_rate float 0.04 QWERTY typo probability per character.
frustration_rate float 0.01 Frustration-error probability per character.
executable_path str None Path to system Chrome binary. None = Playwright's Chromium.

Available methods

Category Methods
Lifecycle launch, close, new_page
Navigation goto, get_url, get_title, wait_for_url, go_back, go_forward
Interaction click, type_text, select_option, press_key, hover, focus
Mouse move_to, move_to_selector, micro_tremor, pre_drift_to
Scroll scroll_down, scroll_up, scroll_to_element
HTTP (TLS) fetch, sync_cookies_to_session, sync_cookies_from_session, sync_cookies
Extraction get_text, get_all_text, get_attribute, is_visible, evaluate
Utilities screenshot, wait_for, wait_between_actions, idle, warmup, enable_network_jitter, warm_history

Direct HTTP with TLS fingerprint

Use fetch() when you need clean TLS without JS rendering (API calls, simple scraping). Cookies are synced automatically between Playwright and curl-cffi.

async with HumanBrowser(profile_dir="./profile") as browser:
    await browser.goto("https://example.com")          # log in via browser
    response = await browser.fetch(                    # call API with same session
        "https://api.example.com/data",
        method="GET",
        mode="xhr",
    )
    print(response.json())

mode controls Sec-Fetch-* headers — use "xhr", "cors", "navigate", or "no-cors" to match what a real browser would send.


Swarm execution

asyncio swarm (< 20 instances, same process)

from phantomime import HumanBrowser, run_swarm

async def scrape(browser: HumanBrowser, url: str) -> str:
    await browser.goto(url)
    return await browser.get_text("h1")

results = await run_swarm(
    task=scrape,
    items=["https://a.com", "https://b.com", "https://c.com"],
    max_concurrent=3,
    browser_kwargs={"headless": True},
)

Multiprocess swarm (large farms, full isolation)

import asyncio
from phantomime import HumanBrowser, run_swarm_multiprocess

def worker(url, profile_dir, browser_kwargs):
    async def _inner():
        async with HumanBrowser(profile_dir=profile_dir, **browser_kwargs) as browser:
            await browser.goto(url)
            return await browser.get_text("h1")
    return asyncio.run(_inner())

if __name__ == "__main__":
    results = run_swarm_multiprocess(
        task_fn=worker,
        items=["https://a.com", "https://b.com"],
        max_workers=2,
        browser_kwargs={"headless": True},
    )

License

MIT

Metadata

Release files for phantomime 9.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for phantomime 9.0.1
File Size Uploaded
phantomime-9.0.1.tar.gz 41.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for phantomime 9.0.1
File Interpreter ABI Platform
phantomime-9.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 65.1 kB

Release files / phantomime-9.0.1.tar.gz

Download URL phantomime-9.0.1.tar.gz
Size 41.1 kB
Tags Source
SHA-256 checksum
How to use checksums
c47710065c887b0eb7e9747fa6bc0d8680cf29e112b0e385ee549bee680c2f63
BLAKE2b-256 checksum
How to use checksums
8c97c32ad643d9369769e8a09e4c2a074bc0a1d13fbdb0e4e750b4d1db7a2032
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.2

Release files / phantomime-9.0.1-py3-none-any.whl

Download URL phantomime-9.0.1-py3-none-any.whl
Size 24.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e6f6b2fb5fdbc9cd6f4928dbabbe871c053feb734be1ddd8597b51bacf7d4674
BLAKE2b-256 checksum
How to use checksums
2404e073c08940b3ed2c7e478e97789706b523c6633d03590096af5230f54466
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.2

Release history Release notifications | RSS feed

This release

9.0.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page