AIREITER

Immagine IA

FLUX.2 ProGPT-Image 2Wan 2.7 Image ProGPT 4o ImageSeedream 5.0 ProSeedream V5 liteSeedream V4.5Altro

Video IA

Kling 3.0 Motion ControlSora 2 ProKling 3.0 TurboSora 2Kling 3.0Grok Imagine 1.5Veo 3.1Altro

LLM

Gemini 3.6 FlashGemini 3.1 ProKimi K3Gemini 3 ProGemini 2.5 ProClaude Opus 5Claude Fable 5Altro
ProssimamenteSeedance 2.5
Super ResolutionLyric Video GeneratorGPT Image 2 1K GeneratorGPT Image 2 Product Mockup GeneratorUse GPT-5.6 Online
DOC APIPREZZI
BlogAggiornamentiLLM API GuideClaude API GuideKimi K3 API Guide
TEMPLATE
  • AIReiter
  • Blog
  • La B2B Ad Intelligence passa dall'HTML: come scrivere un parser che resiste ai redesign

La B2B Ad Intelligence passa dall'HTML: come scrivere un parser che resiste ai redesign

Ultimo Aggiornamento: 2026-07-31 07:00:24

Capire in quali Paesi un concorrente B2B sta facendo pubblicità in questo trimestre, da quanto tempo, con quale volume indicativo e verso quali segmenti di pubblico non dovrebbe essere complicato: quei dati si trovano nella sua libreria inserzioni pubblica, che molte piattaforme devono pubblicare per rispettare gli obblighi di trasparenza pubblicitaria. Poi apri DevTools, cerchi endpoint per un po' e scopri che non esiste una comoda API JSON: c'è solo una pagina intera di HTML renderizzato dal server. Scrivi un parser, funziona e raccogli i dati. Tre settimane dopo arriva un redesign della piattaforma: il parser non estrae più nemmeno un campo, senza però generare errori. Restituisce silenziosamente una serie di valori vuoti, e per poco non prendi una decisione su dati inesistenti.

Questo articolo spiega come mantenere operativo un parser del genere dopo un redesign e quale ruolo concreto può avere un modello nella manutenzione. Prima, però, un confine importante sui dati: tutto ciò di cui parliamo proviene dalle librerie inserzioni pubbliche e dai creative center delle singole piattaforme, consultati accedendo normalmente con il proprio account. Nessuna firma, nessun aggiramento, nessun endpoint non pubblico. Come vedremo, questo limite è incorporato esplicitamente nel design del parser.

Perché la B2B ad intelligence passa necessariamente dall'HTML

Anche tra le librerie pubblicitarie, i dati vengono esposti in modi molto diversi. Alcune librerie consumer, come quella di Meta, offrono ricerca strutturata e JSON; altre richiedono una sessione persino per effettuare una ricerca; nella maggior parte delle piattaforme B2B, invece, le librerie inserzioni sono puro HTML renderizzato dal server, senza alcun endpoint JSON. La ragione è semplice: queste librerie nascono come adempimento normativo, non come API di prodotto.

Esistono per soddisfare le regole sulla trasparenza delle inserzioni, non per essere chiamate dagli sviluppatori. Non hanno versioni, changelog o promesse di compatibilità retroattiva. La pagina è pensata per le persone: il server la renderizza e restituisce HTML, e l'unica “API” disponibile è di fatto la pagina web.

La fragilità, quindi, è intrinseca: dipendi dai dettagli implementativi dell'interfaccia di qualcun altro, che può modificarli quando vuole e non è tenuto ad avvisarti. In un'API JSON, cambiare un campo è almeno un cambiamento riconoscibile; per chi gestisce una pagina HTML, un redesign è normale iterazione frontend. Non si può eliminare questo rischio: si può solo progettare il parser perché degradi bene e sia rapido da sistemare dopo un redesign, invece di restituire campi vuoti in silenzio.

Un parser streaming scritto a mano riduce soprattutto il carico mentale

La reazione iniziale è prendere lxml o BeautifulSoup, costruire l'intero DOM della pagina e scendere con una catena di .find(). Funziona, ma per questo tipo di sorgente è l'approccio sbagliato. Il DOM è un prodotto intermedio della renderizzazione nel browser: MDN definisce il DOM come il parsing del documento in un albero di nodi accessibili dagli script attraverso la struttura. Qui, però, servono soltanto pochi campi. Non occorre costruire quell'albero, né legarsi alla sua struttura.

