Skip to content
EVE Milano Consulenza SEO

EveMilano Logo White EveMilano Logo White

Costruire una lista di keyword per Google Ads non è più una questione di brainstorming su un foglio Excel e poi caricamento manuale via Keyword Planner. Le campagne moderne convivono con broad match potenziato da Smart Bidding, Performance Max con search themes, varianti simili sempre più larghe e Search Terms Report che esplodono in migliaia di query uniche da governare. In questo scenario, la keyword research si fa pipeline: dati grezzi in ingresso, ranking e clustering programmatici, output strutturato pronto per Ads Editor.

Questa guida descrive una pipeline replicabile in Python che combina quattro fonti dati ortogonali — Google Search Console API, Google Ads API, DataForSEO Labs ed embeddings semantici — per generare, scorare e clusterizzare la lista keyword di una campagna SEM. Ogni stage è accompagnato da uno snippet eseguibile, dalle scelte di filtraggio e dalle insidie operative che emergono quando la pipeline va in produzione su account reali con centinaia di campagne e migliaia di keyword.

Il taglio è engineering-grade: presuppone padronanza di Python, pandas, autenticazione OAuth/service account, e familiarità con la terminologia Google Ads del 2026 (no BMM, phrase match allargata, broad + Smart Bidding come combo nativa). La sezione finale racconta gli errori più comuni in produzione e come evitarli.

Perché un revamp ingegnerizzato della keyword research

La keyword research di Google Ads è cambiata in profondità tra il 2021 e il 2024. Tre eventi hanno reso obsolete le checklist scritte fino a quel momento e hanno spostato il baricentro del lavoro dall’editing manuale all’orchestrazione di dati.

Cosa cambia nel 2026: broad + Smart Bidding, search themes, sparizione del BMM

Il Broad Match Modifier è stato deprecato a febbraio 2021 e definitivamente assorbito dal phrase match esteso a luglio dello stesso anno. Da allora i match type disponibili sono tre più la lista delle negative: broad, phrase, exact. Contestualmente Google ha spinto sulla combinazione broad + Smart Bidding (tCPA, tROAS, Maximize Conversion Value), portando la piattaforma a interpretare le keyword più come signal che come filtri rigidi. Performance Max, lanciata a fine 2021 e potenziata con i search themes nel 2024, ha completato il quadro: le keyword non sono più l’unica leva di targeting, ma restano lo scheletro semantico su cui le strategie ibride costruiscono ad group e asset group.

La conseguenza operativa è che oggi una lista keyword serve a tre cose distinte e va costruita avendole tutte e tre in mente: alimentare gli ad group di Search a phrase/exact per le query ad alto intent, fornire seed di discovery alle campagne broad+Smart Bidding, e contribuire come search themes ai pacchetti Performance Max. Per dettagli sui match type rimando alla guida dedicata sulla corrispondenza delle parole chiave in Google Ads.

Quando la ricerca manuale non scala più

Tre soglie operative segnano il passaggio obbligato dal foglio Excel alla pipeline:

  • Inventario superiore a 500 SKU o catalogo articolato per categoria/brand/feature: la combinatoria delle query brand × prodotto × intent supera rapidamente i limiti di gestione manuale. Per scenari da catalogo grande conviene affiancare le Dynamic Search Ads alla ricerca tradizionale.
  • Search Terms Report con oltre 5.000 query uniche al mese: il negative keyword mining manuale diventa impraticabile e si perde gettito su query da escludere ma high-volume.
  • Account multi-mercato con localizzazioni linguistiche: tradurre/adattare la lista a mano produce errori sistematici sulle varianti idiomatiche. L’embedding multilingua risolve il problema nativamente.

Sotto queste soglie l’overhead della pipeline non si ripaga; sopra, è l’unica strada per non lasciare gettito a terra.

Architettura della pipeline

Diagramma orizzontale dei sette stage della pipeline di keyword research: dalle fonti dati al CSV di import in Google Ads Editor
Architettura della pipeline a sette stage: dalle fonti dati (GSC, Ads API, DataForSEO) fino all’export CSV per Google Ads Editor.

