Multi-engine stealth fetch layer for Python scraping—anti-bot bypass from TLS fingerprinting to CDP browsers, with optional auto-escalation.
Project description
StealthPlex
Stealth web scraping when basic HTTP gets blocked — Cloudflare (Turnstile, interstitial), Akamai, Imperva, Datadome, and similar bot walls.
StealthPlex wraps the tools you'd reach for anyway — wreq, curl_cffi, cloudscraper, Scrapling, and SeleniumBase — behind a single Fetch() interface with built-in stealth: randomized browser fingerprints (User-Agent, Sec-CH-UA, Sec-Fetch-*, Accept-Language, Referer), automatic TLS/JA3 impersonation, and serial engine escalation from fast HTTP all the way to stealth browser UC/CDP automation (headed on Windows/macOS, auto-Xvfb on Linux).
from StealthPlex import Fetch
# Zero config — stealth headers + serial engine fallback
fetch = Fetch()
resp = fetch.get("https://protected-site.com")
print(resp.text) # HTML
print(resp.json()) # or JSON
print(resp.engine) # which engine bypassed
Fallback chain: curl_cffi → wreq → cloudscraper → scrapling → seleniumbase
Each request gets randomized stealth fingerprints. If one engine gets blocked, the next one takes over automatically.
Install
1. Installation
StealthPlex core has no default engine dependencies to remain lightweight. You must install at least one engine extra to perform requests.
Recommended: Install all engines
Using uv:
uv add StealthPlex --extra all
Using pip:
pip install "StealthPlex[all]"
Install individual engines
wreq (Rust TLS / HTTP2 Impersonation)
Using uv:
uv add StealthPlex --extra wreq
Using pip:
pip install "StealthPlex[wreq]"
curl_cffi (libcurl Impersonation)
Using uv:
uv add StealthPlex --extra curl_cffi
Using pip:
pip install "StealthPlex[curl_cffi]"
cloudscraper (Cloudflare Solver)
Using uv:
uv add StealthPlex --extra cloudscraper
Using pip:
pip install "StealthPlex[cloudscraper]"
scrapling (Playwright-based Stealth Browser)
Using uv:
uv add StealthPlex --extra scrapling
Using pip:
pip install "StealthPlex[scrapling]"
seleniumbase (UC/CDP Mode Browser)
Using uv:
uv add StealthPlex --extra seleniumbase
Using pip:
pip install "StealthPlex[seleniumbase]"
Install multiple specific engines
Using uv:
uv add StealthPlex --extra curl_cffi --extra seleniumbase
Using pip:
pip install "StealthPlex[curl_cffi,seleniumbase]"
2. Upgrading Engines (Bypass Updates)
Because anti-bot protections change constantly, you should keep all engine packages updated to their latest versions:
Using uv:
uv add --upgrade "StealthPlex[all]"
Using pip (requires --upgrade-strategy eager to force upgrade of all extra engines):
pip install --upgrade --upgrade-strategy eager "StealthPlex[all]"
Engines
| Engine | Extra | Layer | Upstream | Detailed Docs |
|---|---|---|---|---|
wreq |
wreq |
L1 | 0x676e67/wreq-python | wreq Guide |
curl_cffi |
curl_cffi |
L1 | lexiforest/curl_cffi | curl_cffi Guide |
cloudscraper |
cloudscraper |
L2 | VeNoMouS/cloudscraper | cloudscraper Guide |
scrapling |
scrapling |
L3 | D4Vinci/Scrapling | scrapling Guide |
seleniumbase |
seleniumbase |
L4 | seleniumbase/SeleniumBase | seleniumbase Guide |
Quick Start — Stealth Fallback (Default)
Just call Fetch() — no engine needed. StealthPlex injects stealth headers and walks the engine chain serially until one bypasses.
Basic GET — Parse HTML or JSON
from StealthPlex import Fetch
fetch = Fetch()
# GET with full stealth headers auto-injected
resp = fetch.get("https://httpbin.org/get")
print(resp.status_code)
print(resp.text) # raw HTML/text
print(resp.json()) # auto-parse JSON
print(resp.engine) # "wreq", "curl_cffi", etc.
print(resp.attempts) # ("wreq",) or ("wreq", "curl_cffi")
print(resp.ok) # True if status < 400
POST with JSON body
from StealthPlex import Fetch
fetch = Fetch()
resp = fetch.post(
"https://httpbin.org/post",
json={"username": "admin", "password": "secret"},
headers={"X-Custom": "value"},
)
print(resp.json())
PUT, DELETE, PATCH, HEAD, OPTIONS
from StealthPlex import Fetch
fetch = Fetch()
# PUT with raw data
resp = fetch.put("https://httpbin.org/put", data="update payload")
print(resp.json())
# DELETE
resp = fetch.delete("https://httpbin.org/delete")
print(resp.status_code)
# PATCH with JSON
resp = fetch.patch("https://httpbin.org/patch", json={"key": "val"})
print(resp.json())
# HEAD (status + headers only)
resp = fetch.head("https://httpbin.org/get")
print(resp.status_code, resp.headers)
# OPTIONS
resp = fetch.options("https://httpbin.org/get")
print(resp.status_code)
Custom Headers, Cookies, Params, Redirects
from StealthPlex import Fetch
fetch = Fetch()
# All parameters work with full IDE autocomplete
resp = fetch.get(
"https://httpbin.org/get",
headers={"Authorization": "Bearer token123"},
cookies={"session": "abc123"},
params={"q": "stealth scraping", "page": "1"},
timeout=30.0,
allow_redirects=False, # or redirect=False
)
print(resp.status_code)
print(resp.json())
Custom Fallback Order
from StealthPlex import Fetch
# Only try these two engines in this order
fetch = Fetch(fallback=["curl_cffi", "cloudscraper"])
resp = fetch.get("https://example.com")
print(resp.engine)
Engine-Specific Examples
For full upstream API access (types, autocomplete, docs), bind to a specific engine:
wreq (TLS Impersonation - Async)
import asyncio
from StealthPlex import Fetch
async def main():
fetch = Fetch(engine="wreq")
response = await fetch.get("https://example.com", emulation=fetch.Emulation.Firefox149)
print(await response.text())
asyncio.run(main())
curl_cffi (TLS Impersonation - Sync/Async)
from StealthPlex import Fetch
fetch = Fetch(engine="curl_cffi")
response = fetch.get("https://example.com", impersonate="chrome124")
print(response.text)
cloudscraper (Cloudflare Session Bypass)
from StealthPlex import Fetch
fetch = Fetch(engine="cloudscraper")
scraper = fetch.create_scraper(browser="chrome")
response = scraper.get("https://example.com")
print(response.text)
scrapling (Stealth Browser Fetch & Selector)
from StealthPlex import Fetch
fetch = Fetch(engine="scrapling")
response = fetch.fetcher.fetch("https://example.com")
print(response.text)
seleniumbase (Hard-Target Browser UC/CDP Automation)
from StealthPlex import Fetch
fetch = Fetch(engine="seleniumbase")
with fetch.SB(uc=True) as sb:
sb.activate_cdp_mode("https://example.com")
sb.sleep(2.0)
print(sb.get_page_source())
API Summary
| Need | Use | Docs |
|---|---|---|
| Stealth auto-bypass (recommended) | Fetch() |
— |
| Custom engine order | Fetch(fallback=["wreq", "curl_cffi"]) |
— |
| Full wreq API | Fetch(engine="wreq") |
Guide |
| Full curl_cffi API | Fetch(engine="curl_cffi") |
Guide |
| Full cloudscraper API | Fetch(engine="cloudscraper") |
Guide |
| Adaptive fetch (Scrapling) | Fetch(engine="scrapling") |
Guide |
| Full SeleniumBase API | Fetch(engine="seleniumbase") |
Guide |
| Shortcuts | curl_fetch(), wreq_fetch(), cloudscraper_fetch(), scrapling_fetch(), seleniumbase_fetch() |
— |
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file stealthplex-0.0.2.tar.gz.
File metadata
- Download URL: stealthplex-0.0.2.tar.gz
- Upload date:
- Size: 14.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
76661db5d250d8b3ae440711e1b587c85ec3423442400e3ca70d77e1a8b3247f
|
|
| MD5 |
3dc7f4172baf0a7d5480bf579605e451
|
|
| BLAKE2b-256 |
7619e0afe0ea94afddca3cec24e938b9ffb6dbd3d8d187907c81dacd60c306fb
|
Provenance
The following attestation bundles were made for stealthplex-0.0.2.tar.gz:
Publisher:
pypi-publish.yml on SSujitX/StealthPlex
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stealthplex-0.0.2.tar.gz -
Subject digest:
76661db5d250d8b3ae440711e1b587c85ec3423442400e3ca70d77e1a8b3247f - Sigstore transparency entry: 1601853617
- Sigstore integration time:
-
Permalink:
SSujitX/StealthPlex@e2a3460090fc542f9121dad64b42ba6e1aa232ae -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/SSujitX
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@e2a3460090fc542f9121dad64b42ba6e1aa232ae -
Trigger Event:
push
-
Statement type:
File details
Details for the file stealthplex-0.0.2-py3-none-any.whl.
File metadata
- Download URL: stealthplex-0.0.2-py3-none-any.whl
- Upload date:
- Size: 17.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8665a9fa87484d1970abb82f219dbed079eead433b61e8779e9343e2c5f84cd1
|
|
| MD5 |
7630d92c56fcd20c33a8fb134c1ab475
|
|
| BLAKE2b-256 |
da268c25346bb0d11ca229b810d90d5e3656c5c6ea9c23f1db16f64674782e61
|
Provenance
The following attestation bundles were made for stealthplex-0.0.2-py3-none-any.whl:
Publisher:
pypi-publish.yml on SSujitX/StealthPlex
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stealthplex-0.0.2-py3-none-any.whl -
Subject digest:
8665a9fa87484d1970abb82f219dbed079eead433b61e8779e9343e2c5f84cd1 - Sigstore transparency entry: 1601853626
- Sigstore integration time:
-
Permalink:
SSujitX/StealthPlex@e2a3460090fc542f9121dad64b42ba6e1aa232ae -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/SSujitX
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@e2a3460090fc542f9121dad64b42ba6e1aa232ae -
Trigger Event:
push
-
Statement type: