Large-scale web scraping platform with Python workers, MongoDB storage, and Redis job queue.
- Multiple scraper types: HTTP (HTML) and API (JSON) scrapers
- Flexible extraction: CSS selectors, XPath, and JSONPath support
- Rate limiting: Per-domain rate limiting via Redis sliding window
- Retry logic: Exponential backoff with configurable retry attempts
- Pipeline processing: Composable steps for cleaning, transforming, and validating data
- Change detection: Monitor periodic scrapes for content changes
- MongoDB storage: Async storage with automatic TTL for old results
- Redis queue: Distributed job queue with dead letter queue for failures
New to the platform? Start with the Tutorial (15 minutes)
Complete documentation:
- Tutorial - Step-by-step getting started guide
- Overview - Complete technical documentation
- Documentation Index - Navigation and search guide
# 1. Install dependencies
uv pip install -e ".[dev]"
# 2. Start services
docker compose up -d mongodb redis
# 3. Verify setup
python scripts/verify_setup.py
# 4. Enqueue a job (new terminal)
python scripts/enqueue_job.py \
--url "https://quotes.toscrape.com" \
--type http \
--selectors '{"quotes": {"selector": "span.text", "type": "css", "multiple": true}}'
# 5. Start worker (new terminal)
python scripts/run_worker.py
# 6. View results at http://localhost:8082 (Mongo Express)See Tutorial for detailed walkthrough.
ββββββββββββββββββββ ββββββββββββββββββββ
β Redis ββββββΆβ Python Workers β
β (Job Queue) βββββββ (Scraper Pool) β
ββββββββββ¬ββββββββββ ββββββββββ¬ββββββββββ
β β
β βΌ
β ββββββββββββββββ
ββββββββββββββββββΆβ MongoDB β
β (Storage) β
ββββββββββββββββ
- Python 3.12+
- Docker and Docker Compose (for local dev services)
-
Clone and navigate to directory:
cd scraper -
Install dependencies (using uv, pip, or poetry):
# Using uv (recommended - fastest) uv pip install -e ".[dev]" # Or using pip pip install -e ".[dev]"
-
Set up environment variables:
cp .env.example .env # Edit .env with your configuration -
Start local services:
docker compose up -d mongodb redis
Optional web UIs:
- Redis Commander: http://localhost:8081
- Mongo Express: http://localhost:8082 (admin/admin)
# Scrape HTML page
python scripts/enqueue_job.py \
--url "https://quotes.toscrape.com" \
--type http \
--selectors '{
"quotes": {"selector": "span.text", "type": "css", "multiple": true},
"authors": {"selector": "small.author", "type": "css", "multiple": true}
}'
# Scrape JSON API
python scripts/enqueue_job.py \
--url "https://api.example.com/data" \
--type api \
--selectors '{
"items": {"selector": "data.items", "type": "jsonpath"},
"total": {"selector": "meta.total", "type": "jsonpath"}
}' \
--headers '{"Authorization": "Bearer YOUR_TOKEN"}'python scripts/run_worker.py
# With debug logging
python scripts/run_worker.py --log-level DEBUGQuery MongoDB directly or use Mongo Express (http://localhost:8082):
// In MongoDB shell or Mongo Express
db.results.find().sort({scraped_at: -1}).limit(10)Edit .env to configure:
- MongoDB:
MONGO_URI,MONGO_DB_NAME - Redis:
REDIS_URL,REDIS_JOB_QUEUE - Worker:
WORKER_CONCURRENCY,WORKER_MAX_RETRIES - Rate Limiting:
RATE_LIMIT_DEFAULT_REQUESTS,RATE_LIMIT_DEFAULT_WINDOW_SECONDS - HTTP:
HTTP_TIMEOUT_SECONDS,HTTP_USER_AGENT - Storage:
RESULT_TTL_DAYS,STORE_RAW_HTML
{
"fields": {
"title": {
"selector": "h1.title",
"type": "css",
"attribute": "text"
},
"links": {
"selector": "a.product-link",
"type": "css",
"attribute": "href",
"multiple": true
}
}
}{
"fields": {
"price": {
"selector": "//span[@class='price']/text()",
"type": "xpath"
}
}
}{
"fields": {
"items": {
"selector": "data.items[*]",
"type": "jsonpath"
},
"next_page": {
"selector": "links.next",
"type": "jsonpath"
}
}
}# Run all tests
pytest
# Run with coverage
pytest --cov=scraper --cov-report=html
# Run specific test file
pytest tests/test_http_scraper.pyscraper/
βββ scraper/
β βββ models/ # Job and Result schemas
β βββ scrapers/ # HTTP and API scrapers
β βββ extractors/ # CSS, XPath, JSONPath extractors
β βββ config.py # Configuration management
β βββ db.py # MongoDB connection
β βββ worker.py # Job consumer
β βββ pipeline.py # Post-scrape processing
β βββ rate_limiter.py # Redis rate limiter
βββ scripts/ # CLI utilities
βββ tests/ # Test suite
- Create
scraper/extractors/my_extractor.py - Inherit from
BaseExtractor - Implement
extract(content, config)method - Register in
scraper/extractors/__init__.py - Add tests in
tests/test_extractors.py
Worker not processing jobs:
- Check Redis connection:
redis-cli ping - Verify job queue has items:
redis-cli LLEN scraper:jobs - Check worker logs for errors
MongoDB connection failed:
- Ensure MongoDB is running:
docker compose ps - Verify MONGO_URI in
.env
Rate limit too strict:
- Adjust
RATE_LIMIT_DEFAULT_REQUESTSandRATE_LIMIT_DEFAULT_WINDOW_SECONDSin.env - Check rate limit stats in Redis:
redis-cli ZRANGE rate_limit:example.com 0 -1 WITHSCORES
- Phase 2: Elixir orchestrator with Phoenix API and job scheduler
- Phase 3: Domma dashboard for job management and monitoring
- Phase 4: Proxy rotation, headless browsers, distributed deployment
MIT