La pipeline si articola in sette stage sequenziali, ciascuno con responsabilità definita e contratto di I/O chiaro. Ogni stage produce un DataFrame pandas che diventa input dello stage successivo, in modo da rendere il processo ispezionabile passo per passo e ripartibile da qualunque checkpoint intermedio.

Diagramma a stage: i sette passaggi

  1. Seed generation — Estrazione query organiche performanti da Google Search Console come base semantica.
  2. Espansione semantica — Generazione varianti tramite Google Ads Keyword Plan Idea Service, DataForSEO Labs e LLM-assisted expansion.
  3. Enrichment metriche — Volume mensile, CPC top of page bid, competition index, search intent.
  4. Scoring multi-fattore — Combinazione pesata di volume, intent, competition e CPC per ranking finale.
  5. Clustering semantico — Embedding multilingua, riduzione dimensionale UMAP, clustering HDBSCAN per la struttura ad group.
  6. Negative keyword mining — N-gram analysis del Search Terms Report storico per identificare termini da escludere.
  7. Export Ads Editor — Generazione CSV con assegnazione match type per cluster e checklist pre-attivazione.

Setup ambiente: credenziali e dipendenze

Prima di iniziare servono tre set di credenziali e uno stack Python predefinito. Le credenziali Google (GSC + Ads) vivono in service account JSON; quelle DataForSEO in coppia login/password caricata da .env. Lo stack minimo per la pipeline:

# requirements.txt — stack pipeline keyword research
pandas>=2.2
numpy>=1.26
python-dotenv>=1.0
google-api-python-client>=2.130     # GSC API
google-ads>=24.0                     # Google Ads API (Keyword Plan Idea Service)
httpx>=0.27                          # DataForSEO REST
sentence-transformers>=3.0          # embedding multilingua
umap-learn>=0.5
hdbscan>=0.8
scikit-learn>=1.5
tldextract>=5.1

Se l’account Ads non è ancora attivo, la guida di partenza è come creare un account Google Ads con i prerequisiti di fatturazione e setup property. Il developer token Google Ads va richiesto separatamente dal Manager Account (MCC).

Stage 1 — Seed generation da Search Console

Il primo errore della keyword research tradizionale è partire da un’ipotesi commerciale (“queste sono le keyword del mio mercato”). Il modo corretto è partire da dati osservati: quali query già portano traffico al sito e con quale performance. La Search Console API searchanalytics.query permette di estrarre fino a 50.000 righe per chiamata, filtrabili per device, country, search appearance.

Estrazione query organiche via searchanalytics API

L’obiettivo è raccogliere il pool di query organiche degli ultimi 90-180 giorni con almeno una soglia minima di impression. Il payload va in formato dimensioni multiple (query, page) per poter poi associare ogni query alla landing page corrispondente, utile in fase di scoring per il match keyword-LP.

from google.oauth2 import service_account
from googleapiclient.discovery import build
import pandas as pd

creds = service_account.Credentials.from_service_account_file(
    "service-account.json",
    scopes=["https://www.googleapis.com/auth/webmasters.readonly"],
)
webmasters = build("searchconsole", "v1", credentials=creds)

request = {
    "startDate": "2025-11-01",
    "endDate": "2026-05-01",
    "dimensions": ["query", "page"],
    "rowLimit": 25000,
    "startRow": 0,
}
resp = webmasters.searchanalytics().query(
    siteUrl="sc-domain:evemilano.com", body=request
).execute()

rows = resp.get("rows", [])
df_gsc = pd.DataFrame([{
    "query": r["keys"][0],
    "page": r["keys"][1],
    "clicks": r["clicks"],
    "impressions": r["impressions"],
    "ctr": r["ctr"],
    "position": r["position"],
} for r in rows])

Filtri operativi: impressioni, CTR, posizione, branded

Le query estratte vanno filtrate prima di entrare nello stage successivo. I criteri minimi sono:

  • Soglia impressioni: scartare query con < 30 impressioni nel periodo (rumore, query rarissime).
  • Esclusione query branded: il termine brand non va comprato (cannibalizza l’organico e genera CPC inutilmente alto). Si filtra via regex sul nome del brand e sue varianti.
  • Posizione media: separare il pool in due bucket — query già in top 3 (potenziale espansione su intent affini) e query in posizione 5-30 (low-hanging fruit per Ads in attesa che maturi la SEO).
  • Deduplicazione lessicale: applicare normalizzazione lowercase + strip accenti + unicode NFKC per evitare di duplicare “scarpe running” e “Scarpe Running”.