La soluzione a cui sono arrivato è una sottoclasse di HTMLParser della libreria standard Python: poco più di ottocento righe, 881 per l'esattezza, e interamente streaming. Alcune callback starttag / data / endtag alimentano una macchina a stati che accumula dati durante la scansione; quando raggiunge il confine di una card, emette un record, azzera lo stato e prosegue, senza mai costruire un DOM completo.

Il vantaggio dello streaming è molto concreto. Il primo è la memoria: l'HTML di una pagina di dettaglio arriva facilmente a decine o centinaia di KB; un DOM mantiene in memoria l'intera struttura, mentre lo streaming conserva solo lo stato necessario a sapere dove si trova e a che punto è la card corrente. Ancora più importante è il minor carico mentale. Nel momento in cui scrivi .find('div').find('div')[2], leghi il parsing alla posizione gerarchica nel DOM, esattamente ciò che un redesign tende a spostare: basta aggiungere un contenitore o separare un wrapper perché ogni posizione cambi. Una macchina a stati costringe invece a chiedersi soltanto se ciò che si sta leggendo sia, semanticamente, l'inizio di una card, un dato di impression o un tag di targeting. Le posizioni cambiano; la semantica molto meno.

Tre scelte progettuali per superare un redesign

In pratica, tutto si riduce a tre principi, ciascuno imparato sul campo dopo un redesign.

Primo: usare ancore semantiche, non posizionali. La macchina a stati avanza sulla base di segnali semantici: il testo dell'etichetta di un campo, parole leggibili come “impression totali” o “date di pubblicazione”, marcatori legati a un ruolo, il confine semantico di un blocco. Mai “il terzo nodo dall'alto”. Il test è semplice: se l'elemento viene spostato o racchiuso in un ulteriore livello, il parsing continua a funzionare? Se sì, l'ancora è valida. Le ancore di posizione saltano al primo redesign; quelle semantiche sopravvivono alla maggior parte delle modifiche puramente stilistiche.

Secondo: se manca un campo, degradare senza lanciare eccezioni. Prima di accumulare i dati di ogni card, inizializza un template in cui ogni campo ha un valore vuoto di default: stringa vuota per il testo, None per i numeri, array vuoto per le liste. Compila ciò che riesci a estrarre e lascia vuoto il resto. Il fallimento nell'estrazione di un singolo campo non deve invalidare l'intera card, tantomeno tutta la pagina. Se a un annuncio manca il testo della CTA, vuoi comunque conservarne impression e Paesi target. Lasciare che un campo secondario assente distrugga tutta l'intelligence ottenibile dalla pagina è il peggior design possibile.

Terzo: associare ai risultati un indicatore di completezza, affinché “vuoto” e “rotto” non sembrino la stessa cosa. È il punto più facile da trascurare e il più costoso. “0 annunci analizzati” può significare due cose completamente diverse: non ci sono davvero annunci, perché quell'inserzionista non ne ha pubblicati in questo trimestre; oppure la struttura della pagina è cambiata e nessuna ancora ha più funzionato, quindi il parser è rotto. I due casi devono essere distinguibili nel valore restituito. Il modo è allegare evidenze di controllo: il numero di card catturate, il totale dichiarato dalla pagina e lo stato della paginazione. Così, una combinazione come “0 card, ma i metadati della pagina indicano che dovrebbe esserci un batch e non c'è alcun marcatore di pagina successiva” può essere classificata come variazione strutturale anziché come reale assenza di dati, generando un errore esplicito invece di una lista vuota restituita passivamente.

Anche il limite sui dati definito prima entra in gioco qui: il parser controlla di non essere stato reindirizzato a una pagina di login e, se rileva che il titolo corrisponde a una pagina di login o registrazione, genera un errore invece di procedere con il parsing. Gestisce solo le pagine pubbliche visibili normalmente con il proprio account, si ferma davanti a un login wall e non tenta mai di oltrepassarlo.

Il valore dell'intelligence sta nelle dimensioni di filtro

