A high-performance web crawler API built with Go
Extract content, discover URLs, and crawl websites at scale with real-time progress updates
Features β’ Quick Start β’ API β’ Examples β’ Contributing
|
|
|
|
# 1. Clone the repository
git clone https://github.com/LyzrCore/lyzr-crawl.git
cd lyzr-crawl
# 2. Set up environment
cp .env.example .env
# Edit .env with your MongoDB connection string
# 3. Start the crawler
docker-compose up -d
# 4. Check health
curl http://localhost:8080/healthClick to expand local setup instructions
# Prerequisites: Go 1.21+, MongoDB, RabbitMQ (optional)
# Install dependencies
go mod download
# Run with custom configuration
go run . \
-mongo-uri="mongodb://localhost:27017/crawler" \
-rabbitmq-url="amqp://localhost:5672/" \
-port=8080
# Build binary
go build -o crawler .
./crawlerAll API endpoints require authentication:
# Using header
curl -H "X-API-Key: your-api-key-here" http://localhost:8080/api/...
# Using Bearer token
curl -H "Authorization: Bearer your-api-key-here" http://localhost:8080/api/...| Method | Endpoint | Description |
|---|---|---|
GET |
/health |
Health check with system status |
POST |
/crawl |
Start a new crawl job |
POST |
/content |
Extract content from URLs |
GET |
/jobs |
List all crawl jobs |
GET |
/jobs/{id} |
Get specific job details |
WS |
/ws/{id} |
WebSocket for live updates |
GET |
/notforhumans/ |
Swagger UI documentation |
curl -X POST http://localhost:8080/crawl \
-H "X-API-Key: your-api-key-here" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"max_pages": 50,
"max_depth": 2
}'π View full crawl options
{
"url": "https://example.com",
"max_pages": 100,
"max_depth": 3,
"allowed_domains": ["example.com", "blog.example.com"],
"exclude_patterns": ["/admin", "/private"],
"include_patterns": ["/blog", "/docs"],
"respect_robots_txt": true,
"crawl_delay": 1000,
"timeout": 30,
"max_concurrent": 5,
"user_agent": "MyBot/1.0"
}curl -X POST http://localhost:8080/content \
-H "X-API-Key: your-api-key-here" \
-H "Content-Type: application/json" \
-d '{
"urls": [
"https://example.com/page1",
"https://example.com/page2"
],
"concurrency": 50
}'const ws = new WebSocket('ws://localhost:8080/ws/job-id-here');
ws.onmessage = (event) => {
const update = JSON.parse(event.data);
console.log(`Progress: ${update.progress}%`);
console.log(`URLs found: ${update.urls_found}`);
};graph TB
Client[Client Application] --> API[REST API]
API --> MongoDB[(MongoDB)]
API --> RabbitMQ[RabbitMQ]
API --> Crawler[Crawler Engine]
Crawler --> |Tier 1| Static[Static HTML]
Crawler --> |Tier 2| Browser[Headless Browser]
RabbitMQ --> WebSocket[WebSocket Handler]
WebSocket --> Client
style Client fill:#e1f5fe
style API fill:#fff3e0
style MongoDB fill:#c8e6c9
style RabbitMQ fill:#ffccbc
style Crawler fill:#f8bbd0
# Core Configuration
MONGO_URI=mongodb://localhost:27017/crawler # MongoDB connection
RABBITMQ_URL=amqp://localhost:5672/ # RabbitMQ (optional)
API_KEY=your-secure-api-key # API authentication
PORT=8080 # Server port
GIN_MODE=release # Framework mode
# Optional Services
SCRAPEOPS_API_KEY=your-key # Proxy rotation service| Parameter | Type | Default | Description |
|---|---|---|---|
max_pages |
int | 50 | Maximum pages to crawl |
max_depth |
int | 3 | Maximum crawl depth |
crawl_delay |
int | 1000 | Delay between requests (ms) |
timeout |
int | 30 | Request timeout (seconds) |
max_concurrent |
int | 5 | Concurrent requests |
respect_robots_txt |
bool | true | Follow robots.txt rules |
lyzr-crawl/
βββ config/ # Configuration files
β βββ database.go # Database config
β βββ rabbitmq.go # RabbitMQ config
β βββ scrapeops.go # ScrapeOps integration
βββ handlers/ # HTTP request handlers
β βββ content.go # Content extraction endpoints
β βββ crawl.go # Crawl job management
β βββ health.go # Health check endpoints
β βββ jobs.go # Job listing and status
β βββ websocket.go # WebSocket connections
βββ services/ # Core business logic
β βββ crawler.go # Main crawling engine
β βββ database.go # MongoDB operations
β βββ messaging.go # RabbitMQ messaging
β βββ robots.go # Robots.txt parser
β βββ sitemap.go # Sitemap parser
β βββ stealth.go # Anti-detection features
βββ models/ # Data structures
β βββ content.go # Content response models
β βββ crawl.go # Crawl request/response
β βββ events.go # Event models
β βββ job.go # Job tracking models
β βββ sitemap.go # Sitemap models
βββ middleware/ # HTTP middleware
β βββ auth.go # API key authentication
β βββ logging.go # Request logging
βββ utils/ # Helper functions
β βββ url.go # URL utilities
βββ docs/ # API documentation
β βββ docs.go # Generated docs
β βββ swagger.json # Swagger spec
β βββ swagger.yaml # Swagger spec
βββ ui/ # Web UI assets
β βββ index.html # Simple web interface
βββ main.go # Application entry point
βββ server.go # HTTP server setup
βββ docker-compose.yml # Docker composition
βββ Dockerfile # Container definition
βββ README.md # This file
We love contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Make your changes
- Test your changes locally
- Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
# Install dependencies
go mod download
# Build the project
go build -o lyzr-crawl .
# Run locally
./lyzr-crawl -mongo-uri="mongodb://localhost:27017/crawler"
# Generate Swagger docs
swag init -g server.go| Scenario | Requests/sec | Pages/min | Success Rate |
|---|---|---|---|
| Light Load (5 concurrent) | ~8 req/sec | ~480 pages/min | 95%+ |
| Medium Load (25 concurrent) | ~25 req/sec | ~1,500 pages/min | 94%+ |
| Heavy Load (50 concurrent) | ~40 req/sec | ~2,400 pages/min | 92%+ |
| Stress Test (100 concurrent) | ~60 req/sec | ~3,600 pages/min | 89%+ |
- JavaScript rendering: Adds ~50-100ms overhead per page
Common issues and solutions
# Check if MongoDB is running
docker-compose ps
# Verify connection string
echo $MONGO_URI
# Test connection
mongosh "$MONGO_URI"- Ensure RabbitMQ is running
- Check CORS settings if connecting from browser
- Verify job ID is valid
- Reduce
max_concurrentsetting - Lower
max_pageslimit - Enable swap if needed
This project is licensed under the MIT License - see the LICENSE file for details.
Built with these amazing tools:
- Go - The programming language
- Rod - Browser automation
- Gorilla Mux - HTTP router
- MongoDB - Database
- RabbitMQ - Message broker (optional)
Lyzr Crawl - Part of the Lyzr.ai ecosystem