Il pool risultante è tipicamente nell’ordine di qualche migliaio di query. Questo è il seed set della pipeline.

Stage 2 — Espansione semantica

Il seed set di GSC è ricco ma incompleto: contiene solo query che già rankano sul sito. Per coprire l’intero spazio semantico del mercato bisogna espanderlo con fonti esogene. Tre canali, da combinare:

Endpoint nativo di Google Ads API che restituisce idee di keyword correlate alle seed, con metriche storiche di volume, competition e CPC range. Vantaggio: dati ufficiali Google, gli stessi che vede il Keyword Planner web. Limite: una chiamata accetta fino a 20 seed e restituisce fino a 10.000 idee, quindi su seed set di migliaia di query servono batch e gestione del rate limit. Lo stesso servizio supporta anche modalità generateKeywordIdeas da URL della landing page, utile per recuperare semantiche legate al posizionamento attuale.

DataForSEO Labs offre tre endpoint chiave che si integrano nel flusso senza overlap con Google Ads API:

  • dataforseo_labs_google_related_keywords — keyword semanticamente correlate con grafo di profondità (depth) configurabile, utile per coprire varianti non emerse da Google Ads.
  • dataforseo_labs_google_keyword_suggestions — espansione long-tail per ogni seed, copre prefissi e suffissi tematici.
  • dataforseo_labs_google_ranked_keywords applicato a competitor diretti — recupera l’intero spazio keyword dei concorrenti, fondamentale per scoprire intent non coperti.

LLM-assisted expansion: varianti, intent, modificatori

Gli LLM (Claude, GPT-5, Gemini) sono particolarmente efficaci per due task che le API tradizionali non coprono bene: la generazione di modificatori commerciali per intent (transactional vs informational vs comparison) e la traduzione/localizzazione idiomatica delle keyword in mercati multipli. Prompt strutturato di esempio, da chiamare in batch su gruppi di 20-30 seed alla volta:

SYSTEM_PROMPT = """Sei un keyword researcher Google Ads.
Per ogni seed in input genera fino a 15 varianti raggruppate per intent:
- transactional (compra, acquista, prezzo, sconto, offerta)
- comparison (vs, migliore, recensione, opinioni)
- informational (cos'e, come funziona, guida)
Output JSON: {seed: {transactional: [], comparison: [], informational: []}}.
Mantieni la lingua del seed. Niente keyword branded di competitor.
"""

import json
from anthropic import Anthropic
client = Anthropic()

def expand_seeds(seeds: list[str]) -> dict:
    msg = client.messages.create(
        model="claude-opus-4-7",
        max_tokens=4096,
        system=SYSTEM_PROMPT,
        messages=[{"role": "user", "content": json.dumps(seeds)}],
    )
    return json.loads(msg.content[0].text)

La combinazione delle tre fonti produce un expanded set tipicamente 10-30x più grande del seed iniziale. La deduplicazione finale si fa via embedding (cosine similarity > 0.95 = duplicato semantico) per non perdere varianti utili ma anche non gonfiare la lista con sinonimi inutili.

Stage 3 — Enrichment metriche

L’expanded set è una lista grezza di keyword senza dati. Per poter applicare uno scoring servono almeno quattro metriche per ciascuna: volume di ricerca mensile, CPC range, competition index, search intent. Le prime tre vengono dal Keyword Planner via API o da DataForSEO, l’ultima da DataForSEO Labs search_intent o da classificazione LLM.

Volume, CPC, competition da Keyword Planner

La generateKeywordHistoricalMetrics di Google Ads API accetta fino a 10.000 keyword per chiamata e restituisce per ciascuna: avg_monthly_searches, monthly_search_volumes (ultimi 12 mesi mese per mese, per analisi stagionalità), competition (LOW/MEDIUM/HIGH + index 0-100), low_top_of_page_bid_micros e high_top_of_page_bid_micros (CPC bid range, in micro-euro).

Search intent classification via DataForSEO Labs

