Production web crawler vα»i N8N + API orchestration
# Start core services (API + N8N + Celery)
docker compose up -d
# Access services
# API Docs: http://localhost:8000/docs
# N8N: http://localhost:5678
# Flower: http://localhost:5555
# Test Dynamic Crawl API
curl -X POST http://localhost:8000/n8n/crawl/dynamic \
-H "Content-Type: application/json" \
-d '{"table_name": "test", "url_pattern": "https://example.com/{id}", "ids": ["1"], "selectors": {"title": ["h1"]}}'Core Services:
- β API: http://localhost:8000
- β API Docs: http://localhost:8000/docs
- β N8N: http://localhost:5678
- β Flower (Celery): http://localhost:5555
Optional: Add Airflow (heavy workflows)
docker compose -f docker-compose.yml -f docker-compose.airflow.yml up -d
# Airflow: http://localhost:8080 (admin/admin)N8N (Visual workflows) ββ
βββ PCrawler API ββ Celery Workers ββ Database
API (Direct access) βββββ (FastAPI) (Async crawl)
Optional: Airflow (Heavy batch workflows)
Extractors:
- lxml - Fast CSS/XPath (production)
- Crawl4AI - AI-powered extraction
- Regex - Emails, phones, URLs
- SmartExtractor - Auto-combine all (
strategy: "auto")
Perfect for:
- Company directories (1900.com.vn)
- E-commerce (product listings β details)
- Job boards (listings β job details)
- Real estate (listings β property details)
Setup:
# Edit: airflow/dags/pcrawler_two_phase_crawl.py
LIST_CRAWL_CONFIG = {
"base_url": "https://your-site.com/list",
"pages": range(1, 11), # Pages 1-10
"selectors": {
"links": {
"selector": "a.item", # β Your CSS selector
"attr": "href",
"multiple": True,
}
},
"pagination": {"param": "page", "type": "query_param"}
}
DETAIL_CRAWL_CONFIG = {
"selectors": {
"title": "h1.title", # β Your selectors
"price": "span.price",
"description": "div.desc",
},
"extract_emails": True,
"extract_phones": True,
"strategy": "auto",
}Run:
- Airflow UI β
pcrawler_two_phase_crawl - Click Play
- Monitor in Graph View
- Check database for results
See: AIRFLOW.md for complete guide
Use: Test selectors, quick crawl
DAG: pcrawler_simple_crawl
Use: Daily scheduled crawls
DAG: pcrawler_batch_crawl
Schedule: Edit schedule_interval='0 2 * * *' for daily at 2 AM
| File | What's Inside |
|---|---|
| AIRFLOW.md | Airflow guide, two-phase tutorial, config templates |
| N8N.md | N8N setup, workflows, API integration |
| REFERENCE.md | Cheatsheet, troubleshooting, test report |
# Open browser β DevTools (F12)
# List page: https://1900.com.vn/danh-sach-cong-ty?page=1
# Find: selector for company links (e.g., a.company-link)
# Detail page: https://1900.com.vn/cong-ty/example.html
# Find: selectors for name, address, phone, etc.File: airflow/dags/pcrawler_two_phase_crawl.py
LIST_CRAWL_CONFIG = {
"base_url": "https://1900.com.vn/danh-sach-cong-ty",
"pages": range(1, 4), # Test 3 pages first!
"selectors": {
"company_links": {
"selector": "a.YOUR-SELECTOR", # β Replace with actual
"attr": "href",
"multiple": True,
}
},
"pagination": {"param": "page", "type": "query_param"}
}
DETAIL_CRAWL_CONFIG = {
"selectors": {
"company_name": "h1.name", # β Replace
"address": ".address",
"phone": ".phone",
},
"extract_emails": True,
"extract_phones": True,
"strategy": "auto",
}# Airflow auto-detects DAG in ~30s
# UI: http://localhost:8080
# Trigger: pcrawler_two_phase_crawl
# Watch logs in Graph View# Expected logs:
# Phase 1: Found 60 URLs from 3 pages
# Phase 2: Success 58, Errors 2
# Query database:
docker compose exec api sqlite3 data/crawler_orchestrator.db \
"SELECT * FROM data_items WHERE execution_id LIKE 'detail_%' LIMIT 5;"Complete guide: AIRFLOW.md
Airflow imports Python directly:
from app.engine.workflow import WorkflowEngine
# No HTTP calls needed!API /n8n/* is only for N8N (external HTTP service).
Browser console:
document.querySelectorAll('a.your-selector')"pages": range(1, 3), # Only 2 pages for testingScale up after confirming selectors work.
| Issue | Fix |
|---|---|
| Phase 1 finds 0 URLs | Selector wrong β inspect HTML again |
| Phase 2 extracts wrong data | Field selector wrong β test in console |
| DAG not appearing | Wait 30s for auto-detect, check syntax errors |
| Scheduler unhealthy | Ignore - service running correctly |
Full troubleshooting: REFERENCE.md
Day 1: Basic Setup
docker compose up -d- Access Airflow UI
- Trigger
pcrawler_simple_crawl - Check logs
Day 2: Two-Phase Crawl
- Read AIRFLOW.md
- Inspect target website
- Edit
pcrawler_two_phase_crawl.py - Test with 2-3 pages
- Scale up if successful
Day 3: Production
- Set up scheduling
- Add error handling
- Export results
- Explore N8N for visual workflows
pcrawler/
βββ README.md β You are here
βββ AIRFLOW.md β Complete Airflow guide
βββ N8N.md β N8N setup & usage
βββ REFERENCE.md β Cheatsheet & troubleshooting
β
βββ airflow/dags/
β βββ pcrawler_two_phase_crawl.py β β Main DAG
β βββ pcrawler_simple_crawl.py
β βββ pcrawler_batch_crawl.py
β
βββ app/engine/
β βββ extractors.py β SmartExtractor, lxml, Crawl4AI, Regex
β βββ workflow.py
β βββ nodes/
β
βββ docker-compose.yml
- Dynamic Crawl: docs/QUICK-START-DYNAMIC-CRAWL.md - Crawl 20k+ URLs vα»i dynamic workflow
- Full Guide: docs/DYNAMIC-CRAWL-WORKFLOW.md - Complete documentation
- Scripts: scripts/README.md - Python CLI tools
- N8N Integration: N8N.md - Visual workflow automation
- Airflow (Optional): AIRFLOW.md - Heavy batch workflows
- API Reference: REFERENCE.md - Full API documentation
# Start/stop services
docker compose up -d
docker compose down
# View logs
docker compose logs -f api
docker compose logs -f worker
# Restart services
docker compose restart api worker
# Monitor tasks
# Flower: http://localhost:5555
# With Airflow (optional)
docker compose -f docker-compose.yml -f docker-compose.airflow.yml up -dπ Ready to crawl! Start with Quick Start Guide