Skip to main content

High-performance async web scraper with Playwright and httpx. Scrape JavaScript-rendered pages, crawl websites recursively, parse sitemaps, and extract content with anti-bot bypass.

Project description

Trace Scraper

PyPI version Python 3.11+ License: MIT CI

High-performance async web scraper for Python. Scrape JavaScript-rendered pages, crawl websites recursively, parse sitemaps, and extract clean content — all with built-in anti-bot bypass.

Why Trace Scraper?

  • Hybrid Engine: Uses httpx for fast static pages, Playwright for JavaScript-heavy sites
  • Anti-Bot Bypass: Built-in detection evasion with realistic browser fingerprints
  • Async & Parallel: Scrape hundreds of pages concurrently with asyncio
  • Multiple Modes: Single page, recursive crawl, sitemap parsing, URL lists
  • Clean Output: Automatic HTML cleanup, content deduplication, PDF extraction
  • Type Safe: Full type hints with py.typed marker

Installation

pip install trace-scraper

Install Playwright browsers (required for JS rendering):

playwright install chromium

Quick Start

Command Line

# Scrape a single page
trace https://example.com

# Crawl entire website
trace https://docs.example.com --mode recursive --max-pages 100

# Parse sitemap
trace https://example.com/sitemap.xml --mode sitemap

# Use browser for JavaScript sites
trace https://spa-website.com --browser

# Save to JSON
trace https://example.com -o output.json

Python API

import asyncio
from trace_scraper import WebScraper, ScrapeMode

async def main():
    async with WebScraper() as scraper:
        async for doc in scraper.scrape("https://example.com", mode=ScrapeMode.SINGLE):
            print(f"Title: {doc.semantic_identifier}")
            print(f"Content: {doc.sections[0].text}")

asyncio.run(main())

Advanced Configuration

from trace_scraper import WebScraper, ScraperConfig, ScrapeMode

config = ScraperConfig(
    max_concurrent_pages=20,     # Parallel scraping
    page_timeout=15.0,           # Timeout per page
    scroll_pages=True,           # Load lazy content
    extract_pdfs=True,           # Extract PDF text
    use_browser_for_all=False,   # Use httpx when possible
)

async with WebScraper(config) as scraper:
    async for doc in scraper.scrape(
        "https://docs.example.com",
        mode=ScrapeMode.RECURSIVE
    ):
        print(doc.semantic_identifier)

CLI Options

Option Short Default Description
--mode -m single Mode: single, recursive, sitemap
--output -o - Save results to JSON file
--concurrency -c 10 Max concurrent pages
--timeout -t 30 Page timeout (seconds)
--max-pages - - Limit pages to scrape
--browser - - Force browser for all pages
--scroll - - Scroll to load dynamic content
--delay -d 0.1 Delay between requests
--verbose -v - Enable debug logging

Configuration Options

Option Type Default Description
max_concurrent_pages int 10 Pages to scrape in parallel
max_concurrent_browsers int 3 Browser contexts pool size
page_timeout float 30.0 Page load timeout
request_timeout float 10.0 HTTP request timeout
max_retries int 3 Retry attempts per page
delay_between_requests float 0.1 Rate limiting delay
scroll_pages bool False Scroll for lazy-loaded content
extract_pdfs bool True Extract text from PDFs
deduplicate_content bool True Skip duplicate pages
use_browser_for_all bool False Always use Playwright
headless bool True Run browser headless

Features

Scraping Modes

  • Single: Scrape one URL
  • Recursive: Crawl entire site following internal links
  • Sitemap: Parse sitemap.xml and scrape all URLs
  • URL List: Scrape a provided list of URLs

Content Extraction

  • Automatic removal of scripts, styles, navigation, footers
  • Clean text extraction with structure preservation
  • Link extraction with markdown formatting
  • PDF text extraction (optional dependency)

Anti-Bot Features

  • Realistic browser fingerprints
  • Custom User-Agent and headers
  • Stealth mode scripts
  • Automatic retry with browser fallback

Development

# Clone repository
git clone https://github.com/boxed-dev/trace.git
cd trace

# Install with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run linter
ruff check .

# Type check
mypy trace_scraper

License

MIT License - see LICENSE for details.

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

trace_scraper-1.0.0.tar.gz (18.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

trace_scraper-1.0.0-py3-none-any.whl (17.1 kB view details)

Uploaded Python 3

File details

Details for the file trace_scraper-1.0.0.tar.gz.

File metadata

  • Download URL: trace_scraper-1.0.0.tar.gz
  • Upload date:
  • Size: 18.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.10

File hashes

Hashes for trace_scraper-1.0.0.tar.gz
Algorithm Hash digest
SHA256 7ff0936745f11c2a6e116849d74e47e52d2d755fee41f3c93afe1df3711f3e84
MD5 4f34dd55c1b097a4529fc443d04fbee2
BLAKE2b-256 f6aff93ad6cc151d1c5e66fec312879aabb56a803c3eb9b3604651fedb1a8b89

See more details on using hashes here.

File details

Details for the file trace_scraper-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: trace_scraper-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 17.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.10

File hashes

Hashes for trace_scraper-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f94f98def9e8d0e4e87e8dde45cfcf2606b645aa776b5404c901d158dd5e9075
MD5 c7a393be8580be99fda1fe33d2c56c10
BLAKE2b-256 0209b20e98c880d9cb4d91b4211d797f1acf824b93a32ac2907d22198b5fb963

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page