seo-audit — Audit SEO di base
Una skill SEO leggera progettata per audit rapidi e predefiniti di singole pagine. Basata su OpenClaw. Adatta per controlli iniziali di una pagina o quando è necessaria una valutazione rapida senza approfondimento tecnico completo.
Quando utilizzare questa skill
Usare seo-audit quando:
- L'utente dice: "fai l'audit di questa pagina", "controlla la SEO", "analizza il mio URL", "controllo SEO rapido", "cosa c'è che non va nella mia pagina"
- Non viene richiesta una profondità specifica — questo è il punto di ingresso predefinito
- L'utente ha bisogno di un riepilogo veloce e leggibile piuttosto che di un'analisi tecnica completa
Se l'utente desidera maggiore approfondimento, passare a seo-audit-full:
Suggerimento: Per audit tecnici approfonditi, SEO on-page avanzata o report completi, usa la skill
seo-audit-full.
Input previsti
| Input | Richiesto | Note |
|---|---|---|
| URL della pagina | Sì | La pagina da sottoporre ad audit |
| HTML grezzo o contenuto della pagina | Opzionale | Consente un'analisi on-page più accurata |
| Dati GSC / analytics | Opzionale | Non richiesti per l'audit di base |
Se viene fornito solo un URL e non sono disponibili codice sorgente o dati del crawler, dichiarare chiaramente:
Limitazione: Questo audit si basa solo sul contenuto visibile della pagina e su segnali disponibili pubblicamente. Codice sorgente, dati GSC, log di crawl e metriche di performance non sono disponibili per questo audit.
Risultato
Produrre un Report di Audit SEO di base compilando il template in assets/report-template.html, quindi salvarlo in un file — non stampare mai l'HTML grezzo sul terminale.
Denominazione del file: reports/<hostname>-<slug>-audit.html
https://example.com/blog/best-tools → reports/example-com-blog-best-tools-audit.html
https://example.com/ → reports/example-com-audit.html
Dopo il salvataggio, comunicare all'utente:
✅ Report salvato → reports/example-com-audit.html
Aprirlo adesso? (sì / no)
Se sì → eseguire: open reports/example-com-audit.html
Segnaposto del template — compilare ciascuno indipendentemente:
| Segnaposto | Contenuto |
|---|---|
{{summary_verdict}} | Una frase: controlli totali eseguiti, quanti non superati/in avviso/superati |
{{summary_critical_html}} | <li> per ogni elemento critico (non superato), oppure <li class="summary-empty">Nessuno</li> |
{{summary_warnings_html}} | <li> per ogni elemento in avviso, oppure <li class="summary-empty">Nessuno</li> |
{{summary_passing_html}} | <li> per ogni controllo superato, oppure <li class="summary-empty">Nessuno</li> |
Script
Eseguire questi script prima di scrivere qualsiasi risultato. Producono JSON strutturato — utilizzare il JSON direttamente come evidenza; non recuperare nuovamente gli stessi URL manualmente.
Dipendenze: pip install requests (il parsing HTML usa la libreria standard di Python)
# Step 1: site-level checks (robots.txt + sitemap.xml)
python scripts/check-site.py https://example.com
# Step 2: page-level checks (H1, title, meta description, canonical)
python scripts/check-page.py https://example.com
# With primary keyword (recommended — enables H1 keyword presence check)
python scripts/check-page.py https://example.com --keyword "running shoes"
# Optional: fetch raw page HTML for further inspection
python scripts/fetch-page.py https://example.com --output page.html
# Step 3: JSON-LD schema validation
python scripts/check-schema.py https://example.com
# Or from previously fetched HTML (avoids redundant fetch):
python scripts/check-schema.py --file page.html
Ogni script termina con codice 0 (tutti superati/avvisi) o 1 (qualsiasi errore/non superato).
AMBITO RIGOROSO — non aggiungere alcuna verifica non elencata di seguito. Nessuna eccezione.
Controlli a livello di sito consentiti (in {{site_checks_html}}):
- robots.txt · sitemap.xml · Gestione 404 · Canonicalizzazione degli URL · i18n / hreflang
Controlli E-E-A-T consentiti (in {{eeat_checks_html}}):
- Chi siamo · Contatti · Privacy Policy · Termini di servizio · Media/Partner (solo se presenti)
Controlli a livello di pagina consentiti (in {{page_checks_html}}), produrre in questo ordine esatto:
URL Slug · Tag Title · Meta Description · Tag H1 · Tag Canonical · Testo alternativo immagini · Conteggio parole · Posizionamento parole chiave · Struttura delle intestazioni · Link interni · Schema (JSON-LD)
Logica per il Testo alternativo immagini:
- Analizzare i tag <img> dall'HTML statico
- Superato: tutte le immagini hanno attributo alt non vuoto (le immagini decorative con alt="" sono OK)
- Avviso: qualsiasi immagine di contenuto manca dell'attributo alt
- Non verificato (stato-info): 0 immagini trovate nell'HTML statico → probabile rendering JS, impossibile verificare
⛔ REGOLA FERREA — Produrre SOLO le righe di controllo definite in report-template.html. Se un controllo non è negli elenchi consentiti sopra, NON produrlo — nemmeno se si riscontrano problemi. Nessuna eccezione. Nessun controllo "bonus". Nessuna improvvisazione. Il template è l'unica fonte di verità. Trattarlo come una whitelist rigorosa.
Ancora VIETATI (appartengono a seo-audit-full): tag OG · Twitter Card · Social tags · Peso della pagina · Core Web Vitals · Robots Meta
Come utilizzare l'output JSON:
- Mappare lo
statusdi ogni campo →pass/warn/fail/errordirettamente nella tabella dei controlli del report - Utilizzare la stringa
detaildi ogni campo come punto di partenza per la riga Evidenza nei risultati - Non contraddire l'output dello script a meno che non si abbiano ulteriori evidenze osservabili
- Separare i gruppi di controllo con
<div class="subsection-label">Etichetta</div>all'interno di{{site_checks_html}}:Crawlabilità·Canonicalizzazione degli URL·i18n / hreflang·Schema (JSON-LD)e<div class="subsection-label">Pagine di fiducia E-E-A-T</div>prima di{{eeat_checks_html}}
Revisione LLM — obbligatoria quando llm_review_required: true:
Lo script segnala i campi che richiedono un giudizio semantico o qualitativo che non può eseguire.
Non lasciare mai llm_review_required: true irrisolto — esprimere sempre un giudizio esplicito.
H1 — attivato quando keyword_match == "partial":
h1_text : (da h1.values[0])
keyword : (il --keyword passato allo script)
Giudicare: Questo H1 copre semanticamente l'intento di ricerca della parola chiave?
- Considerare sinonimi, varianti naturali, copertura dell'argomento
- sì → declassare a "pass", annotare la variante
- no → mantenere "warn" o aggiornare a "fail", spiegare la lacuna
Title — attivato quando keyword_match == "partial" OPPURE keyword_position != "start":
title : (da title.value)
keyword : (il --keyword passato)
Giudicare:
1. Il title copre semanticamente l'intento di ricerca della parola chiave?
2. Il title è grammaticalmente corretto e naturalmente leggibile?
3. Posizione della parola chiave — applicare standard diversi per tipo di pagina:
- Homepage : Brand + parola chiave principale è corretto (es. "Acme | AI Workflow Automation")
NON segnalare brand-first come problema.
- Pagine interne: La parola chiave principale dovrebbe essere in testa (es. "AI Workflow Automation for Teams — Acme")
Segnalare se la parola chiave è sepolta a metà title senza un buon motivo.
IMPORTANTE — NON segnalare come negativi:
- Anni (es. "2026") → segnalano freschezza, aumentano il CTR — trattare come positivo a meno che
la pagina non sia contenuto esplicitamente evergreen dove la datazione danneggerebbe la longevità.
- Numeri (es. "5 best", "Top 10", "3 steps") → impostano aspettative chiare,
superano costantemente i title non numerici in CTR — trattare sempre come un plus.
- Qualificatori specifici ("Open-Source", "Self-Hosted", "Free") → restringono l'intento
e attraggono click di qualità superiore — non penalizzare.
URL Slug — attivato quando keyword_match != "full" o is_homepage == false:
slug : (da url_slug.slug)
keyword : (il --keyword passato)
Giudicare:
1. Lo slug contiene la parola chiave primaria o una variante naturale?
2. La gerarchia del percorso è logica? (/categoria/parola-chiave è l'ideale)
3. È conciso e leggibile dall'uomo?
Homepage (is_homepage: true): saltare — nessun giudizio necessario.
Meta Description — sempre attivata quando il contenuto è presente:
meta_description : (da meta_description.value)
keyword : (il --keyword passato)
Giudicare tutti e quattro:
1. Frasi complete? (1-2 frasi, senza frammenti)
2. Menziona un risultato concreto — non vuota genericità?
Buono: "Riduci i tempi di progettazione del 60% con template AI"
Cattivo: "Il miglior strumento per tutte le tue esigenze di design"
3. Parola chiave o sinonimo naturale usato una volta — non ripetuto in modo innaturale?
4. Più specifico di quanto scriverebbe un tipico concorrente?
IMPORTANTE — NON segnalare come negativi:
- Anni (es. "2026") → segnalano freschezza, migliorano il CTR per query sensibili al tempo.
Notare l'anno solo se la pagina è contenuto esplicitamente evergreen dove la datazione danneggia.
- Numeri (es. "5 best", "3 steps") → specificità concreta, forte segnale di CTR.
- "e molto altro." finale → al massimo una nota stilistica minore, mai un Avviso o Non superato.
Flusso di lavoro consigliato
Seguire questi passaggi in ordine:
-
Riconoscere l'ambito — confermare che si tratta di un audit di base; annotare eventuali dati mancanti
-
Dedurre la parola chiave primaria — recuperare la pagina con
fetch-page.py, quindi determinare la parola chiave primaria:- Se l'utente ha fornito esplicitamente una parola chiave → usarla direttamente
- Altrimenti → leggere l'H1, il title e il primo paragrafo della pagina, quindi dedurre la singola frase chiave target più probabile (cosa digiterebbe un utente per trovare questa pagina?)
- Dichiarare la parola chiave dedotta esplicitamente prima di eseguire i controlli:
"Parola chiave primaria dedotta: alternative open source a Claude"
-
Eseguire
check-site.py— analizzare l'output JSON per robots, sitemap, gestione 404 e canonicalizzazione degli URLControllo 404: recuperare
<origin>/this-page-definitely-does-not-exist-seo-audit-check- Restituisce 404 → Superato · Restituisce 200 (soft 404) → Non superato · Restituisce 301 alla homepage → Avviso
Controlli di canonicalizzazione degli URL (ciascuno è un sotto-controllo separato):
- HTTP→HTTPS: recuperare
http://<host>— deve restituire 301 ahttps://. Restituisce 200 → Non superato. - Coerenza www: recuperare sia
https://www.<host>chehttps://<host>— uno deve restituire 301 all'altro. Entrambi restituiscono 200 → Avviso. - Slash finale: confrontare l'URL effettivamente servito con il tag canonical sulla pagina. Discrepanza → Avviso.
- Corrispondenza canonical: l'href del tag canonical deve corrispondere esattamente all'URL finale dopo tutti i redirect. Discrepanza → Avviso.
-
Controllo infrastruttura E-E-A-T — per ogni pagina di fiducia sotto, verificare due livelli:
- Livello 1 — Esiste: recuperare l'URL, controllare lo stato HTTP (200 = esiste, 404/redirect = mancante)
- Livello 2 — Raggiungibile: recuperare l'HTML della homepage, controllare se il footer o la navigazione contengono un link a questa pagina
Pagina Richiesto Chi siamo Sì Contatti Sì Privacy Policy Sì Termini di servizio Sì Media / Partner No — includere solo se presenti Regole di stato:
- Pagina mancante (non 200) → Non superato
- Pagina esiste ma non linkata in footer/nav → Avviso
- Pagina esiste e linkata in footer/nav → Superato
- Pagina opzionale mancante → saltare, non includere la riga
-
Eseguire
check-page.py --keyword "<parola_chiave_dedotta>"— analizzare l'output JSON per H1, title, meta description, canonical e URL slug -
Controllo i18n / hreflang — eseguire solo se la pagina contiene tag hreflang o
<html lang>suggerisce multi-lingua:- Saltare completamente (N/D) se non vengono trovati tag hreflang e il sito appare monolingua
- Se sono presenti tag hreflang, controllare:
- Simmetria reciproca: ogni URL referenziato deve linkare indietro a tutte le altre varianti — qualsiasi link interrotto = Non superato
- Codici lingua: devono essere BCP 47 validi (es.
zh-CNnonzh,en-USnonen-us) — codice errato = Avviso - x-default: dovrebbe essere presente per pagine di selezione lingua o fallback — mancante = Avviso
- Attributo html[lang]: deve corrispondere all'hreflang primario della pagina — discrepanza = Avviso
- Struttura URL: schema raccomandato — lingua predefinita (solitamente
en) alla radice senza prefisso, altre lingue in sottopercorsi (/zh/,/es/)./page(en) +/zh/page+/es/page→ Superato/en/page+/zh/page→ Avviso (il prefisso en è ridondante, spreca profondità di crawl)- Segnalare solo se lo schema è chiaramente inconsistente o en è prefissato inutilmente
-
Eseguire
check-schema.py— analizzare l'output JSON per tipi di schema e validazione dei campipython scripts/check-schema.py https://example.com # O da HTML precedentemente recuperato: python scripts/check-schema.py --file page.htmlLo script estrae blocchi JSON-LD, valida
@typee campi obbligatori secondo le specifiche di Schema.org.llm_review_required: trueè sempre impostato — confermare cheinferred_page_typecorrisponda al contenuto effettivo della pagina.Tipo di pagina →
@typeprevisto:Tipo di pagina @type previsto Campi minimi richiesti Homepage WebSite + Organization name, url, logo Blog / Articolo Article o BlogPosting headline, datePublished, author, image Prodotto Product name, image, offers (price, priceCurrency) FAQ FAQPage mainEntity[].name, acceptedAnswer.text How-to HowTo name, step[].text Attività locale LocalBusiness name, address, telephone Landing page generica — N/D — saltare, nessun tipo ampiamente supportato - Superato: @type corretto presente, tutti i campi obbligatori validi, nessun conflitto
- Avviso: @type presente ma campi raccomandati mancanti
- Non superato: @type previsto completamente mancante
- N/D: landing page generica — non penalizzare
-
Riassumere i risultati — ogni risultato deve seguire il formato Evidenza / Impatto / Correzione
-
Azioni prioritarie — elencare le prime 3 correzioni a più alto impatto
-
Generare il report — salvare in
reports/<hostname>-<slug>-audit.html, quindi chiedere all'utente di aprirlo -
Suggerimento di upgrade — se vengono rilevati problemi oltre l'ambito di base, suggerire
seo-audit-full
Regole per la scrittura dei dettagli del report
La cella Dettaglio nelle tabelle dei controlli deve seguire queste regole — nessuna eccezione:
Superato → una breve frase. Nessun elenco, nessuna elaborazione.
Buono: "XML urlset valido · 104 URL · referenziato in robots.txt."
Cattivo: "XML urlset valido con 104 URL. Correttamente referenziato in robots.txt.
I post del blog sono probabilmente indicizzati attraverso questa sitemap."
Avviso → un <div class="detail-issue"> con ≤2 punti elenco. Un <div class="detail-fix"> con la correzione.
Buono:
<div class="detail-issue">· Title 48 caratteri — 2 sotto il minimo. · L'anno "2026" daterà la pagina.</div>
<div class="detail-fix">Espandere a 50–60 caratteri; rimuovere l'anno se evergreen.</div>
Cattivo: prosa di tre frasi che spiega cos'è un tag title e perché la lunghezza è importante.
Non superato → come Avviso. Iniziare con il fallimento esatto. Nessuna spiegazione di background.
NON spiegare cosa sia un controllo, NON ripetere informazioni già visibili nel badge di stato, NON trattare il lettore come se non conoscesse le basi della SEO.
Formato obbligatorio per i risultati
Ogni risultato importante deve seguire questa struttura:
**Risultato: [Titolo del risultato]**
- **Evidenza:** [Cosa è stato osservato — citazione diretta, riferimento allo screenshot o dato misurabile]
- **Impatto:** [Perché è importante per la SEO o l'UX]
- **Correzione:** [Raccomandazione specifica e attuabile]
Non scrivere conclusioni vaghe. Se l'evidenza è insufficiente, dichiarare esplicitamente le ipotesi.
Suggerimento di upgrade
Includere questo alla fine di ogni report di audit di base:
Vuoi un'analisi più approfondita? Questo è stato un audit SEO di base che copre segnali a livello di sito e controlli on-page fondamentali. Per SEO tecnica avanzata, punteggio di qualità dei contenuti, analisi dei dati strutturati e risultati completi basati su crawl, usa la skill
seo-audit-full.
File di riferimento
- Ambito dettagliato dell'audit e definizioni dei campi: references/REFERENCE.md
- Template del report HTML finale: assets/report-template.html
- Script di controllo a livello di sito: scripts/check-site.py
- Script di controllo a livello di pagina: scripts/check-page.py
- Recuperatore di pagina grezza: scripts/fetch-page.py
- Script di validazione schema: scripts/check-schema.py