DataForSEO Labs search_intent classifica ogni keyword in quattro categorie — informational, navigational, commercial, transactional — con probabilità associata. Per le campagne Ads gli intent rilevanti sono commercial e transactional: le informational vanno tipicamente verso campagne Display o YouTube, non Search. La classificazione automatica risparmia ore di etichettatura manuale e si rivela coerente con quella umana nel ~85% dei casi (test empirico su dataset italiani).

Stagionalità: monthly searches per picchi e trend

Il dato di volume medio mensile nasconde stagionalità che cambiano la pianificazione budget. Una keyword come “regali natale” può avere 100k impressioni medie/anno ma concentrare il 70% del traffico in novembre-dicembre. L’array monthly_search_volumes permette di calcolare un seasonality coefficient per ogni keyword:

import numpy as np

def seasonality_score(monthly_volumes: list[int]) -> float:
    """Coefficient of variation: 0 = traffico costante, >0.5 = stagionale forte."""
    arr = np.array(monthly_volumes, dtype=float)
    if arr.mean() == 0:
        return 0.0
    return float(arr.std() / arr.mean())

def peak_month(monthly_volumes: list[int]) -> int:
    """Mese (1-12) di picco assoluto."""
    return int(np.argmax(monthly_volumes)) + 1

df_kw["seasonality_cv"] = df_kw["monthly_volumes"].apply(seasonality_score)
df_kw["peak_month"] = df_kw["monthly_volumes"].apply(peak_month)

Le keyword con seasonality CV > 0.5 vanno in campagne dedicate con programmazione attivazione/sospensione, non miscelate con quelle a domanda costante.

Stage 4 — Scoring multi-fattore

Con tutte le metriche disponibili si può finalmente costruire un punteggio composito che ordini le keyword per attrattività. Il principio: una keyword vale se ha volume alto, intent giusto, competition bassa (cioè CPC abbordabile), e se la landing page disponibile è coerente con la query.

Formula di score: pesata volume × intent × competition × CPC

Lo scoring va vettorizzato in pandas per poter girare su decine di migliaia di keyword in pochi secondi. La formula non ha pretese teoriche: serve a ottenere un ranking ragionevole come punto di partenza che poi viene tarato sui risultati di campagna delle prime due settimane.

import numpy as np

INTENT_WEIGHT = {"transactional": 1.0, "commercial": 0.7,
                 "navigational": 0.3, "informational": 0.1}

def score_keywords(df):
    # Normalizzazione log per smorzare la coda lunga del volume
    df["vol_norm"] = np.log1p(df["avg_monthly_searches"]) / np.log1p(df["avg_monthly_searches"].max())
    # Competition gia 0-1; ribaltata: bassa competition = punteggio alto
    df["comp_inv"] = 1 - df["competition_index"] / 100
    # CPC bid: usiamo il low bid come proxy di accessibilita
    df["cpc_norm"] = 1 - (df["low_top_of_page_bid_eur"] / df["low_top_of_page_bid_eur"].quantile(0.95)).clip(0, 1)
    df["intent_w"] = df["intent"].map(INTENT_WEIGHT).fillna(0.1)

    df["score"] = (
        0.40 * df["vol_norm"] +
        0.30 * df["intent_w"] +
        0.20 * df["comp_inv"] +
        0.10 * df["cpc_norm"]
    )
    return df.sort_values("score", ascending=False)

Soglie di pruning: rimuovere quello che non serve

Lo scoring produce una distribuzione continua. Il pruning serve a tagliare la coda. Soglie operative tipiche:

CriterioSoglia di taglioMotivo
Volume medio mensile< 50Sotto questa soglia il dato è troppo rumoroso per gestire bid in modo affidabile
Intent= informationalDa spostare in campagne Display/Discovery, non Search
Competition index> 90 con CPC > 5 €Mercato saturato, ROI a rischio salvo budget enterprise
Score composito< percentile 25Coda inferiore, basso rendimento atteso

Quality Score atteso: matching keyword–landing page