A questo punto si potrebbe pensare che l'obiettivo sia estrarre perfettamente ogni campo di ogni annuncio. Non è così. I campi di un singolo annuncio, isolati, valgono poco; ciò che conta davvero è in base a quali dimensioni puoi segmentare gli annunci. I filtri di ricerca della libreria inserzioni sono già un elenco pronto di dimensioni di intelligence: trasformarli in parametri di query programmabili non restituisce “un annuncio”, ma una porzione del lancio di un concorrente.

  • Paese: in quali mercati fa pubblicità e in quali no. Quando un'azienda B2B inizia improvvisamente a promuoversi in un Paese, spesso segnala un'espansione prima ancora che la cosa emerga dal suo sito.

  • Periodo di pubblicazione, con date di inizio e fine: per quanto tempo è rimasta attiva una creatività. Un annuncio longevo è il segnale più forte, perché nessuno continua a pagare per una creatività che non converte. La durata della pubblicazione è di per sé il risultato di un A/B test validato con denaro reale e condotto dalla controparte.

  • Intervallo di impression, minimo/massimo: una stima approssimativa della spesa. Il valore assoluto non è preciso, ma basta per ordinare le creatività e capire quali siano gli acquisti prioritari.

  • Faccette di targeting: quali criteri di targeting sono inclusi o esclusi. È l'intelligence più diretta sul pubblico: chi, secondo il concorrente, è più propenso ad acquistare il suo prodotto.

L'estrazione dei campi è il mezzo; queste dimensioni sono il fine. Quando scrivi il parser, ragiona al contrario: per consentire query e ordinamenti su queste dimensioni, qual è il set minimo di campi che devo estrarre in modo affidabile? Gli altri campi più raffinati possono anche restare fuori senza ridurre il valore dell'intelligence.

Dopo un redesign, usa il modello per confrontare HTML vecchio e nuovo

Un parser di questo tipo prima o poi si romperà con un redesign. È proprio nella correzione che un modello trova il suo posto, non nel parsing stesso. Il parsing è lavoro deterministico, affidato a una macchina a stati hardcoded, e non dovrebbe contenere chiamate a modelli (non affidare lavoro deterministico a un modello: vale lo stesso principio usato nel reverse engineering). Il compito del modello è la manutenzione.

Il flusso è questo: apri la libreria inserzioni con il tuo account, conserva una copia dell'HTML salvata prima del redesign e una dell'HTML nuovo, poi fornisci al modello entrambi i documenti insieme all'elenco dei campi estratti dal parser attuale. Deve indicarti, confrontando vecchia e nuova struttura, quali ancore semantiche sono cambiate, quale dovrebbe essere la nuova ancora e quali sono le poche righe da modificare. È un caso da manuale per un modello di fascia reasoning: deve capire se la semantica corrispondente esiste ancora nella nuova struttura e produrre un piano applicabile, non limitarsi a dire che “la struttura è stata modificata”. Le varie fasi richiedono capacità diverse; usare un solo tier per tutto significa pagare troppo o perdere precisione:

Fase

Capacità necessaria

Scelta

model id

Leggere l'intero HTML SSR di una pagina e allineare struttura vecchia e nuova

Contesto lungo, capace di assorbire in una volta una pagina di dettaglio da decine a centinaia di KB

Kimi K3

kimi-k3

Dopo un redesign, leggere il diff vecchio-nuovo, capire dove è slittata l'ancora e proporre la correzione minima

Reasoning solido, capace di spiegare il problema sulla struttura anziché limitarsi a descriverlo

Claude Opus 5

claude-opus-5

Normalizzare e classificare in massa le card di centinaia di inserzionisti trasformandole in intelligence

Conveniente, con centinaia o migliaia di chiamate ad alta concorrenza

Claude Sonnet 5

claude-sonnet-5

Attribuzione delle differenze quando il confronto con le fixture fallisce

Reasoning intermedio, in grado di spiegare lo scarto tra “campo atteso” ed “estrazione effettiva”

GPT-5.6 Sol

gpt-5.6-sol

