Plataforma que agrega avisos de autos en venta desde portales chilenos, normaliza los datos, los almacena en PostgreSQL y detecta oportunidades de compra mediante análisis de historial de precios.
Stack actual: Python 3.12 + httpx/Playwright · PostgreSQL (Supabase) · S3 + CloudFront · Astro 5 + Vercel
EC2 + TMUX (ingesta)
└─ Scrapers (Autocosmos, Yapo)
├─ Fotos raw/AVIF → S3 → CloudFront (CDN)
└─ Metadata validada → PostgreSQL
Vercel (web)
└─ Astro 5 SSR
├─ Consulta PostgreSQL vía Supabase JS client
└─ Imágenes desde CloudFront
Cada scraper implementa el pipeline completo dentro de scrape():
- Paginación HTTP (httpx + BS4) o navegación headless (Playwright)
- Descarga de fotos →
data/raw/fotos/ - Conversión a AVIF →
data/processed/fotos/ - Upload a S3 con retry (12 × 10 min)
- Append a
data/raw/avisos.jsonl - Deduplicación → validación →
data/processed/avisos.jsonl - Upload de metadata y
run_report.jsona S3
ScraperBase.ejecutar() recibe el resultado y hace upsert en PostgreSQL. Las imágenes AVIF se sirven a la web desde CloudFront (CDN_BASE_URL).
| Fuente | Técnica | Tabla PostgreSQL |
|---|---|---|
| Autocosmos | httpx + BeautifulSoup4 | autocosmos_listings |
| Yapo | Playwright + stealth | yapo_listings |
Existe la tabla
mercadolibre_listingsreservada para un scraper futuro vía la API oficial, pero aún no está implementado ni registrado.
- Instancia EC2 (Amazon Linux 2023,
t3.smallrecomendado) - PostgreSQL externo con base de datos
carflipcreada (p. ej. Supabase) - Bucket S3 + distribución CloudFront
- (Opcional) Bucket Cloudflare R2 — solo si se usa el script de migración
S3 → R2
ssh -i /ruta/a/tu-llave.pem ec2-user@<ip-publica>sudo dnf update -y
sudo dnf install -y tmux gitcurl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.local/bin/env
uv python install 3.12git clone https://github.com/DiegoPyLL/CarFlip
cd CarFlip
uv sync
uv run playwright install chromiumnano .env# Base de datos
DATABASE_URL=postgresql+asyncpg://usuario:password@host:5432/carflip
USE_SSL=true
# MercadoLibre API (opcional, para futuro scraper)
MERCADOLIBRE_APP_ID=tu_app_id
MERCADOLIBRE_CLIENT_SECRET=tu_client_secret
# S3 — almacenamiento de fotos (raw + AVIF)
S3_ACCESS_KEY_ID=tu_access_key
S3_SECRET_ACCESS_KEY=tu_secret_key
S3_REGION=us-east-1
S3_BUCKET=carflip-raw
S3_PREFIX=autocosmos/
# CloudFront — CDN que sirve las imágenes a la web
CDN_BASE_URL=https://xxxxxxxxxx.cloudfront.net
# Cloudflare R2 — opcional, solo para el script de migración S3 → R2
R2_ACCOUNT_ID=tu_account_id
R2_BUCKET=carflip-fotos
R2_ACCESS_KEY_ID=tu_r2_access_key
R2_SECRET_ACCESS_KEY=tu_r2_secret_key
# Rate limiting
MIN_DELAY_SECONDS=2.0
MAX_DELAY_SECONDS=6.0
# Scheduler
SCRAPE_INTERVAL_HOURS=24
# Deals
DEAL_THRESHOLD_PCT=15.0
# Logs
LOG_LEVEL=INFO
LOG_FILE=logs/carflip.logCtrl+O → Enter → Ctrl+X para guardar.
uv run alembic upgrade headtmux new -s carflip
source .venv/bin/activate
# Prueba única
carflip run
# Scheduler automático (cada SCRAPE_INTERVAL_HOURS horas)
carflip startDesconectarse sin detener el proceso: Ctrl+B → D
Reconectar: tmux attach -t carflip
| Comando | Descripción |
|---|---|
carflip run |
Ejecuta todos los scrapers una vez |
carflip run --scraper autocosmos |
Ejecuta un scraper específico |
carflip start |
Inicia el scheduler automático |
carflip market <marca> <modelo> <año> |
Estadísticas de mercado |
Los scrapers corren de forma secuencial (uno a la vez), con una pausa configurable entre cada uno. Scrapers registrados actualmente: autocosmos, yapo.
La web está en web/ y se despliega en Vercel. Es un proyecto Astro 5 SSR (con React + Tailwind) que consulta PostgreSQL vía el cliente JS de Supabase y sirve las imágenes desde CloudFront.
Requisitos: Node.js 20+
# 1. Entrar a la carpeta web
cd web
# 2. Instalar dependencias
npm install
# 3. Crear web/.env con las claves de SupabaseContenido de web/.env:
SUPABASE_URL=https://<tu-proyecto>.supabase.co
SUPABASE_SERVICE_KEY=<service_role key desde Supabase → Settings → API>
CDN_BASE_URL=https://<tu-distribucion>.cloudfront.net# 4. Levantar servidor de desarrollo
npm run devAbrir: http://localhost:4321
No se necesita PostgreSQL local, Python ni ninguna otra dependencia. Todo conecta directo a Supabase vía HTTPS.
Configurar como variables de servidor las mismas tres claves:
SUPABASE_URL=https://<tu-proyecto>.supabase.co
SUPABASE_SERVICE_KEY=<service_role key>
CDN_BASE_URL=https://<tu-distribucion>.cloudfront.netuv sync # instalar/actualizar dependencias
alembic upgrade head # aplicar migraciones
alembic revision --autogenerate -m "descripcion" # nueva migración
pytest # correr tests
pytest -x -v tests/test_price_tracker.py # test específico- Crear
src/carflip/scrapers/NombreSitio/NombreSitioCloud.pyheredando deScraperBase - Crear
NuevoSitioListing(ListingMixin, Base)ensrc/carflip/database/models.py - Generar y aplicar migración Alembic
- Declarar
model_classyfuenteen el scraper - Registrar en
src/carflip/scheduler/runner.py - Actualizar los 5 archivos de la web (
tipos.ts,filtros.ts,FiltrosBarra.astro,db.ts,index.astro)
Ver checklist completo en CLAUDE.md.
carflip: command not found al reconectar SSH
source .venv/bin/activate
# o sin activar:
.venv/bin/carflip startTimeouts o errores en Yapo (Playwright)
Aumentar delays en .env:
MIN_DELAY_SECONDS=3.0
MAX_DELAY_SECONDS=8.0- CLAUDE.md — arquitectura, convenciones y decisiones de diseño