Il Quality Score non è osservabile prima dell’attivazione, ma il suo principale driver — la pertinenza tra keyword e landing page — sì. Calcolando la cosine similarity tra l’embedding della keyword e l’embedding del title+H1+meta della LP candidata si ottiene un proxy quantitativo. Sotto similarity 0.45 la keyword va o riassegnata a un’altra LP o esclusa, perché un Quality Score basso porta CPC alti e Ad Rank scarso. Per il dettaglio dei fattori che pesano sul Quality Score rimando alla guida come aumentare il Quality Score di Google Ads.

Stage 5 — Clustering semantico per ad group structure

Scatter plot 2D dei cluster di keyword ottenuti dopo riduzione dimensionale UMAP e clustering HDBSCAN, colorati per ad group
Cluster semantici delle keyword dopo riduzione UMAP a 2D e clustering HDBSCAN: ogni colore corrisponde a un futuro ad group.

Raggruppare a mano alcune migliaia di keyword in ad group coerenti è lavoro tanto noioso quanto soggetto a errori sistematici: l’occhio si stanca, si tende a creare ad group troppo larghi o troppo granulari, e si perdono relazioni semantiche non lessicali (“scarpe corsa” e “running shoe” finiscono in ad group separati se ci si basa sul testo). L’approccio basato su embedding risolve entrambi i problemi.

Embedding multilingua con sentence-transformers

Il modello di riferimento per il clustering keyword cross-lingua è paraphrase-multilingual-mpnet-base-v2 della libreria sentence-transformers: vettori da 768 dimensioni, supporto nativo a 50+ lingue, qualità di sentence embedding superiore ai modelli generici tipo multilingual BERT. Per dataset molto grandi si può scendere a paraphrase-multilingual-MiniLM-L12-v2 (384 dim, 3x più veloce, qualità leggermente inferiore).

UMAP + HDBSCAN per cluster naturali

I 768 dimensioni dell’embedding sono troppi sia per la visualizzazione sia per la qualità del clustering (curse of dimensionality). UMAP riduce a 5-15 dimensioni preservando la struttura locale, e HDBSCAN trova cluster di densità variabile senza richiedere di specificare k a priori, marcando come noise i punti che non appartengono a nessun cluster denso. Combinazione che funziona meglio di KMeans su dati testuali, dove cluster sono naturalmente di dimensioni asimmetriche.

from sentence_transformers import SentenceTransformer
import umap
import hdbscan

model = SentenceTransformer("paraphrase-multilingual-mpnet-base-v2")
embeddings = model.encode(df_kw["keyword"].tolist(),
                          batch_size=64, show_progress_bar=True)

# Riduzione dimensionale per il clustering
reducer = umap.UMAP(n_neighbors=15, n_components=10,
                    metric="cosine", random_state=42)
emb_reduced = reducer.fit_transform(embeddings)

# Clustering density-based
clusterer = hdbscan.HDBSCAN(min_cluster_size=8, min_samples=3,
                            cluster_selection_method="eom")
df_kw["cluster"] = clusterer.fit_predict(emb_reduced)
# cluster == -1 sono noise: keyword "orfane" da gestire manualmente

Validazione cluster: silhouette e naming ad group

HDBSCAN va validato prima di essere accettato in produzione. Tre check:

  • Silhouette score medio per cluster (escludendo noise): valori > 0.3 indicano cluster ben separati. Valori sotto 0.15 segnalano che l’embedding non distingue bene le keyword e va valutato un modello migliore o seed più diversificati.
  • Ispezione manuale dei primi 5 cluster per dimensione: se contengono keyword evidentemente eterogenee (es. brand mescolati con prodotti generici), abbassare min_cluster_size o aumentare n_neighbors di UMAP per cluster più granulari.
  • Naming automatico ad group: per ogni cluster, estrai i 3 token più frequenti (TF-IDF) e usali come ad group name. Naming alternativo: usare un LLM per generare un nome semantico data una lista di 10 keyword campione del cluster.

Stage 6 — Negative keyword mining via n-gram analysis

Le negative keyword sono il fattore più sottovalutato della keyword research. In account maturi, una negative list ben costruita può abbattere il CPA del 20-40% in due settimane senza modificare nient’altro. Il problema è scoprire quali negative aggiungere, e qui l’n-gram analysis del Search Terms Report è lo strumento più affilato disponibile.

Estrazione Search Terms Report storico

