Skip to main content

Anti-Fingerprinting HTTP client with easy TLS fingerprint spoofing

Project description

TLS-Chameleon

TLSChameleom

PyPI version

Anti-Fingerprinting HTTP client that spoofs real browser TLS fingerprints with a simple, requests-like API.

🆕 What's New in v2.0

  • AI-Urllib4 Adaptive Features:
    • Domain Memory: "Learns" which profile works for a specific domain and remembers it.
    • Adaptive Headers: Dynamically adjusts header casing and order (e.g., Title-Case for Firefox, lowercase for Chrome) to match the selected profile perfectly.
  • 45 Browser Profiles: Chrome, Firefox, Safari, Edge across Windows 10, Windows 11, macOS, Linux, iOS, Android.
  • Fingerprint Randomization: Slight variations to avoid pattern detection.
  • HTTP/2 Priority Simulation: Browser-specific HTTP/2 SETTINGS.
  • Auto-Update System: Fetch latest JA3 fingerprints from online sources.
  • Enhanced API: New TLSSession class with profile, randomize, http2_priority parameters.

🎯 Ideal For

  • Professional Scraping: Bypass Cloudflare, Akamai, and DataDome on E-commerce/Finance sites.
  • Stealth Automation: Mimic human behavior to avoid ML-based traffic analysis.
  • Cybersecurity / OSINT: Extract hidden JWTs, API keys, and metadata from protected portals.
  • Price Intelligence: Track competitors without being flagged or served "bot-only" prices.

🚀 Features

  • TLS Fingerprint Spoofing: Built-in profiles for Chrome, Firefox, Safari, Edge (uses curl_cffi for realistic signatures).
  • Multi-OS Support: Profiles for Windows 10, Windows 11, macOS, Linux, iOS, and Android.
  • Persistent Sessions: Proper cookie handling and connection pooling (just like requests.Session).
  • Magnet Module 🧲: One-line data extraction (Emails, Tables, Forms, JSON-LD, Links).
  • Smart Static ⚡: Automatically fetch page assets (CSS/JS/Images) to mimic real browser traffic.
  • Auto-Form 📝: Find and submit forms automatically, handling hidden inputs and CSRF tokens.
  • Humanize 🧠: Built-in delays to mimic human reading/typing speed.
  • Resilience: Auto-rotation of proxies/profiles upon blocking (403/429/Cloudflare).
  • Ghost Mode (Pro) 👻: Stealth traffic shaping with randomized timing and payload padding.
  • WAF Shield (Pro) 🛡️: Automatic detection and adaptation for Cloudflare, Akamai, and DataDome.
  • Header Morphing (Pro) 🧬: Dynamic casing and ordering to match specific browser signatures perfectly.
  • Deep Extract (Pro) 🕵️: Find hidden JWTs, API keys, and JS configs in any page.

📦 Install

You can install TLS-Chameleon directly from PyPI:

pip install tls-chameleon[curl]

Note: The [curl] extra is required for TLS fingerprint spoofing.

⚡ Quick Start

1. Simple Requests (Drop-in)

from tls_chameleon import get

# One-line spoofing
r = get("https://httpbin.org/get", fingerprint="chrome_124")
print(r.json())

2. Persistent Session (Recommended)

Use Session (alias for TLSChameleon) to maintain cookies across requests:

from tls_chameleon import Session

with Session(fingerprint="chrome_120") as client:
    # First request sets cookies
    client.get("https://github.com/login")
    
    # Second request sends them back!
    r = client.get("https://github.com/settings")

3. New v2.0 API with OS-Specific Profiles 🆕

from tls_chameleon import TLSSession

# Select specific browser + OS combination
session = TLSSession(
    profile='chrome_124_linux',     # Linux Chrome 124
    randomize=True,                  # Enable fingerprint randomization
    http2_priority='chrome'          # Match HTTP/2 behavior
)

# Make requests
response = session.get("https://example.com")

# Debug: see what fingerprint is being used
print(session.get_fingerprint_info())
# {
#     'profile_name': 'chrome_124_linux',
#     'user_agent': 'Mozilla/5.0 (X11; Linux x86_64)...',
#     'ja3_hash': 'cd08e31494f9531f560d64c695473da9',
#     'randomized': True,
#     ...
# }

📚 Available Profiles (v2.0)

By Browser

Browser Versions OS Support
Chrome 120, 124, 125 Windows 10, Windows 11, macOS, Linux, Android
Firefox 120, 124 Windows 10, Windows 11, macOS, Linux
Safari iOS 16, iOS 17, macOS 13, macOS 14 iOS, macOS
Edge 120, 124 Windows 10, Windows 11

Profile Naming Convention

{browser}_{version}_{os}

Examples:

  • chrome_124_win11 - Chrome 124 on Windows 11
  • chrome_124_linux - Chrome 124 on Linux
  • firefox_120_macos - Firefox 120 on macOS
  • safari_ios17 - Safari on iOS 17
  • edge_124_win10 - Edge 124 on Windows 10
  • chrome_android_124 - Chrome 124 on Android

Convenience Aliases

