# 🚀 Guida Ottimizzazione Scraping

## 📊 Sistema Ottimizzato - Architettura Completa

### 🎯 Parametri Chiave

| Parametro | Valore | Dove | Descrizione |
|-----------|--------|------|-------------|
| **Frontend Default** | 50 | ScraperView.vue | N. URL richiesti di default |
| **Frontend Max** | 100 | ScraperView.vue | Limite UI (validazione client) |
| **Backend Max** | 100 | .env `SCRAPING_MAX_SITES` | Limite reale accettato |
| **SerpAPI Per Request** | 50 | Hardcoded API | Max risultati per chiamata |
| **SerpAPI Pagination** | ✅ Abilitata | scraper.service.js | Fino a 100 risultati totali |
| **Timeout Per Sito** | 15s | .env `SCRAPING_TIMEOUT_MS` | Max attesa per pagina |
| **Delay Tra Siti** | 1s | .env `SCRAPING_DELAY_MS` | Pausa tra scraping |
| **Contact Pages** | 14 | scraper.service.js | Pagine extra per sito |

---

## 🔄 Flusso di Scraping Ottimizzato

```
1. Frontend invia query + maxUrls (es. 50)
          ↓
2. Backend valida: 1 ≤ maxUrls ≤ SCRAPING_MAX_SITES (100)
          ↓
3. SerpAPI: Chiamate multiple con pagination
   - Request 1: risultati 1-50
   - Request 2: risultati 51-100 (se richiesti)
   - Delay 1s tra requests
          ↓
4. Deduplica per dominio (1 URL per sito)
   Esempio: 80 URL → 60 domini unici
          ↓
5. Per ogni dominio (in parallelo, max 5 concurrent):
   a) Scraping pagina principale
   b) Scraping 14 pagine contatti:
      - /contatti, /contact, /contact-us
      - /chi-siamo, /about, /about-us
      - /team, /staff
      - /lavora-con-noi, /careers
      - /locations, /sedi, /uffici
          ↓
6. Circuit Breaker: Skip siti con 2+ fallimenti
          ↓
7. Estrazione email + info aziendali
          ↓
8. Validazione + Salvataggio in DB
```

---

## 📈 Stima Risultati per Query

### Scenario Conservativo (query: "carrozzeria milano")
```
Input: 50 URL richiesti
├─ SerpAPI: 50 risultati
├─ Deduplica domini: ~40 domini unici (20% duplicati)
├─ Circuit breaker: 5 siti falliscono (12.5%)
├─ Siti processati: 35
│
└─ Per ogni sito:
    ├─ Pagina principale: 0-3 email
    └─ 14 pagine contatti: 0-5 email
    
Risultato atteso: 35-140 email/contatti
```

### Scenario Ottimale (query: "studio commercialista torino")
```
Input: 100 URL richiesti
├─ SerpAPI: 100 risultati (2 requests)
├─ Deduplica domini: ~80 domini unici
├─ Circuit breaker: 8 siti falliscono (10%)
├─ Siti processati: 72
│
└─ Per ogni sito:
    ├─ Pagina principale: 1-2 email
    └─ 14 pagine contatti: 1-3 email
    
Risultato atteso: 144-360 email/contatti
```

---

## ⚙️ Variabili di Configurazione (.env)

### Variabili Utilizzate Attivamente

```bash
# Limite massimo di siti da processare
SCRAPING_MAX_SITES=100

# Timeout per ogni pagina (millisecondi)
SCRAPING_TIMEOUT_MS=15000

# Delay tra scraping di siti diversi
SCRAPING_DELAY_MS=1000

# User Agent per richieste
SCRAPING_USER_AGENT=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
```

### Variabili Non Utilizzate (Legacy)
```bash
# NOTA: Queste non influenzano il comportamento attuale
SCRAPING_MAX_PAGES=15  # Non usato (fisso a 1 + 14 contact)
```

---

## 🎚️ Come Massimizzare i Risultati

### 1. **Aumenta maxUrls nel Frontend**
```vue
<!-- Usa valori alti per query ampie -->
maxUrls: 80-100 per query generiche
maxUrls: 30-50 per query specifiche
```

### 2. **Ottimizza le Query Google**
✅ **Query Efficaci:**
- `"studio commercialista" + città`
- `"carrozzeria" + zona geografica`
- `"agenzia immobiliare" + provincia`
- `"idraulico" + CAP`

❌ **Query Inefficaci:**
- Troppo generiche: "negozio"
- Troppo specifiche: "Mario Rossi carrozzeria via Roma 123"

### 3. **Usa Filtri Geografici**
```
"categoria professionale" + località
```
Esempio: `avvocato milano zona porta romana`

### 4. **Esegui Query Multiple**
Invece di 1 query con 100 URL:
```
Query 1: "carrozzeria milano" (50 URL)
Query 2: "carrozzeria torino" (50 URL)
Query 3: "carrozzeria roma" (50 URL)
```
**Risultato:** 3x più contatti con deduplica automatica nel DB

### 5. **Monitora i Log**
```bash
# Verifica siti skippati dal circuit breaker
pm2 logs gix-demtools-backend --lines 100 | grep "circuit breaker"

# Verifica errori di timeout
pm2 logs gix-demtools-backend --lines 100 | grep "timeout"
```