Il Search Terms Report di Google Ads contiene tutte le query effettive che hanno attivato gli annunci. Estraibile via Google Ads API con query GAQL search_term_view: campi essenziali sono search_term, clicks, impressions, cost_micros, conversions, conversions_value. Periodo consigliato: ultimi 90 giorni con almeno 100 click per dare significatività statistica all’analisi successiva.

N-gram analysis: 1, 2, 3-gram su query non-converting

L’idea: scomporre ogni search term in 1-gram, 2-gram e 3-gram, e aggregare costo e conversioni per ogni n-gram. Gli n-gram con alto costo cumulato e zero o pochissime conversioni sono candidati negative. Il livello di n-gram conta: gli 1-gram catturano negative generici (“gratis”, “lavoro”), i 2-gram e 3-gram pattern più specifici (“come fare”, “fai da te”).

from collections import defaultdict
import pandas as pd

def ngrams(text: str, n: int) -> list[str]:
    tokens = text.lower().split()
    return [" ".join(tokens[i:i+n]) for i in range(len(tokens) - n + 1)]

def mine_negatives(df_terms: pd.DataFrame, n: int = 2,
                   min_cost: float = 20.0, max_cvr: float = 0.005) -> pd.DataFrame:
    stats = defaultdict(lambda: {"cost": 0, "conv": 0, "imp": 0})
    for _, row in df_terms.iterrows():
        for g in ngrams(row["search_term"], n):
            stats[g]["cost"] += row["cost_eur"]
            stats[g]["conv"] += row["conversions"]
            stats[g]["imp"] += row["impressions"]
    out = pd.DataFrame([
        {"ngram": k, **v, "cvr": v["conv"] / max(v["imp"], 1)}
        for k, v in stats.items()
    ])
    return out[(out["cost"] >= min_cost) & (out["cvr"] <= max_cvr)] \
        .sort_values("cost", ascending=False)

Promozione dei top n-gram a livello campagna o ad group

I top n-gram candidati vanno classificati prima di essere caricati come negative:

  • Negative trasversali (es. “gratis”, “torrent”, “lavoro”, “stipendio”) → livello account o lista negativa condivisa.
  • Negative di intent (es. “come fare”, “fai da te”, “tutorial”) → livello campagna per le sole campagne transactional.
  • Negative di segmento (es. “usato” per un brand che vende solo nuovo) → livello ad group dell’ad group specifico.

La revisione manuale prima dell’upload è non negoziabile: un n-gram che sembra negativo può nascondere intent legittimi su query specifiche. Esempio classico: “economico” è candidate negative per un brand premium ma legitimate keyword per un’altra campagna dello stesso account.

Stage 7 — Export per Google Ads Editor

L’output finale della pipeline è un CSV importabile in Google Ads Editor con le colonne nello schema esatto richiesto dalla piattaforma. Ads Editor è preferibile alla UI web per upload bulk per due motivi: la validazione preventiva degli errori prima del push e la possibilità di fare diff visivi tra stato locale e stato live.

Schema CSV Ads Editor: le colonne obbligatorie

ColonnaValoreNote
CampaignNome campagna esistenteDeve esistere o essere creata in altro foglio
Ad groupNome cluster derivato dallo Stage 5Naming automatico da TF-IDF o LLM
KeywordTesto keywordSenza wildcard, lowercase consigliato
Match typeBroad, Phrase o ExactAssegnazione automatica da regole cluster (vedi sotto)
StatusEnabled o PausedDefault consigliato Paused, attivazione manuale post-review
Max CPCCifra in euro (opzionale)Sovrascritto se la campagna è in Smart Bidding
Final URLLanding page assegnataDerivata dal matching keyword-LP dello Stage 4

Assegnazione automatica match type per cluster

La regola operativa che funziona meglio in account misti:

  • Exact per keyword con intent transactional, score > percentile 75, già presenti come query convertenti nel Search Terms storico.
  • Phrase per keyword con intent commercial o transactional, score percentile 50-75. È il match type più equilibrato post-2021 dopo l’assorbimento del BMM.
  • Broad da usare solo in campagne con Smart Bidding attivo (tCPA o tROAS) e con negative list robusta: senza queste due condizioni il broad disperde budget.
