trafilatura è un estrattore di contenuti Python che non richiede un browser. Nei fixture etichettati di questo articolo, l’unico rivale sulla stessa pagina HTML per la qualità dell’estrazione è Mozilla Readability: trafilatura ha “perso” solo un blocco di boilerplate annotato su 17, mentre Readability ne ha lasciati passare cinque. Gli strumenti basati su browser compaiono solo nel contesto dell’impronta di deploy e non sono stati valutati qui per la qualità dell’estrazione.

La sua funzione principale è estrarre il contenuto centrale: input HTML, output di testo e metadati orientati all’articolo, con i componenti di contorno della pagina filtrati tramite euristiche. Può serializzare l’output in JSON e in altri formati, ma non produce uno schema di righe definito dall’utente né record catalogati ripetuti e tipizzati. È stata testata la versione 2.1.0. Non esegue JavaScript e il confronto con Readability mostra un compromesso tra precisione e conservazione del contenuto, non una vittoria assoluta su tutta la linea.
Dove si colloca trafilatura, e cosa non fa per scelta
trafilatura si presenta come uno strumento Python e da riga di comando per raccogliere testo e metadati sul web — crawling, scraping, extraction — con output in CSV, JSON, HTML, Markdown, TXT o XML. È una promessa ampia. In pratica, però, la parte davvero forte dello strumento è molto più mirata: prende un documento HTML e restituisce il contenuto principale, ripulito da tutto il resto della pagina.

Ecco il modello mentale, perché spiega sia il punto di forza sia il limite. La maggior parte degli scraper puntati su una pagina è guidata da selettori: dici allo strumento “prendi l’elemento con classe product-price” e lui ti restituisce ciò che trova lì. trafilatura funziona al contrario. Legge l’intero documento e decide quali blocchi sono davvero l’articolo e quali sono boilerplate, usando euristiche sul contenuto invece di un selettore scritto da te. Per questo non ha bisogno di regole specifiche per ogni sito per ripulire una pagina. Ed è proprio per questo che non può consegnarti un catalogo strutturato: non c’è uno schema, non ci sono righe tipizzate, solo “ecco il testo significativo”. È un estrattore, non un parser da indirizzare.
Non richiede nemmeno un runtime browser da scaricare separatamente. La catena di dipendenze include wheel di piattaforma come lxml, quindi “nessun download del browser” non va confuso con un’installazione composta solo da codice sorgente o priva di codice nativo.
Installazione: poche dipendenze, nessun browser da installare
pip install trafilatura in un virtualenv pulito su Python 3.14 ha installato 17 pacchetti; la wheel più grande registrata era lxml, da 8,6 MB, secondo pip-install-trafilatura.log. Non è stata necessaria alcuna installazione separata del browser né un comando post-install per il browser.
Per fare un confronto sulla scala, il pacchetto Scrapling nello stesso corpus di ricerca ha richiesto quattro invocazioni pip separate per far funzionare i suoi fetcher ed è arrivato a 26 pacchetti, due dei quali sono wheel driver Playwright da 42,2 MB (tools/scrapling/artifacts/logs/pip-install-scrapling.log) — e questo prima ancora di scaricare il binario del browser. Il pacchetto Crawlee ha misurato quel download separato di Chromium in circa 81,7 MiB (tools/crawlee/research-materials.md). Quegli strumenti fanno un lavoro più ampio, quindi non è un confronto equo sulle capacità; mostra solo ciò che vede il tuo disco e la cache della tua CI. E la versione che pip mi ha fornito (2.1.0) coincide con la release corrente, quindi non c’è l’asterisco del tipo “hai testato qualcosa di vecchio” su nessun dato riportato sotto.
Prova pratica: cosa ha restituito davvero l’estrattore

