Trace Scraper
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
httpxfor fast static pages,Playwrightfor 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.typedmarker
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.
Metadata
Release files for trace-scraper 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| trace_scraper-1.0.0.tar.gz | 18.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| trace_scraper-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 35.0 kB
Release files / trace_scraper-1.0.0.tar.gz
| Download URL | trace_scraper-1.0.0.tar.gz |
|---|---|
| Size | 18.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7ff0936745f11c2a6e116849d74e47e52d2d755fee41f3c93afe1df3711f3e84
|
|
BLAKE2b-256 checksum How to use checksums |
f6aff93ad6cc151d1c5e66fec312879aabb56a803c3eb9b3604651fedb1a8b89
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.10
|
Release files / trace_scraper-1.0.0-py3-none-any.whl
| Download URL | trace_scraper-1.0.0-py3-none-any.whl |
|---|---|
| Size | 17.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f94f98def9e8d0e4e87e8dde45cfcf2606b645aa776b5404c901d158dd5e9075
|
|
BLAKE2b-256 checksum How to use checksums |
0209b20e98c880d9cb4d91b4211d797f1acf824b93a32ac2907d22198b5fb963
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.10
|