def assign_match_type(row, score_q75, score_q50, converting_terms: set) -> str:
    kw = row["keyword"]
    if row["intent"] == "transactional" and row["score"] >= score_q75 \
       and kw in converting_terms:
        return "Exact"
    if row["intent"] in {"commercial", "transactional"} and row["score"] >= score_q50:
        return "Phrase"
    return "Broad"

q75 = df_kw["score"].quantile(0.75)
q50 = df_kw["score"].quantile(0.50)
df_kw["match_type"] = df_kw.apply(
    lambda r: assign_match_type(r, q75, q50, converting_set), axis=1
)

cols = ["Campaign", "Ad group", "Keyword", "Match type",
        "Status", "Max CPC", "Final URL"]
df_kw.rename(columns={"campaign": "Campaign", "cluster_name": "Ad group",
                       "keyword": "Keyword", "match_type": "Match type",
                       "max_cpc": "Max CPC", "final_url": "Final URL"}) \
     .assign(Status="Paused")[cols] \
     .to_csv("ads_editor_import.csv", index=False, encoding="utf-8-sig")

Checklist pre-attivazione

  • Tutte le keyword caricate in stato Paused: attivazione progressiva per cluster, non massiva.
  • Verifica che ciascun ad group abbia almeno 3 annunci responsive coerenti con il cluster semantico.
  • Negative list dello Stage 6 già caricata prima di attivare le nuove campagne (importante: la negative deve precedere la live).
  • Tracking di conversione testato end-to-end: senza Quality Score signal corretto dal day-1 lo Smart Bidding parte male e impiega settimane a recuperare.
  • Per dettagli sull’ottimizzazione post-launch vedi come ottimizzare una campagna Google Ads.

Errori comuni e troubleshooting

Over-clustering: ad group troppo granulari

HDBSCAN con min_cluster_size troppo basso (es. 3-4) produce centinaia di micro-ad group con 5-10 keyword ciascuno. In Smart Bidding questa granularità diventa controproducente: ogni ad group ha pochi conversion event, il signal è rumoroso, l’algoritmo non riesce a ottimizzare. Regola empirica: nessun ad group sotto le 15 keyword se la campagna usa Smart Bidding. Soluzione: alzare min_cluster_size a 12-20, oppure fare un secondo step di merge cluster simili via cosine similarity sui centroidi (soglia 0.85).

Volume Planner overfit: il dato non coincide con il traffico reale

I volumi di Keyword Planner sono aggregati per varianti close-match: la stessa keyword in account diversi mostra spesso forchette larghe (es. 100-1K). In assenza di developer token con account a spesa alta, l’API restituisce range arrotondati. Per fare scoring affidabile su keyword vicine alla soglia di pruning, integrare i volumi DataForSEO o Google Trends come secondo segnale e prendere la mediana dei due. Per la corrispondenza ufficiale dei volumi degli account ad alta spesa, vedi la documentazione su generateKeywordHistoricalMetrics della Google Ads API Keyword Planning.

API rate limit e quota: pattern di retry e backoff

Google Ads API ha quote giornaliere e per-minute che variano con il tier dell’account (Basic vs Standard). Per pipeline che eseguono migliaia di chiamate, tre pattern obbligati:

  • Batch size massimo: 10.000 keyword per generateKeywordHistoricalMetrics, 20 seed per generateKeywordIdeas. Sopra queste soglie la chiamata fallisce silenziosamente.
  • Retry con exponential backoff sugli errori 429 (rate limit) e 503 (service unavailable): partire da 2 secondi e raddoppiare fino a 64 secondi, poi failure.
  • Caching aggressivo dei risultati intermedi (parquet o sqlite) per non ri-chiamare le stesse keyword se la pipeline va in errore a metà strada.

Conclusioni e prossimi step

La pipeline descritta — dal seed GSC al CSV per Ads Editor — porta la keyword research da arte artigianale a processo ingegnerizzato e replicabile. Una volta consolidata, gira in un’ora su account di medie dimensioni e in 4-6 ore su account enterprise con catalogo multi-mercato. I benefici diretti misurabili nelle prime 4-8 settimane di campagna sono: copertura semantica più ampia del seed solo umano, ad group con coerenza interna superiore (Quality Score atteso più alto), e abbattimento del rumore Search Terms grazie alla negative list mining.