L’ho testato su fixture pensati sia per il suo punto forte sia per il suo limite, con gli output grezzi salvati nel repository del benchmark. Il test sull’articolo è quello che mi ha convinto.
Ho preso una fixture di articolo locale e ho avvolto il contenuto reale nel rumore: prompt di login, invito a “Subscribe”, link di navigazione, footer con copyright — il boilerplate standard che uno scraper ingenuo si porta dietro insieme al corpo della pagina. trafilatura ha restituito il titolo più tutti e 3 i paragrafi su 3 e tutti quei marcatori di boilerplate — Login, Subscribe, Copyright — sono spariti dall’output. Oltre al testo, ha estratto correttamente autore e data dai metadati della pagina. Il risultato completo, in .txt, .md e .json, si trova in results/local_article.json.
Lo stesso HTML salvato è stato esportato come testo semplice, Markdown e JSON. L’articolo non dimostra che tutti e tre i formati provengano da una singola chiamata simultanea; sono serializzazioni alternative dello stesso percorso di estrazione. Qui il JSON impacchetta testo estratto e metadati, non record ripetuti definiti dall’utente.
Ecco il primo passaggio completo in un unico punto, così puoi verificare le affermazioni sopra invece di prenderle per buone:
| Fixture | Cosa è tornato | Tempo di esecuzione | Evidenza |
|---|---|---|---|
| Articolo locale, avvolto in nav / login / subscribe / copyright | titolo + 3/3 paragrafi, nessun boilerplate filtrato in output, autore Thunderbit Research Lab, data 2026-07-09 | 0.007 s | local_article.json |
| Catalogo prodotti locale | 12 nomi prodotto e i relativi 12 prezzi come testo piatto, 0 righe strutturate, 478 caratteri | 0.064 s | local_catalog_extraction.txt |
| Pagina che restituisce HTTP 500 | fetch_url ha restituito None, nessuna eccezione sollevata | 30.012 s | local_failure_500.json |
| Pagina prodotto Books to Scrape (pubblica) | 1.324 caratteri di testo pulito, più il gemello Markdown | 0.753 s | public_books_product.txt / .md |
Ogni riga proviene da artifacts/raw/trafilatura-test-summary.json nel pacchetto trafilatura — trafilatura 2.1.0, Python 3.14, macOS arm64, un run su una macchina. Considera questi tempi come osservazioni, non come benchmark.
Nel fixture 500, fetch_url ha restituito None dopo circa 30 secondi, mentre gli endpoint locali vicini erano veloci. Il run dimostra il ritardo, non se la causa sia retry/backoff, un timeout fisso o un altro percorso interno. Questo articolo non ha verificato un parametro di timeout per chiamata supportato da fetch_url; il controllo dimostrato è usare un client gestito dal chiamante e passare poi l’HTML risultante a trafilatura.

Gli stessi test mettono anche in evidenza tre limiti.
Primo e più importante: trafilatura è un estrattore di contenuti, non uno scraper strutturato. L’ho eseguito su una fixture di catalogo prodotti. Ha restituito tutti i 12 nomi prodotto — come testo — e esattamente 0 righe strutturate (478 caratteri di testo piatto, secondo results/local_catalog_extraction.txt). Anche i prezzi sono arrivati, da $18.00 fino a $51.00, ciascuno su una riga separata sotto il nome corrispondente. Tutto ciò che ti serve è nell’output; nulla però è un campo. Se ti servono [{name, price, rating}, …], questo è lo strumento sbagliato e nessuna configurazione lo trasforma in altro — è una scelta di progetto, non un bug.

Secondo: non esegue JavaScript. Consuma HTML statico. Se lo punti a una pagina renderizzata lato client, otterrai ciò che il server ha inviato prima dell’esecuzione dello script, che spesso non è nulla di utile. Affiancalo a un renderer se i tuoi target dipendono molto da JS; trafilatura non copre quella parte.
Terzo, una precisazione sulle mie stesse prove: il primo test pubblico sull’estrazione ha usato un blocco di descrizione prodotto, non un vero articolo di news, perché il sandbox pubblico non contiene pagine di notizie. Il risultato di pulizia dell’articolo sopra proviene da una fixture locale controllata. Mi fido del risultato — la rimozione del boilerplate è inequivocabile — ma non volevo spacciare una pagina prodotto per prova di estrazione da redazione, quindi nel pacchetto è rimasto come lacuna aperta. Un run successivo il 2026-07-14 l’ha chiusa, e i risultati sono nella sezione successiva.
Verifica di sanità del boilerplate su pagine reali