---

## 🔧 Tuning Avanzato

### Aumentare Timeout per Siti Lenti
```bash
# .env
SCRAPING_TIMEOUT_MS=20000  # Da 15s a 20s
```
**Pro:** Meno timeout su siti lenti  
**Contro:** Scraping più lento

### Ridurre Delay Tra Siti
```bash
# .env
SCRAPING_DELAY_MS=500  # Da 1000ms a 500ms
```
**Pro:** Scraping più veloce  
**Contro:** Rischio rate limiting

### Disabilitare Circuit Breaker (Non Consigliato)
```javascript
// scraper.service.js
this.maxFailures = 999; // Praticamente disabilitato
```
**Pro:** Ritenta sempre tutti i siti  
**Contro:** Spreco risorse su siti offline

---

## 📊 Performance Monitoring

### Metriche da Monitorare
```sql
-- Email trovate per job negli ultimi 7 giorni
SELECT 
  DATE(created_at) as data,
  AVG(emails_found) as media_email,
  MAX(emails_found) as max_email,
  COUNT(*) as num_jobs
FROM scraping_jobs
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
  AND status = 'completed'
GROUP BY DATE(created_at);

-- Top query per risultati
SELECT 
  query,
  AVG(emails_found) as media_email,
  COUNT(*) as volte_eseguita
FROM scraping_jobs
WHERE status = 'completed'
GROUP BY query
ORDER BY media_email DESC
LIMIT 10;
```

### Dashboard Metrics
```javascript
// Aggiungi nel frontend
- Success Rate: (completed / total) * 100
- Avg Emails per Job: SUM(emails_found) / COUNT(jobs)
- Avg Processing Time: AVG(completed_at - created_at)
- Circuit Breaker Hit Rate: (skipped_sites / total_sites) * 100
```

---

## 🐛 Troubleshooting

### Pochi Risultati Nonostante Alto maxUrls

**Cause Possibili:**
1. ✅ **Deduplica domini:** 100 URL → 60 domini unici è normale
2. ✅ **Circuit breaker:** Siti che falliscono vengono skippati
3. ✅ **Siti senza email:** Molti siti moderni usano form invece di email
4. ✅ **Timeout:** Siti lenti vengono abbandonati dopo 15s

**Soluzioni:**
```bash
# 1. Aumenta timeout
SCRAPING_TIMEOUT_MS=20000

# 2. Verifica circuit breaker nei log
pm2 logs gix-demtools-backend | grep "circuit breaker"

# 3. Usa query più specifiche con siti "veri"
"studio legale milano" invece di "avvocato"
```

### Job Bloccato su "Processing"

**Cause:**
- Browser Puppeteer crashato
- Redis disconnesso
- Out of Memory

**Soluzioni:**
```bash
# 1. Verifica processi
ps aux | grep chrome

# 2. Verifica Redis
redis-cli ping

# 3. Restart backend
pm2 restart gix-demtools-backend

# 4. Clear stuck jobs
pm2 flush gix-demtools-backend
```

---

## 🎯 Best Practices

### ✅ Raccomandazioni

1. **Start Small, Scale Up**
   - Prima query: 30 URL
   - Verifica risultati
   - Aumenta gradualmente a 50-100

2. **Query Specifiche > Query Generiche**
   ```
   ✅ "carrozzeria milano zona 3"
   ❌ "carrozzeria"
   ```

3. **Monitora i Log Attivamente**
   ```bash
   pm2 logs gix-demtools-backend --lines 50
   ```

4. **Database Cleanup Periodico**
   ```sql
   -- Rimuovi job vecchi falliti
   DELETE FROM scraping_jobs 
   WHERE status = 'failed' 
     AND created_at < DATE_SUB(NOW(), INTERVAL 30 DAY);
   ```

5. **Rate Limiting SerpAPI**
   - Free Plan: 100 ricerche/mese
   - Con pagination (2 requests): 50 query/mese
   - Monitora usage su serpapi.com/dashboard

---

## 📞 Quick Reference

```bash
# Restart completo sistema
pm2 restart gix-demtools-backend
pm2 restart gix-demtools-frontend

# Verifica configurazione
cat backend/.env | grep SCRAPING

# Logs in tempo reale
pm2 logs gix-demtools-backend --lines 100 --raw

# Memoria utilizzata
pm2 info gix-demtools-backend

# Reset completo queue
redis-cli FLUSHDB
pm2 restart gix-demtools-backend
```

---

## 🔮 Futuri Miglioramenti

### In Roadmap
- [ ] Scraping parallelizzato (aumentare concorrenza)
- [ ] Cache risultati Google per 24h
- [ ] Retry intelligente per siti timeout
- [ ] Machine learning per predire siti con email
- [ ] Export risultati in CSV/Excel
- [ ] API pubblica per integrazioni

### Ottimizzazioni Potenziali
```javascript
// Concorrenza aumentata (attualmente 5)
const batchSize = 10; // Processa 10 siti simultaneamente

// Smart timeout basato su velocità sito
const adaptiveTimeout = avgResponseTime * 3;

// Prefetch DNS
await dns.resolve(domain);
```

---

**Last Updated:** 2025-02-12  
**Version:** 2.0 - Ottimizzazione Completa  
**Contact:** Backend Team