I prossimi step naturali sono due. Primo, automatizzare l’esecuzione settimanale dello Stage 6 (negative mining) per intercettare i nuovi search term che emergono man mano che le campagne maturano. Secondo, alimentare uno scoring di secondo livello con i dati di performance live (CTR, conversion rate, ROAS effettivi) per il feedback loop che ribilancia bid e match type ad ogni ciclo. Questa è la base per costruire un sistema di ottimizzazione continua delle campagne — argomento che merita una guida a sé.

Per supporto sulla progettazione o sull’audit di campagne Google Ads complesse vedi i nostri servizi di consulenza Google Ads.

Articoli correlati

22 min lettura

Il Quality Score di Google Ads è uno strumento diagnostico basato su dati storici a 90 giorni per valutare la pertinenza delle keyword. Analisi tecnica di CTR atteso, rilevanza e landing page experience per abbattere i CPC e ottimizzare l'ad quality score dell'account.
42 mi piace
22 min lettura

Un audit SEO tecnico completo richiede un approccio manuale rigoroso che supera i limiti intrinseci dei tool automatici. Metodo strutturato e template professionale per identificare criticità di scansione, valutare i fattori di ranking e ottimizzare le performance dei siti web.
41 mi piace
14 min lettura

L'analisi del rendering di un sito web da parte di Googlebot è essenziale per diagnosticare criticità di indicizzazione. Metodi tecnici per verificare l'esecuzione di JavaScript e l'interpretazione del DOM, garantendo che il motore processi correttamente ogni singola pagina web.
38 mi piace

Autore

Commenti |2

Lascia un commento Lascia un commento
  1. Monica Mony 1 commento

    Processo pratico e utile, grazie Giovanni per la spiegazione. I tuoi articoli sono sempre interessanti!

    1. Giovanni Sacheli 774 risposte

      Grazie Monica per il tuo feedback! Spero di trovarti presto in altri commenti :)

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Ultimi articoli aggiornati

20 min lettura

Pipeline ingegnerizzata in Python per costruire una lista di keyword Google Ads moderna: seed da Search Console, espansione con Ads API e DataForSEO, scoring multi-fattore, clustering semantico via UMAP e HDBSCAN, mining negative da n-gram analysis ed export CSV per Ads Editor. Otto snippet eseguibili, scelte di filtraggio e troubleshooting da produzione.
1 mi piace
24 min lettura

L'advertising hijacking sfrutta redirect chain e cloaking server-side per dirottare il traffico navigazionale tramite frodi sui programmi affiliate. Analisi tecnica delle vulnerabilità nel brand bidding e pipeline operativa in Playwright per il brand SERP monitoring avanzato.
0 mi piace
88 min lettura

Analisi tecnica delle innovazioni Google Ads 2023-2025 per professionisti. Focus sull'impatto dell'IA generativa, l'evoluzione del bidding automatizzato e l'integrazione di Consent Mode v2 per ottimizzare le conversion action e le performance delle campagne avanzate.
2 mi piace
5 min lettura

Il dominio @xwf.google.com identifica le email legittime dell'Extended Workforce di Google Ads. Verifica l'autenticità dei messaggi e analizza criticamente le ottimizzazioni proposte da questi collaboratori esterni, spesso incentivati all'aumento della spesa piuttosto che al ROI.
2 mi piace

Richiedi un preventivo SEO e Google Ads

Porta il tuo sito web al livello successivo con l’esperienza di EVE Milano. La nostra agenzia di Search Marketing ha ricevuto oltre 1207 richieste di preventivo, un segnale chiaro della fiducia che imprenditori e manager, come te, ripongono nella nostra specializzazione tecnica e verticale nella SEO e PPC. Se la tua organizzazione cerca competenze specifiche per emergere nei risultati di Google, noi siamo pronti a fornire quel valore aggiunto. Richiedi un preventivo ora e scopri la differenza tra noi e gli altri.
Richiedi un preventivo

Vuoi ricevere un avviso al mese con le nuove guide pubblicate?

Iscriviti alla newsletter!