Due pagine reali sono state scaricate una volta, salvate come fixture offline con hash SHA-256 e rieseguite senza accesso alla rete. Non sono stati registrati tempi né ground truth etichettati. Questa è una verifica di sanità del boilerplate su pagine reali, non un punteggio di accuratezza.
| Fixture di articolo reale | HTML grezzo | Corpo estratto | Corpo/grezzo | Marcatori di pagina rimossi | title | date | hostname | author | sitename |
|---|---|---|---|---|---|---|---|---|---|
| Wikipedia, "Web scraping" | 230,049 bytes | 26,673 bytes | 0.116 | 4 su 4 | sì | 2005-09-17 | wikipedia.org | null | null |
| Wikinews, "7th Heaven" (archiviato) | 79,716 bytes | 2,200 bytes | 0.028 | 5 su 5 | sì | 2005-11-29 | wikinews.org | null | null |
Entrambe le righe provengono da artifacts/results/trafilatura-fidelity-summary.json. I marcatori controllati erano “Jump to content”, “Privacy policy”, “Powered by MediaWiki”, “This page was last edited” e, sulla pagina Wikinews, anche “free news source” — tutti rimossi, nessuno trapelato, su entrambe le pagine.
Il rapporto corpo/grezzo misura la riduzione, non l’accuratezza; il contenuto dell’articolo eventualmente omesso non è stato valutato. author e sitename erano null in questi due template MediaWiki, mentre la fixture locale controllata forniva un autore. Si tratta di una mancanza osservata nel test e specifica di MediaWiki, non della prova di una affidabilità generale del byline. Le date estratte sono riportate così come restituite e non sono state verificate contro un ground truth.
Due estrattori, gli stessi byte HTML, uno script di scoring