# Latest versions
'chrome_latest'        # Latest Chrome on Windows 11
'chrome_latest_linux'  # Latest Chrome on Linux
'firefox_latest'       # Latest Firefox
'safari_latest'        # Latest Safari
'edge_latest'          # Latest Edge

# Mobile
'mobile_safari'        # Safari iOS 17
'mobile_chrome'        # Chrome Android 124

List Available Profiles

from tls_chameleon import (
    list_available_profiles,
    get_profiles_by_browser,
    get_profiles_by_os
)

# All 45 profiles
all_profiles = list_available_profiles()
print(f"Total: {len(all_profiles)} profiles")

# Filter by browser
chrome_profiles = get_profiles_by_browser("chrome")
# ['chrome_120_win11', 'chrome_120_win10', 'chrome_120_linux', ...]

# Filter by OS
linux_profiles = get_profiles_by_os("linux")
# ['chrome_120_linux', 'chrome_124_linux', 'firefox_120_linux', ...]

🎲 Fingerprint Randomization

Enable slight variations to avoid pattern detection:

from tls_chameleon import TLSSession

# Each session gets a slightly different fingerprint
session = TLSSession(
    profile='chrome_124_win11',
    randomize=True  # Enable randomization
)

# Variations include:
# - Minor User-Agent version changes
# - TLS extension order shuffles (where browsers allow)
# - Slight cipher order variations

Manual Randomization

from tls_chameleon import FingerprintRandomizer, get_profile

# Get base profile
profile = get_profile("chrome_124_win11")

# Create randomizer
randomizer = FingerprintRandomizer(profile)

# Generate unique variants
variant1 = randomizer.generate_variant()
variant2 = randomizer.generate_variant()
# Each variant is slightly different but still looks like Chrome 124

🛠 API Reference

TLSSession / Session Parameters

Parameter Type Default Description
profile str None Profile name (e.g., 'chrome_124_linux'). New in v2.0
fingerprint str 'chrome_120' Legacy profile name (use profile for v2.0 profiles)
randomize bool False Enable fingerprint randomization. New in v2.0
http2_priority str None HTTP/2 priority simulation ('chrome', 'firefox', 'safari'). New in v2.0
engine str 'curl' HTTP engine ('curl' or 'httpx')
randomize_ciphers bool False Shuffle cipher suite order
timeout float 30.0 Request timeout in seconds
headers dict None Custom headers to add
proxies dict/str None Proxy configuration
rotate_profiles list None List of profiles to rotate through on blocks
on_block str 'rotate' Action on block ('rotate', 'proxy', 'both', 'none')
max_retries int 2 Max retry attempts
site str None Site preset ('cloudflare', 'akamai')
proxies_pool list None Pool of proxies to rotate
http2 bool None Force HTTP/2
verify bool True Verify SSL certificates
ghost_mode bool False Enable stealth traffic shaping

Session Methods

session = TLSSession(profile='chrome_124_win11')

# HTTP Methods
session.get(url, **kwargs)
session.post(url, **kwargs)
session.put(url, **kwargs)
session.delete(url, **kwargs)
session.head(url, **kwargs)
session.patch(url, **kwargs)
session.options(url, **kwargs)

# v2.0 Methods
session.get_fingerprint_info()  # Returns dict with profile details
session.sync_fingerprint(ja3=..., user_agent=...)  # Manually sync fingerprint

# Cookie Management
session.save_cookies("cookies.txt")
session.load_cookies("cookies.txt")

# Session State
session.export_session()  # Returns dict for persistence
session.import_session(state)  # Restore from dict

# Forms
session.submit_form(url, {"username": "x", "password": "y"})

# Human Delays
session.human_delay(reading_speed="normal")  # 'fast', 'normal', 'slow'

� AI-Urllib4 Adaptive Features (New!)

TLS-Chameleon now includes "AI-Urllib4" capabilities to intelligently adapt to target sites.

Domain Memory

The client automatically "learns" which browser profile works best for a specific domain. If a request succeeds with a specific profile (e.g., chrome_124_win11), the client remembers this association. Subsequent requests to the same domain will automatically switch to the known-good profile, regardless of the initial setting.

from tls_chameleon import TLSSession

# First request: Tries with default profile (e.g., Chrome)
# If it fails/rotates and eventually succeeds with Firefox, it remembers "example.com -> Firefox"
with TLSSession() as client:
    client.get("https://example.com")

# Later...
# Automatically switches to Firefox for example.com
with TLSSession() as client:
    client.get("https://example.com")

Adaptive Headers

Headers are no longer static. The client dynamically "morphs" header casing and ordering to match the specific browser profile being used.

  • Chrome/Edge: Headers are sent in lowercase (HTTP/2 standard behavior for Chromium).
  • Firefox/Safari: Headers utilize Title-Case where appropriate and follow specific ordering (e.g., Host first vs. User-Agent location).

This prevents detection systems from flagging mismatches between the TLS fingerprint (JA3) and the HTTP header structure.

�🧲 Magnet Extraction

AI Extraction (New! ✨)

