antibot-rs
Auto-managed Byparr / FlareSolverr client for bypassing bot detection in Rust web scrapers.
Features
- Provider-agnostic — Byparr, FlareSolverr, or any compatible Docker image
- Docker lifecycle — auto-pull, start, health-wait, optional auto-restart on failure, optional stop-on-drop
- Resource limits — memory / CPU / shm-size caps on the spawned container
- Rich
SolveRequest— GET/POST, custom headers and cookies, per-request proxy, browser fingerprint hints - Per-domain session cache — repeat solves for the same domain are cookie-cache hits
- Concurrent-solve coalescer — N parallel solves for one domain → 1 provider call
- Retry policy — exponential backoff with jitter
- Persistent sessions —
create_session()returns aSessionHandlefor multi-step flows - Metrics — lock-free counters: success rate, avg solve time, cache hits, coalesced waits, retries, restarts
- Debug / replay sink — dump every solved page + cookie metadata to disk for inspection
- Multi-instance pool — round-robin across multiple solver containers
solve_stream— bounded-concurrency stream of solved pages for batch jobs- Standalone challenge detection — cheap
detect_challenge(...)helpers, no solver call
When to use this
This crate is the right choice when you're scraping from sites that:
- Block requests with Cloudflare ("Just a moment…",
cf_clearancecookie) - Throw Turnstile / DataDome / PerimeterX / Akamai / Imperva challenges
- Require a fully-rendered page (JS execution, cookies issued by JS) before serving content
It is not the right tool for:
- Sites that block on TLS fingerprint (JA3/JA4) — you need
rquestor curl-impersonate; the headless browser inside Byparr/FlareSolverr leaks its own TLS shape - IP-based blocking / rate limits — pair this with a proxy via
default_proxy()or per-requestwith_proxy() - Sites that require passing a CAPTCHA (hCaptcha, reCAPTCHA v2 image grids) — Byparr handles invisible challenges, but image-CAPTCHAs need a paid solver
- Low-latency/high-throughput cases — every uncached solve takes 5–30 seconds because a real browser is loading the page
Comparison with alternatives
| Tool | Language | Approach | Where it fits |
|---|---|---|---|
| antibot-rs (this crate) | Rust client → Byparr/FlareSolverr | Headless browser via local Docker | Rust scrapers that need a typed, async, lifecycle-managed solver |
| FlareSolverr (raw HTTP) | n/a | Headless browser | Same as above, but you write your own client / lifecycle |
| Byparr (raw HTTP) | n/a | Modern FlareSolverr fork | Recommended provider; this crate's default |
rquest |
Rust | TLS fingerprint impersonation | Sites that block on JA3/JA4 — much faster than a full browser |
cloudscraper (Python) |
Python | JS interpreter, no browser | Older, mostly broken against current Cloudflare |
undetected-chromedriver (Python) |
Python | Patched Chromedriver | Long-running scrapers in Python |
| Paid services (ScraperAPI, ZenRows, Bright Data) | n/a | Hosted solver pool | When self-hosting Docker isn't an option |
Quick start
use ;
let client = builder
.provider
.auto_start
.enable_session_cache
.build
.await?;
let solution = client.solve.await?;
println!;
println!;
Full-featured client
use ;
use Duration;
let client = builder
.provider
.auto_start
.docker_limits
.enable_session_cache
.coalesce_solves
.retry // 3 attempts, exponential backoff with jitter
.default_proxy
.debug
.health_watch // restart container if it stops responding
.manage_lifecycle // stop container when client drops
.build
.await?;
// POST with custom headers, cookies, and a per-request proxy override.
let solution = client.execute.await?;
// Inspect runtime stats.
let m = client.metrics;
println!;
Persistent sessions
use SolveRequest;
let session = client.create_session.await?;
let _login = session.execute.await?;
let dash = session.solve.await?;
println!;
session.destroy.await?; // or just let it drop
Batch with bounded concurrency
use StreamExt;
let urls = vec!;
let mut stream = client.solve_stream;
while let Some = stream.next.await
Multi-instance pool
let client = builder
.auto_start
.add_instance
.add_instance
.build
.await?;
// Requests now round-robin across all three URLs.
Challenge detection (no solver call)
Cheap header + body inspection, useful as a gate before invoking the (slow) solver:
use ;
use HeaderMap;
let headers = new;
let body = "<html><body>Just a moment...</body></html>";
let input = new;
if let Some = detect_challenge
Detects: Cloudflare, Turnstile, DataDome, PerimeterX, Akamai, Imperva, reCAPTCHA.
Connect to an existing instance
let client = connect;
let solution = client.solve.await?;
Requirements
- Docker installed and accessible (only when
auto_startis on) - One of: Byparr, FlareSolverr, or any compatible image with a
/v1endpoint
Troubleshooting
DockerNotAvailable on build()
You enabled auto_start(true) but the Docker daemon isn't running. Either start Docker Desktop, or
use Antibot::connect("http://...") against an externally-managed instance.
HealthCheckFailed after auto_start
The container started but isn't responding on the host port. Most common causes:
- Port collision — something else is bound to
8191. Pick another with.port(...). - Image is still warming up — bump
.health_check_attempts(30)(each attempt waits 2 seconds). - ARM64 host with an x86-only image — pull a multi-arch tag, or use
Provider::Custom(...).
Container immediately exits on slow / low-memory hosts
Chrome inside the container needs more shared memory than Docker's default 64MB. Apply
DockerLimits::default().shm_size("1g").
Solves succeed but cookies don't authenticate downstream requests
The Cookie header alone isn't enough — most modern protections also fingerprint the request's
User-Agent and TLS shape. Use Antibot::build_http_client(&solution.user_agent)? to copy the
solver's user-agent, and consider rquest for TLS fingerprint impersonation.
Repeated ChallengeFailed for one site
The provider's headless browser was detected. Try:
RetryPolicy::default()— sometimes the second attempt clears- A residential proxy via
default_proxy(...)— cloud IPs are blocked aggressively - Switch providers:
Provider::FlareSolverr↔Provider::Byparr
Build is slow / cargo pulls a lot of crates
This crate brings in reqwest (with rustls), dashmap, futures, and wiremock (dev-only).
The runtime dep tree is comparable to any other reqwest-based HTTP client.
License
MIT