In questo corpus di ricerca esiste esattamente un confronto sulla stessa base di test per trafilatura, e il pacchetto di trafilatura non l’ha costruito. L’ha costruito il pacchetto mozilla-readability, come braccio di controllo: 22 fixture etichettate a mano in cui ogni blocco di testo è marcato come ARTICLE o BOILERPLATE e ogni parola porta un token sentinella univoco, così ogni parola estratta può essere ricondotta a un solo blocco etichettato. Entrambi gli strumenti hanno ricevuto byte HTML identici. Readability ha girato su jsdom 29.1.1 con Node v22.22.3; trafilatura ha usato il proprio parser.
| Metrica (media micro, set di fedeltà del contenuto) | trafilatura 2.1.0 | @mozilla/readability 0.6.0 | Evidenza |
|---|---|---|---|
| Unità di articolo recuperate | 40 su 40 | 40 su 40 | comparison.json |
| Unità di boilerplate trapelate | 1 su 17 | 5 su 17 | comparison.json |
| Token di boilerplate che contaminano l’output | 3 | 41 | comparison.json |
| Precisione token | 0.939 | 0.902 | comparison.json |
| F1 token | 0.969 | 0.948 | comparison.json |
Recall non-prose, fixture f6_nonprose | 7 su 8 | 8 su 8 | comparison.json |
Articolo molto breve, F1 f3_short_120 | 0.571 | 0.800 | comparison.json |
Fonte: tools/mozilla-readability/artifacts/raw/comparison.json in questo corpus di ricerca — 11 fixture nel set content-fidelity, 40 unità articolo e 17 unità boilerplate. Sono fixture sintetiche volutamente sbilanciate verso i casi avversi, quindi vanno lette come meccanismo, non come classifica su un corpus reale.
Nessuno dei due “spazza via tutto”, e la differenza è proprio la parte interessante. trafilatura tiene fuori il chrome della pagina — un solo blocco trapelato contro cinque di Readability, tre token contaminanti contro 41. Questa è la metà “precisione” del concetto di “testo pulito da articolo”, ed è quella che determina se la finestra di contesto del tuo LLM si riempie di link laterali. Ma Readability recupera contenuti che trafilatura scarta: nella fixture non-prose, trafilatura ha eliminato un <figcaption> che Readability ha conservato, e su un articolo molto breve ha ottenuto 0.571 contro lo 0.800 di Readability. Una pulizia aggressiva è un compromesso, non una vittoria gratuita. Se il tuo corpus è pieno di stub, didascalie e pagine ricche di tabelle, quel compromesso gioca contro di te.
Come trasformare il confronto in un test di scelta
Parti stabilendo quale errore costa di più alla tua pipeline. Se il boilerplate consuma token downstream o sporca i risultati di ricerca, i valori di leakage dei blocchi boilerplate e dei token contaminanti meritano più peso. Se invece perdere una didascalia, un post molto corto o un blocco non narrativo è inaccettabile, allora va pesata di più la capacità di recuperare contenuto in base alla forma della pagina. Il set di fixture condiviso rende visibile quel compromesso, ma non assegna i pesi per un archivio giornalistico, un corpus di documentazione o una pipeline di retrieval.
Il contesto più ampio del test di stress è nel confronto tra dieci librerie su memoria e HTML malformato.
Costruisci il bake-off a partire da HTML salvato, non da URL live, così entrambi gli estrattori ricevono byte identici. Includi articoli lunghi normali, annunci brevi, pezzi ricchi di didascalie, documenti pieni di tabelle o codice e template di ciascun publisher che integri davvero. Etichetta un piccolo numero di unità di contenuto richieste e di blocchi boilerplate noti prima di far partire uno dei due strumenti. Poi valuta separatamente output vuoto, recupero delle unità richieste, leakage di unità indesiderate e campi dei metadati. Un singolo punteggio aggregato di “qualità” può nascondere il modo preciso in cui il sistema fallisce, ed è proprio quel modo a contare operativamente.
Valida anche il contratto dell’output a valle. Il JSON di trafilatura può contenere contenuto estratto e metadati, ma una serializzazione JSON non è la stessa cosa di uno schema di righe tipizzate. Per il testo degli articoli, controlla lunghezza minima del corpo e marker richiesti invece di accettare qualsiasi output non vuoto. Per i metadati, distingui tra assenza e valore errato e conserva l’URL sorgente insieme alla versione di estrazione, così i mancati recuperi possono essere riprodotti.
Anche il fetching va testato come livello a sé. L’osservazione del fallimento locale dopo 30 secondi riguarda fetch_url, non l’estrazione da HTML già in memoria, e il suo meccanismo interno non è stato determinato. Se contano deadline, retry, autenticazione o policy proxy, usa un client di cui controlli il comportamento, registra i byte della risposta finale e passa quei byte all’estrattore. In questo modo separi i problemi di acquisizione da quelli di selezione del contenuto e rendi i confronti ripetibili.
Infine, misura le proprietà di deployment sulla piattaforma effettiva. L’installazione Python 3.14 da 17 pacchetti non ha richiesto un browser separato, ma questo non dice nulla su throughput, crescita della memoria, disponibilità delle wheel su ogni architettura o comportamento con worker concorrenti. L’articolo dimostra un meccanismo utile di precisione/retention rispetto a Readability; l’idoneità alla produzione dipende comunque dal corpus e dai test runtime.
Per un riscontro esterno che non sia un lavoro di questo stesso corpus, la pagina di valutazione di trafilatura e il pubblico ScrapingHub article-extraction-benchmark lo collocano entrambi sopra readability-lxml nel word-F1 su circa 181 pagine reali — nella stessa direzione della tabella sopra. Una precisazione che molte sintesi che citano quel benchmark saltano: il celebre F1 di trafilatura (~0.945) è associato a una vecchia linea 0.5.1, non alla 2.1.0 testata qui.
Pro e contro
Pro:
- Meno leakage di boilerplate etichettato rispetto a Readability sul set di fixture condiviso: 1 blocco su 17 contro 5.
- Ha estratto correttamente autore e data nella fixture locale, e title/date/hostname in entrambe le pagine reali dell’articolo.
- Lo stesso HTML può essere serializzato come testo, Markdown o JSON.
- Installazione da 17 pacchetti senza runtime browser separato.
- Il fallimento è silenzioso:
fetch_urlrestituisceNonesu HTTP 500 invece di sollevare un’eccezione. - La versione testata coincide con la più recente (2.1.0) — nessun drift di versione.
- Licenza Apache-2.0 — permissiva e adatta all’uso commerciale.
Contro:
- Non è uno scraper strutturato: il test sul catalogo ha restituito 12 nomi e 12 prezzi come testo e 0 righe tipizzate. Nessuno schema, nessun campo.
- Nessun rendering JavaScript — solo HTML statico; per pagine client-side serve un renderer separato.
authoresitenamesono tornati null su entrambe le pagine MediaWiki reali, quindi l’estrazione del byline non è garantita.- La pulizia aggressiva ha un costo: ha rimosso un
<figcaption>che Readability ha conservato e ha totalizzato 0.571 contro lo 0.800 di Readability su un articolo molto breve. - Quel 500 silenzioso ha impiegato 30.012 secondi per restituire
None; usa un fetcher controllato dal chiamante quando la gestione delle scadenze è importante. - Lo spider integrato per crawling/sitemap e i formati di output CSV/XML non sono stati esercitati in questo passaggio, quindi non faccio affermazioni su di essi.
Per chi è adatto — e chi dovrebbe evitarlo
trafilatura è pensato per l’estrazione del contenuto principale orientato agli articoli. È una buona scelta per costruire corpora testuali, archivi leggibili o input NLP da HTML statico quando una pulizia euristica è accettabile. Il confronto sulle fixture condivise indica un leakage di boilerplate inferiore a Readability, mentre Readability ha trattenuto di più nei casi brevi e non narrativi.
Evitalo se ti serve davvero un’estrazione strutturata — righe di prodotti con prezzi, record tipizzati, campi chiave: valore — perché restituisce testo, non tabelle (il test sul catalogo ha recuperato tutti i 12 nomi e tutti i 12 prezzi, e 0 righe). Evitalo anche se i tuoi target renderizzano il contenuto nel browser e non vuoi aggiungere un renderer separato, perché trafilatura legge HTML statico e si ferma lì. E pensa due volte se il tuo corpus è fatto soprattutto di stub brevi, didascalie di immagini e pagine ricche di tabelle: sui fixture etichettati è proprio lì che la pulizia taglia contenuto reale (F1 0.571 sull’articolo molto breve, un <figcaption> perso). Abbina lo strumento al compito: testo completo di articoli, sì; JSON strutturato, pagine JS o stub da 100 parole, meglio guardare altrove.
Alternative, incluso dove si inserisce Thunderbit
trafilatura è una libreria self-hosted con licenza Apache-2.0 e senza fee per chiamata imposta dal vendor; restano a carico dell’operatore i costi di compute, banda, fetching, monitoraggio e manutenzione. Gestisce l’estrazione di contenuti orientata agli articoli a partire da HTML fornito, ma non l’esecuzione del browser né schemi di righe ripetute definiti dall’utente.
Per gli stessi fixture su tutte e sei le extractor, vedi il confronto tra sei librerie di estrazione.
Un servizio gestito può mettere acquisizione, rendering e modellazione dello schema dietro il confine di un fornitore. Noi realizziamo Thunderbit, ma non l’abbiamo eseguito su questi fixture, quindi questo articolo non supporta alcun confronto su qualità, rendering, latenza, anti-bot o costo. La scelta è tra controllo self-hosted dell’HTML verso il contenuto e un confine hosted per acquisizione ed estrazione strutturata.
Recensioni benchmark correlate: il confronto completo degli scraper open source, la review di Crawl4AI con browser e la review self-hosted di Firecrawl.
Prova Thunderbit per l’estrazione di dati dal web
Verdetto
Considera trafilatura quando il lavoro consiste nell’estrazione orientata agli articoli da HTML statico e la tua priorità è eliminare il boilerplate etichettato. Sui fixture condivisi ha lasciato passare un solo blocco di boilerplate annotato contro i cinque di Readability. Questo vantaggio è però arrivato con una minore conservazione nei fixture molto brevi e non narrativi, quindi la forma del corpus dovrebbe guidare la scelta.
Non esegue JavaScript né produce righe ripetute definite dall’utente. Nelle due pagine MediaWiki, author e sitename erano null: un’osservazione limitata al template. Readability ha conservato la didascalia che trafilatura ha rimosso e ha ottenuto un punteggio migliore nel fixture etichettato f3_short_120; l’evidenza visibile supporta “F1 più basso nel fixture molto breve”, non un conteggio di caratteri né l’affermazione che l’output fosse corrotto.
Prova Thunderbit per l’estrazione di dati dal web Get Started Free
FAQ
Che tipo di struttura restituisce trafilatura? Può serializzare contenuti estratti e metadati in JSON, Markdown, testo, HTML, XML o CSV. Si tratta di una serializzazione strutturata, ma non di uno schema di righe ripetute definito dall’utente, come nome prodotto, prezzo e valutazione. La fixture del catalogo ha restituito valori come contenuto piatto, non come righe tipizzate.
trafilatura può trasformare un catalogo prodotti in righe strutturate? No. È un estrattore di contenuti, non uno scraper strutturato. Su una fixture di catalogo ha restituito tutti i 12 nomi prodotto come testo piatto e 0 righe strutturate — i nomi sono nell’output, ma non sono campi. Se ti servono record tipizzati come nome/prezzo/valutazione, usa invece un parser basato su selettori o un’API di estrazione guidata da schema.
trafilatura rende JavaScript? No. Consuma solo HTML statico. Se lo punti a una pagina renderizzata lato client, ottieni ciò che il server ha inviato prima dell’esecuzione del JavaScript, che spesso non è il contenuto desiderato. Affiancalo a un renderer separato se i tuoi target fanno molto uso di JS.
trafilatura è difficile da installare?
Nel virtualenv Python 3.14 testato, l’installazione ha scaricato 17 pacchetti e non ha richiesto un runtime browser separato. La wheel più grande registrata era lxml, da 8,6 MB. Separatamente, una singola chiamata locale a una pagina 500 ha impiegato 30.012 secondi per restituire None; usa un client HTTP controllato dal chiamante se ti serve una scadenza verificabile.
trafilatura è gratuito per uso commerciale? È licenziato Apache-2.0, quindi permissivo e favorevole all’uso commerciale. Come sempre, verifica la licenza corrente nel repo prima di costruirci sopra.