Il secondo tier è il fulcro, ed è l'unico passaggio in cui cambiare modello modifica visibilmente il risultato. Per capire se il tier reasoning valga il costo, non serve fidarsi sulla parola: basta provarlo con un protocollo breve.

  1. Salva l'HTML di una pagina prima di un redesign e uno dopo il redesign, aprendo la libreria inserzioni con il tuo account e salvando la pagina.

  2. Fornisci entrambi gli HTML e l'elenco dei campi del parser corrente a claude-opus-5 e gpt-5.6-sol.

  3. Osserva una sola cosa: la correzione indica un cambiamento preciso nell'ancora semantica, ad esempio “prima il parser si ancorava all'etichetta ‘impression totali’, nella nuova versione è cambiato il ruolo del contenitore dell'etichetta, quindi ancora a X”, oppure resta sul vago con “la struttura è stata modificata, si consiglia di riadattare”?

  4. Il primo risultato è applicabile subito, il secondo non dice nulla. Questa è la discriminante per la scelta, e determina direttamente quanti tentativi alla cieca dovrai fare il giorno del redesign.

Un solo giro di prova rende la differenza evidente, molto più di qualsiasi benchmark.

Il vero freno è il costo del cambio di modello

I quattro tier provengono da tre vendor, con tre SDK, tre meccanismi di autenticazione e tre formati di errore. Integrare tre client per fasi diverse porta molti a fare i conti, decidere che non valga la pena per “la correzione occasionale di un parser più la pulizia dati in bulk” e finire per usare sempre un solo modello. Per correggere un redesign si ritrovano così con un tier che sa solo dire “si consiglia di riadattare”, perdendo tempo senza capire il motivo.

AIReiter appiattisce questo livello: una sola chiave, un'unica interfaccia compatibile con OpenAI e tutti e quattro i tier disponibili dietro la stessa API. Per cambiare basta modificare il campo model nel body della richiesta.

# Correzione dopo un redesign: tier reasoning
curl https://aireiter.com/api/v1/chat/completions \
  -H "Authorization: Bearer $AIREITER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-opus-5",
    "messages": [{"role": "user", "content": "<old-new HTML diff + current field list, ask where the anchor drifted>"}]
  }'

# Normalizzazione dell'intelligence in bulk: cambia il campo model, lascia invariato il resto
#   "model": "claude-sonnet-5"
# Contesto lungo per leggere l'intera pagina: "model": "kimi-k3"
# Attribuzione delle differenze:             "model": "gpt-5.6-sol"

Se usi già l'SDK OpenAI, imposta base_url su https://aireiter.com/api/v1 senza modificare altro. Con l'SDK Anthropic, usa POST /api/v1/messages con la stessa chiave.

Sul fronte prezzi, i modelli Claude hanno uno sconto del 30% sul listino, i modelli GPT costano la metà e Kimi K3 è utilizzabile con la stessa chiave. In questo flusso, lo sconto incide proprio dove si concentra il costo: non nella correzione del redesign, che è una chiamata sporadica, poco frequente ma di alto valore, bensì nella normalizzazione dell'intelligence in bulk. Segui venti inserzionisti concorrenti, ciascuno con decine o centinaia di card, e le invii tutte al modello per estrarre promessa, pubblico e periodo di pubblicazione: è la fase più densa di chiamate e gira su Claude Sonnet con il 30% di sconto. Il secondo carico più consistente è l'input long-context necessario per leggere un'intera pagina e allinearne la struttura. Le due voci più costose coincidono con quelle scontate.

  • Ottieni una chiave API

  • Provalo senza registrarti: fornisci manualmente a entrambi i modelli una coppia di HTML prima/dopo e confronta quale riesce a indicare davvero dove è slittata l'ancora; poi decidi se integrarlo.

Dopo la correzione e la normalizzazione in massa delle card grezze, il passo successivo è usare questa intelligence nella pipeline creativa per prendere decisioni e generare asset. È il compito di l'intero ciclo dalla keyword all'annuncio finito; questo articolo ne descrive il segmento iniziale, cioè l'acquisizione affidabile dei dati pubblici.

Sui campi corretti, l'ultima parola spetta alle fixture

La correzione proposta dal modello resta solo un suggerimento finché non viene validata. Può dire “l'ancora va spostata su X”, e la proposta può sembrare ragionevole, ma non c'è alcuna garanzia che X funzioni su tutte le card. Gli annunci B2B possono essere immagine e testo, solo testo, carousel, con landing page o senza: i due esempi analizzati dal modello potrebbero non coprire tutti i casi.

