Skip to main content

anti-bot-detector

PyPI - Version License: MIT Python

Framework-agnostic anti-bot detection for web crawlers — HTTP header fingerprinting, JS challenge identification, and proxy auto-rotation in one dependency-free core. Derived from crawl4ai's Anti-Bot Detection subsystem (Apache-2.0); zero crawl4ai imports, zero runtime dependencies.

Why

Every crawler eventually hits a WAF: Cloudflare challenges, DataDome blocks, rate-limit pages that look like real content. anti-bot-detector classifies responses before your parser wastes time on them, and tells you what to do next — proceed, rotate proxy, solve challenge, or back off.

  • Zero dependencies — the detection core is pure standard library
  • Framework-agnostic — adapters for httpx, scrapy, playwright and crawl4ai (all optional extras, lazily imported)
  • 3-layer detection — header fingerprints → JS challenge bodies → proxy auto-upgrade state machine
  • Apache-2.0 compliant — derivation scope documented in DESIGN.md, new code MIT-licensed

Installation

pip install anti-bot-detector

# with framework adapters (optional extras):
pip install anti-bot-detector[httpx]      # httpx integration
pip install anti-bot-detector[scrapy]     # scrapy downloader middleware
pip install anti-bot-detector[playwright] # playwright integration
pip install anti-bot-detector[dev]        # pytest + build + twine

Requires Python ≥ 3.9. Installing the base package does not install crawl4ai, httpx, scrapy or playwright.

Quick start

Classify a response you already have (no network needed):

from anti_bot_detector import AntiBotEngine, FetchResponse

engine = AntiBotEngine()
result = engine.detect_response(
    FetchResponse(
        url="https://example.com",
        status_code=503,
        headers={"cf-mitigated": "challenge", "server": "cloudflare"},
        body="<html>Just a moment...</html>",
    )
)
print(result.summary())
# https://example.com -> level=blocked challenge=cloudflare
#   confidence=0.90 action=rotate_proxy

Fetch + detect + auto-upgrade in one call:

from anti_bot_detector import AntiBotEngine

def fetch(url: str, headers: dict):
    import httpx  # any HTTP client works
    resp = httpx.get(url, headers=headers, timeout=10, follow_redirects=True)
    from anti_bot_detector import FetchResponse
    return FetchResponse(
        url=str(resp.url),
        status_code=resp.status_code,
        headers=dict(resp.headers),
        body=resp.text,
    )

engine = AntiBotEngine(
    fetcher=fetch,
    proxies=["http://proxy1:8080", "http://proxy2:8080"],
    max_retries=3,
)
result = engine.detect("https://target.example.com")
if result.recommended_action.value == "proceed":
    print("safe to crawl", result.url)

API reference

Core (anti_bot_detector)

Object Purpose
AntiBotEngine Unified entry point orchestrating all 3 layers
FetchResponse Minimal, framework-agnostic view of an HTTP response
DetectionResult Outcome of the pipeline: bot_level, challenge_type, confidence, recommended_action, summary()
BotLevel NONE / FINGERPRINT / CHALLENGE / BLOCKED
ChallengeType NONE / CLOUDFLARE / RECAPTCHA / HCAPTCHA / PERIMETERX / DATADOME / AKAMAI / CUSTOM
RecommendedAction PROCEED / ROTATE_PROXY / SOLVE_CHALLENGE / BACKOFF / ABORT
FingerprintGenerator Layer 1 — coherent browser-like header sets (UA pool, Sec-CH-UA, Sec-Fetch-*)
ProxyRotator Layer 3 — round-robin rotation, per-proxy cooldown, exhaustion fallback
StaticProxyProvider Trivial ProxyProvider backed by a fixed list

Key methods:

engine.detect_response(response: FetchResponse) -> DetectionResult  # layers 1+2
engine.detect(url: str) -> DetectionResult                          # fetch + layers 1-3
engine.fetch(url: str) -> DetectionResult                           # with auto-upgrade

rotator.current()                                  # active proxy or None (exhausted)
rotator.rotate(reason="soft-block")                # upgrade to next healthy proxy
rotator.mark_failed(proxy, reason="timeout")       # cooldown + rotate away

Adapters (anti_bot_detector.adapters)

Adapters are lazily imported — importing the package never pulls a framework.

Adapter Reduces Extra
HttpxAdapter httpx.Response → FetchResponse [httpx]
PlaywrightAdapter playwright Response → FetchResponse [playwright]
Crawl4AIAdapter crawl4ai AsyncWebCrawler result → FetchResponse [crawl4ai]
AntiBotMiddleware scrapy downloader middleware (drops blocked responses) [scrapy]

Integration examples

httpx client

import httpx
from anti_bot_detector import BotLevel
from anti_bot_detector.adapters import HttpxAdapter

def detect_url(url: str):
    with httpx.Client() as client:
        response = client.get(url, follow_redirects=True)
    verdict = HttpxAdapter().detect(response)
    if verdict.bot_level is BotLevel.BLOCKED:
        raise RuntimeError(f"WAF block: {verdict.summary()}")
    return verdict

scrapy downloader middleware

# settings.py
DOWNLOADER_MIDDLEWARES = {
    "anti_bot_detector.adapters.scrapy_middleware.AntiBotMiddleware": 560,
}
ANTIBOT_DROP_CHALLENGES = True  # also drop "challenge" pages, not just blocks

Blocked responses raise before they reach your spider callback, so parsers never see WAF error pages.

More runnable scripts in examples/: standalone_detect.py (pure Python, stdlib only) and httpx_integration.py (httpx client integration).

License

New code: MIT (see LICENSE). Derived from crawl4ai's Anti-Bot Detection subsystem, Apache-2.0 — see NOTICE and LICENSES/ for the upstream license and the derivation scope.

Metadata

Release files for anti-bot-detector 0.1.0

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

Source distribution (sdist)

Source distribution for anti-bot-detector 0.1.0
File Size Uploaded
anti_bot_detector-0.1.0.tar.gz 22.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for anti-bot-detector 0.1.0
File Interpreter ABI Platform
anti_bot_detector-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 44.7 kB

Release files / anti_bot_detector-0.1.0.tar.gz

Download URL anti_bot_detector-0.1.0.tar.gz
Size 22.3 kB
Tags Source
SHA-256 checksum
How to use checksums
e0e35dbb9be34cc81a9532c2252c259409d1bf74544e8d5a3da5df5cb78ee009
BLAKE2b-256 checksum
How to use checksums
45e604faf9f1bdd77cb88e5a15130a887094527a5bc41113af85d0f38cdd84bc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / anti_bot_detector-0.1.0-py3-none-any.whl

Download URL anti_bot_detector-0.1.0-py3-none-any.whl
Size 22.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d19f5109a3dcb5a805837ae9af0e49f1231fc8862847a93c5b10e88fe4ed6b90
BLAKE2b-256 checksum
How to use checksums
bdfa949377f4a4b77161ca714c4ce7777cb4843a71f576cb775bfc52c8c7176e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.1.0 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