Use Gemini, Claude, or OpenAI (ChatGPT/Grok) to extract data intelligently without regex.

# Install AI support
pip install tls-chameleon[ai]
r = client.get("https://news.ycombinator.com")

# 1. Google Gemini (Default)
print(r.magnet.ask("Summary", provider="gemini"))

# 2. Anthropic Claude
print(r.magnet.ask("Summary", provider="anthropic", model="claude-3-opus-20240229"))

# 3. OpenAI / Grok
# (Set OPENAI_API_KEY or pass api_key=...)
print(r.magnet.ask("Summary", provider="openai", model="gpt-4o"))

Standard Extractors

Don't write regex. Let Magnet do it.

r = client.get("https://example.com/contact")

emails = r.magnet.emails()        # ['support@example.com']
tables = r.magnet.tables()        # [['Row1', 'Val1'], ...]
links  = r.magnet.links()
forms  = r.magnet.get_forms()     # List of parsed forms
json_data = r.magnet.json_ld()    # Schema.org data

🍪 Cookie Persistence

Save your session to a Netscape-formatted file (compatible with wget/curl) to use later.

# Save
client.save_cookies("cookies.txt")

# Load later
client.load_cookies("cookies.txt")

🔄 Auto-Update Fingerprints (Optional)

Fetch the latest fingerprints from online sources:

from tls_chameleon import FingerprintUpdater

updater = FingerprintUpdater()

# Check for updates (downloads to ~/.tls_chameleon/cache/)
updated_count = updater.update_gallery()
print(f"Updated {updated_count} profiles")

# Get cache info
print(updater.get_cache_info())

🆚 Why use this vs curl_cffi?

Feature Raw curl_cffi TLS-Chameleon
TLS Spoofing You must manually set impersonate="chrome110" 45 profiles with OS-specific variants
Profile Selection Manual profile='chrome_124_linux'
Fingerprint Variation None randomize=True avoids pattern detection
Asset Loading You just get the HTML. mimic_assets=True: Fetches CSS/JS/Images
Forms You must manually parse CSRF tokens client.submit_form(): Auto-handles tokens
Data Extraction Use BeautifulSoup manually Magnet Module: emails, tables, json_ld
Blocking Recovery Manual retry Auto-rotation on 403/429

🔧 Advanced Usage

Multi-OS Scraping

from tls_chameleon import TLSSession

# Rotate between different OS fingerprints
profiles = [
    'chrome_124_win11',
    'chrome_124_linux',
    'chrome_124_macos',
]

for profile in profiles:
    session = TLSSession(profile=profile, randomize=True)
    response = session.get("https://target-site.com")
    print(f"{profile}: {response.status_code}")
    session.close()

Cloudflare Bypass with Profile Rotation

from tls_chameleon import TLSSession

session = TLSSession(
    profile='chrome_124_win11',
    site='cloudflare',  # Preset for Cloudflare sites
    rotate_profiles=[
        'chrome_124_win11',
        'chrome_120_linux',
        'firefox_124_win11',
    ],
    on_block='rotate',
    max_retries=3
)

response = session.get("https://cloudflare-protected-site.com")

Ghost Mode for Stealth

session = TLSSession(
    profile='chrome_124_win11',
    ghost_mode=True,  # Random delays + payload padding
    randomize=True
)

# Requests include random timing jitter and data padding
response = session.get("https://anti-bot-site.com")

🤝 Contributing

Issues and Pull Requests welcome!

🌟 Credits

Special thanks to curl_cffi for the amazing low-level TLS spoofing capabilities that power this library.

☕ Support / Donate

If you found this library useful, buy me a coffee!

zied

📜 License

MIT

🚨 Is this library failing on a specific site?

Please open an issue with the URL! I need test cases to improve the fingerprinting logic.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tls_chameleon-2.1.0.tar.gz (37.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tls_chameleon-2.1.0-py3-none-any.whl (35.0 kB view details)

Uploaded Python 3

File details

Details for the file tls_chameleon-2.1.0.tar.gz.

File metadata

  • Download URL: tls_chameleon-2.1.0.tar.gz
  • Upload date:
  • Size: 37.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for tls_chameleon-2.1.0.tar.gz
Algorithm Hash digest
SHA256 56848c0554215334cd19e0fde30f10f587a43ba9ae60451a59e7700be8db1703
MD5 5c7ba745f480dfd514d1d5c7126ef0cf
BLAKE2b-256 9dcadb216c7d9272939134fc25f8b69780769ea7a81907d70eb4217d13d7c052

See more details on using hashes here.

File details

Details for the file tls_chameleon-2.1.0-py3-none-any.whl.

File metadata

  • Download URL: tls_chameleon-2.1.0-py3-none-any.whl
  • Upload date:
  • Size: 35.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for tls_chameleon-2.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 220f3ac6535c40fb67f3c13323cad4b65cdf41560364d7a3ae982b74b5e952da
MD5 92ae20166bac8d6c859b77c81fbd7a80
BLAKE2b-256 9bda93dc58b0fc83fb79eeae20d6b53aeecab640ad62948f9bbeb62ce4b78fc0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page