Workflow N8N Template
Scraper Prezzi con n8n: Flusso End‑to‑End con Storico, Regole di Alert e Notifiche
Il modo più rapido per individuare sconti reali e opportunità di pricing? Automatizzare il monitoraggio con uno scraper prezzi n8n che raccoglie listini da più store, pulisce e normalizza i dati, li archivia in uno storico e invia notifiche quando il prezzo cambia davvero. In questa guida costruisci un flusso completo: scheduler (Cron), raccolta con richieste HTTP e gestione cookie, parsing HTML/JSON, salvataggio dello storico, confronto con l’ultimo valore, regole di alert con soglie e cooldown, deduplicazione del rumore e digest giornalieri su Slack. Il risultato è un sistema robusto per monitoraggio prezzi e‑commerce con automazione che supporta casi pratici come vigilanza competitor, dynamic pricing, affiliate e content commerce. Troverai esempi di nodi, configurazioni e snippet pronti da incollare, oltre a best practice su anti‑bot e riduzione del rumore.
📚 Nuovo a n8n? Parti dalla guida completa: cos’è n8n e come funziona.
Architettura e modello dati: dal target alla notifica
Prima di toccare i nodi, chiarisci il perimetro. Cosa vuoi monitorare? SKU strategici, top seller, competitor diretti? Con una base chiara, il tracciamento variazioni di prezzo con flussi n8n diventa prevedibile e misurabile.
- Pipeline logica: Scheduler → Raccolta → Parsing/Normalizzazione → Persistenza storico → Confronto ultimo prezzo → Regole/Severità → Notifica → Log.
- KPI minimi: delta assoluto/percentuale, frequenza update, coverage (quanti prodotti × quanti store), tasso di falsi positivi (rumore).
Modello dati essenziale (per tabella “prices_history”)
- product_id: ID interno o SKU.
- store: dominio o etichetta dello store.
- currency: ISO (es. EUR, USD).
- price: numero decimale (2‑4 decimali).
- timestamp: ISO o epoch.
- selector_hash: hash del selettore usato (CSS/XPath) per tracciabilità.
- url: URL della pagina prodotto.
Strategie di confronto
- Ultima osservazione: confronta il prezzo attuale con l’ultimo rilevato per lo stesso product_id+store.
- Rolling window: mediana/percentile delle ultime N osservazioni per attenuare outlier.
- Regole: soglie su ±X% o valore assoluto; escalazione se il calo supera limiti anomali (es. >25%).
Insight operativo: separa “prodotti critici” (più frequenti, soglie strette) da “long tail” (frequenza minore, soglie più ampie) per ridurre costi e rumore.
Scheduler e raccolta: Cron + HTTP Request con header e fallback
Usa un Cron per lanciare il flusso alla frequenza desiderata (es. ogni ora per i top seller, ogni 6‑12 ore per la long tail). Poi esegui richieste con HTTP Request. Preferisci API/endpoint JSON quando disponibili; in alternativa, esegui scraping HTML con parsing personalizzato.
Esempio HTTP Request (GET JSON)
{
"name": "Fetch Product JSON",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"parameters": {
"url": "https://api.example.com/products/{{$json.sku}}/price",
"method": "GET",
"responseFormat": "json",
"queryParametersUi": {
"parameter": [
{ "name": "currency", "value": "EUR" }
]
},
"continueOnFail": true
}
}
Consigli pratici
- Headers: imposta user‑agent, accept‑language e cache‑control per migliorare compatibilità. Se lo store blocca richieste senza header standard, usa HTTP Request con header personalizzati.
- Gestione cookie/sessione: salva cookie da una prima chiamata (login o consenso) e riutilizzali nelle successive (supporta parametri header/cookie). Per sessioni complesse valuta integrazione con attori esterni di scraping via API.
- Rate/Retry: con Split In Batches limita il batchSize per rispettare limiti. Imposta continueOnFail a true per non bloccare e instrada gli errori su rami di gestione.
Schedulazione
- Fraziona i lanci nel tempo (SKU ad alta priorità più frequenti). Evita che tutti i target girino allo stesso minuto per ridurre carico e anti‑bot.
Parsing e normalizzazione: da HTML/JSON al numero affidabile
Quando hai JSON, leggi direttamente il campo prezzo. Con HTML, usa un Code node per estrarre e pulire il valore. Mantieni selettori CSS/XPath stabili e versiona i cambi; in assenza di un estrattore dedicato, il parsing testuale controllato è spesso sufficiente.
Parsing prezzo da JSON (Code)
// Input: { json: { data: { price: "€1.299,00", currency: "EUR" }, url, store, product_id } }
function toNumber(str) {
if (!str) return null;
const cleaned = str.replace(/[^\d,.\-]/g, '')
.replace(/\.(?=\d{3}\b)/g, '')
.replace(',', '.');
const n = parseFloat(cleaned);
return Number.isFinite(n) ? n : null;
}
const price = toNumber($json.data.price);
return [{ json: { ...$json, price, currency: $json.data.currency || 'EUR' } }];
Parsing HTML (Code, regex mirato al selettore noto)
// Input: { json: { html, url, store, product_id } }
const html = $json.html || '';
// Esempio: cerca contenuto in <span id="price">€1.299,00</span>
const m = html.match(/<span[^>]*id=["']price["'][^>]*>([^<]+)<\/span>/i);
const raw = m ? m[1].trim() : null;
function toNumber(str) {
if (!str) return null;
const cleaned = str.replace(/[^\d,.\-]/g, '')
.replace(/\.(?=\d{3}\b)/g, '')
.replace(',', '.');
const n = parseFloat(cleaned);
return Number.isFinite(n) ? n : null;
}
const price = toNumber(raw);
return [{ json: { ...$json, price, currency: 'EUR', selector_hash: 'id:price' } }];
Normalizzazione e conversione valuta (facoltativa)
// Input: { json: { price, currency } } — esempio FX statico
const fx = { EUR: 1, USD: 0.93, GBP: 1.16 };
const target = 'EUR';
const rate = fx[$json.currency] || 1;
const price_eur = Math.round(($json.price * rate) * 100) / 100;
return [{ json: { ...$json, price_eur, currency: target } }];
Best practice
- Deduplicazione: se ricevi più letture ravvicinate, mantieni l’ultima valida per finestra (es. 10 minuti).
- Tracciabilità: salva selector_hash per capire quando cambiano i selettori.
Storico e confronto: salva, riprendi, calcola delta
Per confronto storico dei prezzi prodotti, scrivi l’osservazione odierna e carica l’ultima disponibile. Puoi usare un database relazionale. Con i nodi DB esegui SELECT/INSERT via query parameterizzate.
Esempio SELECT ultimo prezzo (query parametro da item)
{
"name": "Get Last Price",
"type": "n8n-nodes-base.mySql",
"typeVersion": 1,
"parameters": {
"operation": "executeQuery",
"query": "SELECT price, currency, timestamp FROM prices_history WHERE product_id = {{ $json.product_id }} AND store = {{ $json.store }} ORDER BY timestamp DESC LIMIT 1"
}
}
Esempio INSERT nuova osservazione
{
"name": "Insert Price",
"type": "n8n-nodes-base.mySql",
"typeVersion": 1,
"parameters": {
"operation": "executeQuery",
"query": "INSERT INTO prices_history (product_id, store, currency, price, url, selector_hash, timestamp) VALUES ({{ $json.product_id }}, {{ $json.store }}, {{ $json.currency }}, {{ $json.price }}, {{ $json.url }}, {{ $json.selector_hash }}, NOW())"
}
}
Merge per confronto (unisci “corrente” e “storico” per product_id)
{
"name": "Merge Current vs Last",
"type": "n8n-nodes-base.merge",
"typeVersion": 1,
"parameters": {
"mode": "mergeByKey",
"propertyName": "product_id",
"outputDataFrom": "both"
}
}
Calcolo delta in Code
// Input: item con current.price e last.price
const current = $json.current_price;
const last = $json.last_price;
const delta = current - last;
const deltaPct = last ? (delta / last) * 100 : null;
return [{ json: { ...$json, delta, deltaPct: deltaPct !== null ? Math.round(deltaPct * 100) / 100 : null } }];
Suggerimenti
- Se usi più store, includi store nella chiave di merge.
- Gestisci outlier: ignora variazioni impossibili (es. >70% senza input promozioni).
Regole di alert e riduzione del rumore: soglie, cooldown, digest
Definisci regole chiare per regole di alert su calo prezzo evitando notifiche eccessive.
If (soglia percentuale)
{
"name": "Is Price Drop > 10%",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"parameters": {
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.deltaPct }}",
"rightValue": "-10",
"operator": { "type": "number", "operation": "smaller" }
}
],
"combinator": "and"
}
}
}
Riduzione rumore
- Cooldown per prodotto/store (es. max 1 alert/24h): memorizza l’ultimo alert in DB e filtra.
- Raggruppamento/digest: aggrega tutte le variazioni significative e invia un unico messaggio a fine giornata.
- Escalation: se il delta supera soglia alta (es. >25%), invia immediatamente un alert “critico”.
Esempio digest in Code (compatta una lista di cambi in un Markdown)
const lines = items.map(i => `- ${i.json.product_id} @ ${i.json.store}: ${i.json.last_price} → ${i.json.current_price} (${i.json.deltaPct}%)`);
return [{ json: { text: `Price drop digest:\n` + lines.join('\n') } }];
Notifiche: Slack e messaggi strutturati
Invia notifiche su canali di team (pricing/merchandising). Usa un testo conciso, link alla pagina e delta percentuale. Con notifiche su Slack/Email ottieni visibilità immediata senza seppellire il team di alert.
Slack (Send Message)
{
"name": "Send Slack Message",
"type": "n8n-nodes-base.slack",
"typeVersion": 1,
"parameters": {
"resource": "message",
"operation": "send",
"channel": "C01234567",
"text": "Price drop: {{$json.product_id}} @ {{$json.store}} da {{$json.last_price}} a {{$json.current_price}} ({{$json.deltaPct}}%). Link: {{$json.url}}"
},
"credentials": {
"slackApi": { "name": "Slack OAuth2" }
}
}
Consigli
- Per digest: invia un solo messaggio con elenco puntato.
- Per casi critici: messaggio dedicato con emoji/menzioni del team.
Anti‑bot e resilienza: header, batching, retry
Molti e‑commerce limitano scraping aggressivo. Minimizza rischi di blocco e garantisci stabilità.
- Header realistici: imposta user‑agent e accept‑language; ruota user‑agent su elenchi noti.
- Intervalli casuali e batching: usa Split In Batches per processare piccoli lotti (batchSize 5‑10). Evita picchi.
{
"name": "Batch Loop",
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 1,
"parameters": { "batchSize": 10 }
}
- Retry mirati: su HTTP Request imposta continueOnFail: true e instrada gli errori su un ramo che riprova solo i prodotti falliti dopo un intervallo (via scheduling separato).
- Cookie/sessione: dove serve login, ottieni cookie/headers con una prima chiamata e riusali per le successive.
- Rispetto di robots.txt/ToS: valuta i limiti d’uso e considera soluzioni con attori esterni quando necessario.
Osservabilità
- Logga errori transitori e finali (dead‑letter list) per capire quali store/selettori sono problematici.
- Monitora error rate per store e regola batchSize/frequenza di conseguenza.
Qualità dati e controllo: deduplica, varianti, valute
Deduplicazione e controllo qualità sono essenziali per evitare falsi positivi.
- Deduplica: se più URL puntano allo stesso SKU/variante, scegli la fonte principale e marca le altre come di supporto.
- Varianti: per taglie/colore/bundle, assegna product_id varianti (es. SKU‑RED‑M) per differenziare prezzi.
- Valute: normalizzazione e conversione valuta coerente (EUR come base).
- Selettori: salva selector_hash; se il sito cambia markup, individui rapidamente cosa aggiornare.
Controlli automatici
- Validità prezzo: scarta valori nulli, 0 non attesi, o delta estremo (probabile parsing errato).
- Controllo formati: normalizza separatori migliaia/decimali (internazionale vs locale).
- Audit: salva timestamp, URL, store, selector_hash, user‑agent per ricostruire l’estrazione.
Esempio di flusso completo: dal CSV di target al digest Slack
Scenario: hai un CSV con product_id, store, url, currency. Vuoi un digest giornaliero con i cali >10%.
- Cron: ogni giorno alle 08:00.
- HTTP Request: scarica CSV target o leggi da DB.
- Split In Batches: batchSize 8.
- HTTP Request (per item): tenta JSON API, altrimenti HTML page.
- Code: parsing prezzo, normalizzazione valuta.
- DB SELECT: ultimo prezzo per product_id+store.
- Merge: unisci “corrente” e “ultimo”.
- Code: delta/deltaPct e filtri qualità.
- If: deltaPct < -10.
- Aggrega “true” in lista; genera testo digest (Code).
- Slack: invia digest al canale.
Vantaggi
- Riduzione rumore grazie a soglia e digest.
- Tracciabilità completa (storico + selector_hash).
- Scalabilità via batching controllato.
Quick Takeaways
- Progetta il modello dati (productid, store, currency, price, timestamp, selectorhash) prima del primo run.
- Usa HTTP Request con header realistici e Split In Batches per ridurre blocchi anti‑bot.
- Normalizza prezzi e valute con Code; salva storico e confronta con l’ultima osservazione.
- Applica If con soglie percentuali e digest giornalieri per ridurre il rumore.
- Invia notifiche strutturate su Slack, con link e delta; escalazione per cali anomali.
- Monitora errori e selettori: aggiorna rapidamente quando gli store cambiano markup.
Conclusione
Uno scraper prezzi n8n ben progettato trasforma dati pubblici in insight azionabili per pricing, merchandising e content commerce. Con una pipeline che parte da Cron, raccoglie via HTTP, pulisce con Code, archivia lo storico e confronta l’ultimo prezzo, puoi impostare regole chiare e notifiche efficaci senza sommergere i team di alert inutili. La chiave è l’equilibrio: limiti al traffico (batching e frequenze), parsing affidabile e tracciabile (selector_hash, audit), regole con soglie sensate e digest per concentrare l’attenzione su eventi che contano. Inizia piccolo (pochi SKU strategici), misura il rumore, calibra soglie e frequenza, poi scala coverage e integrazioni. Così ottieni un sistema di monitoraggio prezzi e‑commerce con automazione che supporta decisioni quotidiane, anticipa il mercato e libera tempo ai marketer per le attività ad alto impatto.
FAQ
- Come scelgo la frequenza di raccolta?
Dipende da volumi e priorità. Per i top seller usa schedulazione cron per raccolta dati ogni 1‑3 ore; per la long tail ogni 6‑24 ore. Aumenta la frequenza in periodi promozionali.
- Come gestisco pagine con markup che cambia spesso?
Salva selector_hash e monitora aumenti di errori di parsing. Se un dominio cambia spesso, passa a selettori più robusti, aggiungi fallback e un test automatico che valida il selettore prima del run.
- Come evitare notifiche eccessive?
Applica soglie (±X% o valore), cooldown per prodotto/store (un alert ogni 24h) e digest giornalieri. Raggruppa più variazioni in un solo messaggio su Slack.
- Come tratto le valute?
Normalizza tutto verso una base (es. EUR). Applica conversione con tassi aggiornati e arrotondamento coerente. Conserva anche la valuta originale per audit.
- Posso integrare servizi esterni di scraping?
Sì, tramite integrazione con attori di scraping esterni via API (chiamati con HTTP Request). Valuta costi, compatibilità anti‑bot e affidabilità; usa questi attori per store più complessi.
Ci dai una mano?
Qual è il primo prodotto o categoria che vuoi monitorare con lo scraper prezzi n8n? Condividi la tua idea e gira l’articolo al team: vediamo insieme come tarare soglie e digest per segnalazioni davvero utili!
Articoli correlati
- Newsletter Automatica con n8n + Mailchimp/ConvertKit: Guida Pratica End‑to‑End
- Monitorare l’Uptime di un Sito Web e Inviare Alert
- Automatizzare la Fatturazione con Stripe e n8n
- Creare un Flusso di Approvazione Contenuti con n8n e Airtable
Vuoi automazioni AI su misura per la tua azienda?
Scopri la consulenza →