Modern websites block standard automation tools within seconds. Cloudflare detects Selenium, DataDome flags Puppeteer, and even Playwright triggers bot warnings.
Botright solves these problems by mimicking human browser behavior using real Chromium fingerprints and built-in CAPTCHA solvers. This guide shows you how to use Botright for undetected web scraping, including installation, code examples, and advanced techniques.
What Is Botright?
Botright lets you automate browsers without getting detected by anti-bot systems. Built on Playwright, it removes automation signatures like the navigator.webdriver property and spoofs browser fingerprints using scraped Chrome data.
Unlike standard tools, Botright uses local Chromium browsers to create genuine sessions. It also includes free AI-powered CAPTCHA solvers for reCAPTCHA, hCaptcha, and other challenges.
Why Use Botright?
Standard automation tools fail against modern detection. Here's why Botright works better:
Detection Evasion: Removes WebDriver flags and randomizes fingerprints across canvas, WebGL, and audio contexts.
Free CAPTCHA Solving: Solves reCAPTCHA and hCaptcha using computer vision. No paid APIs required.
Real Browser Automation: Runs actual Chromium or Firefox instances instead of headless environments that trigger red flags.
Asynchronous Operations: Handles multiple scraping tasks simultaneously, though not thread-safe by default.
Botright vs Other Tools
| Feature | Botright | Selenium | Playwright | Puppeteer |
|---|---|---|---|---|
| WebDriver Detection | ✅ Removed | ❌ Visible | ⚠️ Partially Hidden | ⚠️ Partially Hidden |
| Fingerprint Spoofing | ✅ Built-in | ❌ Manual | ❌ Manual | ❌ Manual |
| CAPTCHA Solving | ✅ Free AI | ❌ None | ❌ None | ❌ None |
| Setup Complexity | Medium | Low | Low | Medium |
| Python Version | ≤3.10 | Any | Any | N/A (Node.js) |
| Best For | Stealth scraping | Simple automation | Fast automation | Node.js projects |
Installing Botright
Botright requires Python 3.10 or lower. Newer versions cause dependency conflicts.
Step 1: Create Virtual Environment
Set up an isolated environment with Python 3.10:
python3.10 -m venv botright_env
source botright_env/bin/activate # Windows: botright_env\Scripts\activate
This prevents conflicts with other Python projects.
Step 2: Install Botright
Use the --use-pep517 flag to avoid installation errors:
pip install --use-pep517 botright
playwright install
The Playwright command downloads required browser binaries.
Step 3: Install Ungoogled Chromium (Optional)
Download Ungoogled Chromium for maximum stealth. This privacy-focused browser removes Google tracking.
Botright automatically detects and uses it. No configuration needed.
Basic Botright Usage
This example shows how Botright navigates to a website and takes a screenshot:
import asyncio
import botright
async def basic_scrape():
# Initialize Botright client
client = await botright.Botright(headless=False)
# Create browser instance
browser = await client.new_browser()
page = await browser.new_page()
# Navigate to target site
await page.goto("https://bot.sannysoft.com")
# Take screenshot
await page.screenshot(path="bot_test.png")
# Cleanup
await client.close()
if __name__ == "__main__":
asyncio.run(basic_scrape())
Set headless=False during development to watch the browser. Change to headless=True for production.
Each browser instance gets unique fingerprints, making concurrent sessions undetectable.
How to Scrape Dynamic Content
Websites with infinite scrolling need special handling. Botright can automate scrolling to load all content:
async def scrape_infinite_scroll():
client = await botright.Botright(headless=True)
browser = await client.new_browser()
page = await browser.new_page()
await page.goto("https://example.com/products")
# Auto-scroll to bottom
last_height = 0
while True:
await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
await page.wait_for_timeout(2000)
new_height = await page.evaluate("document.body.scrollHeight")
if new_height == last_height:
break
last_height = new_height
# Extract data after all content loads
products = await page.query_selector_all(".product-item")
await client.close()
This scrolls until no new content appears, ensuring complete data extraction.
Solving CAPTCHAs With Botright
Botright includes AI-powered solvers for popular CAPTCHAs. No external services needed.
Solving reCAPTCHA
async def solve_recaptcha_example():
client = await botright.Botright()
browser = await client.new_browser()
page = await browser.new_page()
# Navigate to CAPTCHA-protected page
await page.goto("https://www.google.com/recaptcha/api2/demo")
# Solve CAPTCHA automatically
solution = await page.solve_recaptcha()
if solution:
print(f"CAPTCHA solved! Token: {solution[:50]}...")
await page.click('input[type="submit"]')
await client.close()
The solve_recaptcha() method handles detection, solving, and token submission. Success rates range from 70-85%.
Solving hCaptcha
hCaptcha requires the sitekey parameter:
async def solve_hcaptcha_example():
client = await botright.Botright()
browser = await client.new_browser()
page = await browser.new_page()
await page.goto("https://accounts.hcaptcha.com/demo")
# Solve with sitekey
solution = await page.solve_hcaptcha(
sitekey="00000000-0000-0000-0000-000000000000"
)
if solution:
print("hCaptcha bypassed!")
await client.close()
Replace the sitekey with the actual value from the target website. Find it in the page source.
Advanced Fingerprint Spoofing
Botright randomizes browser fingerprints to avoid detection. Enable advanced mode for maximum stealth:
async def advanced_stealth():
client = await botright.Botright(
headless=False,
mask_fingerprint=True # Enable fingerprint randomization
)
browser = await client.new_browser(
proxy="username:password@ip:port",
viewport={"width": 1920, "height": 1080},
locale="en-US",
timezone_id="America/New_York"
)
page = await browser.new_page()
# Test fingerprint
await page.goto("https://abrahamjuliot.github.io/creepjs/")
await page.wait_for_timeout(10000)
await client.close()
Use residential proxies for best results. Datacenter IPs get flagged instantly.
Production-Ready Scraper Pattern
This class-based approach handles errors, retries, and resource cleanup properly:
import asyncio
import logging
from typing import Optional
import botright
class BotrightScraper:
def __init__(self, headless: bool = True):
self.headless = headless
self.client = None
self.browser = None
self.logger = logging.getLogger(__name__)
async def initialize(self):
self.client = await botright.Botright(
headless=self.headless,
mask_fingerprint=True
)
self.browser = await self.client.new_browser()
async def scrape_with_retry(self, url: str, max_retries: int = 3):
for attempt in range(max_retries):
page = None
try:
page = await self.browser.new_page()
await page.goto(url, wait_until="domcontentloaded")
# Handle CAPTCHAs
if await page.query_selector(".g-recaptcha"):
await page.solve_recaptcha()
content = await page.content()
return content
except Exception as e:
self.logger.error(f"Attempt {attempt + 1} failed: {e}")
await asyncio.sleep(2 ** attempt)
finally:
if page:
await page.close()
return None
async def cleanup(self):
if self.browser:
await self.browser.close()
if self.client:
await self.client.close()
This pattern includes exponential backoff, automatic CAPTCHA detection, and proper cleanup.
Handling Concurrent Scraping
Botright isn't thread-safe. Create separate instances for parallel operations:
async def scrape_worker(url: str):
client = await botright.Botright(headless=True)
browser = await client.new_browser()
page = await browser.new_page()
try:
await page.goto(url)
content = await page.content()
return content
finally:
await client.close()
async def parallel_scraping(urls: list):
tasks = [scrape_worker(url) for url in urls]
results = await asyncio.gather(*tasks)
return results
Each worker gets its own Botright instance to prevent conflicts.
Memory Management for Scale
Process URLs in batches to avoid memory issues:
async def batch_scraping(urls: list, batch_size: int = 5):
results = []
for i in range(0, len(urls), batch_size):
batch = urls[i:i + batch_size]
client = await botright.Botright(headless=True)
browser = await client.new_browser()
batch_results = []
for url in batch:
page = await browser.new_page()
await page.goto(url)
content = await page.content()
batch_results.append(content)
await page.close()
results.extend(batch_results)
await client.close()
await asyncio.sleep(1)
return results
Close pages immediately after use. The sleep allows garbage collection between batches.
Common Botright Mistakes
Mistake 1: Using Python 3.11+
Problem: Dependency conflicts break installation.
Solution: Always use Python 3.10 or lower. Create dedicated virtual environments.
Mistake 2: Running Headless for Tough Sites
Problem: Some sites detect headless mode despite Botright's patches.
Solution: Use headless=False for sites with advanced detection. Run on virtual displays for servers.
Mistake 3: Not Handling Thread Safety
Problem: Multiple threads share one Botright instance, causing deadlocks.
Solution: Create one client per thread or use asyncio.gather() for concurrent operations.
Mistake 4: Forgetting to Close Resources
Problem: Memory leaks crash long-running scrapers.
Solution: Always call await client.close() in a finally block or use proper cleanup methods.
Mistake 5: Ignoring Rate Limits
Problem: Rapid requests trigger anti-bot systems even with Botright.
Solution: Add random delays between requests. Respect robots.txt and rate limits.
Botright Limitations
Botright isn't perfect. Know these limitations:
Python Version Restriction: Only works with Python 3.10 or lower. Incompatible with modern frameworks requiring 3.11+.
CAPTCHA Success Rates: Solves 70-85% of reCAPTCHA challenges. Complex puzzles may still block you.
Advanced Anti-Bot Systems: Struggles with enterprise-grade protection from Cloudflare Turnstile, DataDome, and Akamai when configured aggressively.
Resource Intensive: Browser automation uses significant CPU and memory. Not ideal for massive concurrent operations.
Not Thread-Safe: Requires careful architecture for parallel processing. Creates complexity in multi-threaded applications.
When to Use Botright Alternatives
Consider other tools if:
- You need Python 3.11+ compatibility
- Scraping requires 99%+ reliability
- Budget allows paid CAPTCHA solving services
- Targeting enterprise sites with cutting-edge protection
For simple scraping without anti-bot measures, standard Playwright or Requests libraries work fine.
Botright Best Practices
Use Quality Proxies: Residential proxies dramatically improve success rates. Avoid datacenter IPs.
Implement Retry Logic: Network issues and CAPTCHA failures happen. Build in automatic retries with exponential backoff.
Monitor Success Rates: Track which sites work and which fail. Adjust strategies based on data.
Respect Website Terms: Use Botright ethically. Honor robots.txt, rate limits, and terms of service.
Keep Ungoogled Chromium Updated: Download new versions periodically to maintain stealth effectiveness.
Complete Scraping Example
This full example combines all techniques:
import asyncio
import botright
import csv
async def scrape_products():
client = await botright.Botright(
headless=True,
mask_fingerprint=True
)
browser = await client.new_browser()
page = await browser.new_page()
try:
await page.goto("https://example.com/products")
# Scroll to load all products
for _ in range(5):
await page.evaluate("window.scrollBy(0, 1000)")
await page.wait_for_timeout(1000)
# Extract product data
products = await page.query_selector_all(".product")
data = []
for product in products:
name = await product.query_selector(".name")
price = await product.query_selector(".price")
data.append({
"name": await name.inner_text(),
"price": await price.inner_text()
})
# Save to CSV
with open("products.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["name", "price"])
writer.writeheader()
writer.writerows(data)
print(f"Scraped {len(data)} products")
finally:
await client.close()
asyncio.run(scrape_products())
This script scrolls, extracts data, and exports to CSV with proper error handling.
Next Steps With Botright
You now know how to use Botright for web scraping without getting blocked.
Start with basic examples on test sites. Gradually add fingerprint spoofing and CAPTCHA solving as needed.
Monitor your success rates and adjust techniques based on target websites. Remember: the best automation looks human.