Ciò che evita il problema è lo stesso meccanismo che ferma le allucinazioni dei modelli nel reverse engineering: il confronto su vettori fissi. Conserva come fixture, versionata nel repository, un insieme di input noti, cioè alcune pagine HTML reali salvate, con i rispettivi output corretti, ossia i risultati dei campi che hai verificato manualmente una volta. A ogni modifica del parser, sia che tu la faccia autonomamente sia che derivi da un suggerimento del modello, riesegui il batch di fixture e confronta i campi uno a uno. È l'unico modo per capire rapidamente, dopo un redesign a monte, se hai applicato male il suggerimento oppure se la pagina è cambiata di nuovo: se passa tutto, la modifica è corretta; se falliscono alcuni casi, i campi di quei casi mostrano direttamente a quale livello si trova il problema. Il modello genera suggerimenti di riparazione, la fixture decide se sono corretti: i due ruoli non devono essere confusi. Il metodo completo di confronto differenziale è illustrato in l'articolo sul differential testing, e il parser della libreria inserzioni applica lo stesso controllo. Senza questo livello, stai scambiando la sicurezza espressa dal modello per correttezza effettiva; è facile “applicare il suggerimento, non vedere errori, distribuire la modifica e scoprire tre giorni dopo che i dati di un Paese erano rimasti vuoti per tutto il tempo”.

In sintesi

La B2B ad intelligence passa dall'HTML perché la libreria inserzioni è un adempimento di compliance e non un'API di prodotto: non esiste un contratto API e i redesign possono arrivare in qualunque momento. La resistenza al deterioramento dipende da tre scelte: ancore semantiche anziché posizionali, degradazione sui campi mancanti invece di eccezioni, risultati accompagnati da un indicatore di completezza così che “vuoto” e “rotto” siano distinguibili. Il valore reale non è nel singolo campo dell'annuncio, ma nelle dimensioni Paese, periodo di pubblicazione, intervallo di impression e faccette di targeting, che permettono di sezionare il lancio di un concorrente. Il modello ha un ruolo preciso: non nel parsing, che è una macchina a stati deterministica, ma nella manutenzione. Il confronto tra HTML vecchio e nuovo dopo un redesign, per ottenere suggerimenti di riparazione, è il punto in cui serve il tier reasoning; trasformare le card in intelligence in massa è invece lavoro da tier economico ad alta concorrenza. La correttezza dei campi, però, passa sempre dalle fixture. Collegando questi tier a un'unica interfaccia, l'unico attrito rimasto è cambiare un campo model, risolto da scegliere il modello.

>_Directory modelli AIReiter

Accesso API rapido ai modelli collegati a questa guida

Claude Opus 5

Chat

Un modello Claude premium per ragionamenti complessi, programmazione e lavoro professionale su contesti lunghi.

anthropicCrea API Key >

Claude Sonnet 5

Chat

Un modello Claude equilibrato per ragionamento avanzato, coding e lavoro quotidiano.

AnthropicCrea API Key >

Kimi K3

Chat

Un modello di ragionamento a lungo contesto per coding, scrittura, analisi e workflow agentici.

moonshotCrea API Key >

GPT-5.6 Sol

Chat

Un modello di testo GPT-5.6 premium per attività impegnative di coding, ragionamento e lavoro agentico a lungo formato.

OpenAICrea API Key >

Claude Fable 5

Chat

Un modello Claude premium per il ragionamento profondo e il lavoro complesso su contenuti lunghi.

AnthropicCrea API Key >

Post recenti

Taglio dei prezzi di GPT-5.6: quanto costano davvero Luna e Terra

2026-07-31

API Key non valida: diagnostica 401 e 403 prima di intervenire

2026-07-31

Risolvere OpenRouter 429: errore del provider o limite di frequenza?

2026-07-31

DeepSeek V4 Flash vs GLM-5.2: test dell'aggiornamento 0731

2026-07-31
AIREITER

Domande? Contattaci a
[email protected]

LLM

Gemini 3.6 FlashGemini 3.1 ProKimi K3Gemini 3 ProGemini 2.5 Pro

Video IA

Kling 3.0 Motion ControlSora 2 ProKling 3.0 TurboSora 2Kling 3.0

Immagine IA

FLUX.2 ProGPT-Image 2Wan 2.7 Image ProGPT 4o ImageSeedream 5.0 Pro

Blog

Vedi Tutto →

Azienda

Informativa sulla privacyTermini di servizioPolitica di rimborso

© 2026 AIReiter. Tutti i diritti riservati.