How to Use Botright for Web Automation in 2025

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.