Guide
Web Scraping Avanzato: Gestire Paginazione e Contenuti Dinamici
Vuoi trasformare la raccolta di dati dal web in un processo stabile, scalabile e “ban‑proof”? Con scraping web n8n paginazione puoi costruire workflow resilienti che navigano tra pagine, gestiscono contenuti caricati via JavaScript e riducono i rischi di blocco. In questa guida pratica impari a scegliere quando basta l’HTTP Request e quando serve il rendering lato client per scraping, come implementare la paginazione in n8n con loop su page/offset/cursor, come mantenere uno stato persistente, deduplicare i record estratti e ridurre ban grazie a rate limiting, caching (ETag/Last‑Modified) e rotazione IP. Vedrai snippet pronti all’uso, configurazioni chiave e un framework per qualità dati (selettori, normalizzazione, tracciabilità), oltre alle considerazioni legali/etiche che spesso vengono ignorate. Obiettivo: passare da script fragili a pipeline solide, schedulate con Cron in n8n e monitorate con alert mirati.
📚 Nuovo a n8n? Parti dalla guida completa: cos’è n8n e come funziona.
[IMG: Canvas n8n con Cron → HTTP Request → Code (extract + nextPage) → IF (hasNext) → HTTP Request (next) → … → DB + Slack alert]
Scegliere lo strumento giusto: HTTP Request, servizi headless o API di terze parti
Non tutti i siti sono uguali e non tutte le strategie di scraping lo sono. La prima decisione è tecnica e strategica.
- Quando basta HTTP Request
- La pagina restituisce HTML “statico” o espone un endpoint JSON (spesso usato dal frontend).
- Paginazione prevedibile tramite query param (page, offset, cursor).
- Nessuna protezione anti‑bot aggressiva.
- Quando serve rendering lato client per scraping
- Contenuti caricati via JavaScript (lazy loading, infinite scroll) senza API pubbliche facili da replicare.
- Elementi critici generati dopo esecuzione JS (prezzi, disponibilità).
- In questi casi valuta un servizio headless (browser automatizzato) o un’API di scraping specializzata. Integra in n8n tramite HTTP Request verso il servizio, mantenendo in n8n la logica di orchestrazione, paginazione e salvataggio.
- Criteri di scelta tra approcci
- Manutenzione: meno dipendenze esterne = meno costi, ma più fragilità su siti dinamici.
- Volume e robustezza: siti con protezioni anti‑bot (Cloudflare, fingerprint TLS) richiedono rotazione proxy e IP residenziali, o soluzioni “browser‑like”.
- Compliance: controlla sempre i termini del sito e le policy robot.txt.
Consiglio operativo: parti con HTTP Request e prova a individuare gli endpoint JSON interni. Se non basta, passa a un servizio di rendering; tieni separata l’estrazione (servizio) dall’orchestrazione (n8n), così il passaggio scala meglio.
Paginazione in n8n: loop su page/offset/cursor con scheduling e rate limiting
La paginazione è il cuore di ogni pipeline di scraping affidabile.
- Modello con page/offset
- Costruisci l’URL con query dinamiche (page=1, 2, 3…) o offset (0, 50, 100…).
- Esegui la richiesta, estrai i risultati, verifica se ci sono più pagine.
- Modello con cursor/nextPage
- Alcune API restituiscono un cursore o un link next. Gestiscilo in un nodo Code e decidi se proseguire.
- Scheduling con Cron in n8n
- Usa un trigger temporizzato (esecuzione ogni 15 minuti/ogni notte) per avviare il job.
- Esegui solo delta (ultime novità) se l’origine lo consente.
- Rate limiting per richieste HTTP
- Inserisci attese brevi tra batch (1–3 s).
- Usa “Split In Batches” quando processi molte URL per stabilizzare il throughput.
Esempio (estrazione JSON e controllo nextPage, Code node — Run Once For All Items):
// Input atteso dal nodo precedente: response JSON dell'HTTP Request
const res = $input.first().json;
const items = (res.items || []).map((it) => ({
json: {
id: it.id,
title: it.title?.trim() || '',
url: it.url || '',
price: Number(it.price ?? 0),
source: res.source || 'unknown',
fetchedAt: new Date().toISOString(),
}
}));
const hasNext = Boolean(res.nextPage || res.nextCursor);
return [
{ json: { hasNext, next: res.nextPage || res.nextCursor || null } },
...items
];
[IMG: HTTP Request configurato con query page={{$json.page}} e nodo Code che calcola hasNext/next]
Stato persistente, cursori e deduplica: evitare doppioni e “ricominciare da dove hai lasciato”
Quando la raccolta è ricorrente, la gestione dello stato è cruciale.
- Gestione dello stato nello scraping
- Conserva l’ultimo cursore o la pagina elaborata in uno storage persistente (DB) o nello stato del workflow.
- Mantieni l’ultima “data di aggiornamento” per estrarre solo le novità.
- Stato persistente con getWorkflowStaticData(‘global’)
- Usa uno storage globale del workflow per salvare cursori/ultima pagina. Esempio (Code node — Run Once For All Items):
// Salvataggio/lettura cursore globale
const state = getWorkflowStaticData('global');
const lastCursor = state.lastCursor || null;
const input = $input.first().json;
if (input.newCursor) {
state.lastCursor = input.newCursor;
}
return [{ json: { lastCursor: state.lastCursor || null } }];
- Deduplica dei record estratti
- Definisci una chiave unica (id, slug, url canonical). Prima di salvare, scarta duplicati visti nell’esecuzione corrente e in DB.
// All-items: dedup in memoria per url
const rows = $input.all().map(i => i.json);
const seen = new Set();
const out = [];
for (const r of rows) {
const key = (r.url || '').trim().toLowerCase();
if (!key || seen.has(key)) continue;
seen.add(key);
out.push(r);
}
return out.map(j => ({ json: j }));
- Tracciabilità
- Aggiungi “source”, “fetchedAt” e, se utile, un “hashContent” per rilevare cambiamenti nel tempo.
Contenuti caricati via JavaScript: strategie operative e infinite scroll
Molti siti popolari caricano i dati lato client: servono tattiche diverse.
- Individua l’endpoint JSON
- Apri la rete (DevTools) e cerca richieste XHR/fetch che restituiscono i dati. Spesso basta replicarle in HTTP Request in n8n con gli header corretti (cookie/sessione, user‑agent).
- Infinite scroll
- La pagina richiama un endpoint con “cursor/after/offset”. Riproduci lo schema: HTTP Request → Code (next) → IF (hasNext) → loop.
- Rendering lato client per scraping
- Se i dati non sono esposti, usa un servizio headless con rotazione proxy e fingerprinting del browser. Integra via HTTP Request e mantieni in n8n paginazione, dedup e salvataggio.
- Lazy loading di immagini/dettagli
- Spesso ci sono endpoint di dettaglio per ogni item. Accodali a un “Split In Batches” → HTTP Request (dettaglio) → arricchisci i record con i campi mancanti.
[IMG: Diagramma a due fasi: Catalogo (JSON/HTML) → Lista URL → Dettaglio (JSON/HTML) → Merge + Salva]
Antibot e resilienza: Cloudflare, rotazione IP, fingerprint e limiti
- Protezioni anti‑bot come Cloudflare
- Evita burst: imposta rate limiting per richieste HTTP con attese tra batch.
- Usa proxy pool e IP residenziali; alterna user‑agent plausibili e mantieni header coerenti (Accept‑Language, Accept, sec‑ch‑ua).
- Riduci parallelismo: serializza le chiamate più sensibili.
- Fingerprinting del browser
- Alcune difese controllano TLS fingerprint e comportamenti JS. Se fallisci, passa a servizi “browser‑like”.
- Retry con backoff esponenziale
- Sui 429/5xx, attiva retry progressivo (2s → 5s → 10s). Interrompi dopo N tentativi e invia alert.
- Osservabilità
- Logga gli status code, la latenza media e il tasso di errore per dominio. Monitora i ban nel tempo per calibrare batch e attese.
Parsing sicuro e robusto: selettori, normalizzazione e validazione
- Selettori CSS/XPath con estrattori
- Per HTML semplice, identifica pattern stabili (class, id); evita selettori fragili.
- Se ottieni JSON, preferiscilo: parsing più stabile e veloce.
- Normalizzazione schema
- Definisci uno schema di output con tipi coerenti (string/number/date) e campi opzionali.
- Valida i campi chiave (url, price, title) e imposta default sicuri.
- Qualità dati e tracciabilità
- Aggiungi sourceUrl, timestamp, e un checksum del record. Questo aiuta ad auditare e a identificare update reali vs rumore.
Esempio (Code — per‑item: normalizza e mappa)
const j = $json;
return {
json: {
id: j.id || j.slug || null,
title: String(j.title || '').trim(),
url: String(j.url || '').trim(),
price: Number(j.price ?? 0),
currency: j.currency || 'USD',
fetchedAt: new Date().toISOString(),
source: j.source || 'unknown'
}
};
Cache e conditional requests: ETag, Last‑Modified e riduzione dei costi/ban
Riduci richieste inutili e rispetta i limiti.
- ETag e Last‑Modified
- Salva ETag/Last‑Modified dal response precedente.
- Nelle richieste successive, invia If‑None‑Match / If‑Modified‑Since. Se ricevi 304 Not Modified, salta parsing e passa oltre.
- Come farlo in n8n
- HTTP Request: aggiungi header dinamici con espressioni (If‑None‑Match: ={{$json.etag}}).
- Gestisci la logica in un nodo IF: se statusCode==304, non aggiornare; altrimenti prosegui e aggiorna ETag/Last‑Modified persistenze.
- Benefici
- Meno banda, meno load sul sito target, minor probabilità di ban.
[IMG: HTTP Request con Headers If‑None‑Match/If‑Modified‑Since e IF che intercetta 304]
Salvataggio e indicizzazione: database, dedup e scheduling/alerting
- Database di destinazione
- MongoDB/Postgres: scegli in base a volumi e query. Mongo è flessibile per documenti JSON; Postgres+JSONB per query strutturate e join.
- Imposta un indice univoco sulla chiave (id/url) per prevenire duplicati lato DB.
- Deduplica dei record estratti
- Dedup in memoria (per esecuzione) + indice univoco (persistenza). Logga conflitti e scarti per audit.
- Scheduling con Cron in n8n
- Pianifica finestre orarie “soft” (notte/weekend) per scraping massivo.
- Aggiungi alert: invia un riepilogo Slack con conteggio record nuovi/aggiornati, errori e durata.
- Pipeline a due fasi
- Catalogo (lista) → Dettaglio (arricchimento) → Merge → Salva. Questa separazione migliora debug e controlli qualità.
Resilienza end‑to‑end: retry, limiti di concorrenza e aspetti legali/etici
- Retry con backoff esponenziale
- Implementa retry solo su errori temporanei. Limita i tentativi e aumenta l’attesa per ogni retry.
- Limiti di concorrenza
- Evita chiamate parallele elevate su domini sensibili. Meglio batch piccoli e costanti.
- Osservabilità
- Attiva un workflow con Error Trigger per log centralizzato. Traccia tassi di errore per dominio/source.
- Aspetti legali/etici
- Rispetta robots.txt, ToS e privacy. Non raccogliere dati personali senza base legale. Fornisci un meccanismo per eliminare dati se richiesto.
Esempio operativo: paginazione con page e arricchimento dettaglio
Scenario: elenco prodotti con endpoint JSON paginato (page=1..N) e endpoint dettaglio per ogni item.
-
Cron (ogni notte)
-
Code (imposta page iniziale, o leggi cursore persistente)
-
HTTP Request (GET lista?page={{$json.page}})
-
Code (estrai items, nextPage)
-
IF (hasNext) → incrementa page → loop al punto 3; altrimenti prosegui
-
Split In Batches (20)
-
HTTP Request (GET dettaglio per item.url)
-
Code (merge campi, normalizza schema)
-
DB (insert/upsert) con indice unico
-
Slack (report)
Snippet per incrementare page (Code — per‑item):
const j = $json;
const nextPage = Number(j.page || 1) + 1;
return { json: { page: nextPage } };
[IMG: Canvas con ramo Lista (loop page) e ramo Dettaglio (Split In Batches) fino al DB]
Quick Takeaways
- Inizia con HTTP Request e punta agli endpoint JSON; passa al rendering lato client solo quando necessario.
- Implementa la paginazione in n8n con loop su page/offset/cursor, controlli IF e attese tra batch.
- Mantieni stato e cursori (getWorkflowStaticData(‘global’) o DB) e applica dedup su chiave unica.
- Riduci ban con rate limiting, caching via ETag/Last‑Modified e rotazione IP su domini “sensibili”.
- Normalizza e valida i dati prima del salvataggio; traccia source e fetchedAt per audit.
- Schedula con Cron e invia alert/summary: osservabilità prima di tutto.
Conclusione
Portare scraping web n8n paginazione a livello “produzione” richiede una combinazione di scelte strategiche e tattiche: puntare prima agli endpoint JSON, orchestrare la paginazione con loop chiari e stato persistente, assicurare qualità e dedup, e proteggere il ciclo con rate limiting, caching e retry intelligenti. Con un disegno a due fasi (lista → dettaglio), salvataggio su DB con indice unico e un layer di observability (Slack report, Error Trigger), i tuoi workflow diventano affidabili e prevedibili. Per i marketer, significa dati freschi e puliti per campagne, pricing intelligence e analisi competitive, senza il peso di manutenzioni continue. Parti da un MVP con pochi endpoint, misura tempi/ban/errori, poi scala con batching e caching: il salto di qualità è nel processo, non solo nel parser.
FAQ
- Come gestisco la paginazione in n8n senza rischiare loop infiniti?
Controlla sempre un segnale di uscita (no results/hasNext=false). Incrementa page/offset in un Code node, valida i limiti e usa IF per interrompere quando non ci sono più dati.
- Come tratto contenuti caricati via JavaScript?
Cerca gli endpoint JSON usati dal frontend. Se non esistono o sono offuscati, integra un servizio di rendering lato client e usa n8n per orchestrazione, paginazione e salvataggio.
- Come riduco i ban su siti protetti (Cloudflare)?
Diminuisci parallelismo, aggiungi attese tra batch, usa proxy/rotazione IP residenziali e header plausibili. Implementa retry con backoff sui 429/5xx e monitora i tassi di errore per dominio.
- Posso usare caching con ETag/Last‑Modified in n8n?
Sì. Salva ETag/Last‑Modified e inviali come If‑None‑Match/If‑Modified‑Since negli header dell’HTTP Request. Gestisci i 304 per saltare parsing e ridurre richieste.
- Qual è il modo migliore per evitare duplicati nel database?
Definisci una chiave unica (id/url canonical) e crea un indice unico nel DB. In n8n, aggiungi anche una dedup in memoria per esecuzione, loggando i record scartati.
Ci dai una mano?
Qual è il tuo prossimo target: stabilizzare la paginazione, ridurre i ban con caching/limiti o arricchire i dati con un passo “dettaglio”? Condividi la tua scelta e questo articolo con il team: confrontiamo pattern e trasformiamo gli scraper in pipeline affidabili!
Articoli correlati
- Automate RPA: Guida Completa a Power Automate e all’Iperautomazione per le Aziende
- RPA Process: Guida Completa e Operativa all’Automazione Robotica
- RPA Robotica: guida completa a benefici, costi e roadmap
- Automation RPA: Guida Completa all’Automazione Robotica dei Processi
Vuoi automazioni AI su misura per la tua azienda?
Scopri la consulenza →