Briljant

Van SEO-bulk naar veel minder maar relevantere content

Hoe je met data, embeddings en een beetje Python je content eindelijk opschoont

TL;DR

Na positieve reacties op mijn LinkedIn post deel ik hier mijn eerste experiment met Python en embeddings om content te analyseren. Deze methode combineert harde data (verkeer, conversies) met inhoudelijke relevantie via openAI om te bepalen welke content waardevol is en wat weg kan. Belangrijk: ik ben zelf een Python-beginner en dit is vooral bedoeld als inspiratie. Er zijn vast betere methodes, maar deze werkt voor mij. Zie het als een startpunt om je eigen aanpak te ontwikkelen.

SEO-blogs… Ieks!

We kennen ze allemaal: die eindeloze stroom blogs, FAQ’s en how-to’s, vooral geschreven om te “ranken” en omdat we allemaal aan de EEAT moeten! We schreven (schrijven) echt nog veel te veel voor machines; niet omdat iemand écht zat te wachten op het antwoord, maar omdat een keywordtool zei dat er volume op zat. En ja, dan gaan de SEO’s rennen.

Het resultaat? Talloze contentsecties, blogs en kennisbanken die uitpuilen van digitale bagger. Honderden pagina’s waar niemand blij van wordt. Niet de bezoeker, niet de klant, en zeker Google (en andere Search Engine’s) niet meer anno al een tijdje.

We weten stiekem allemaal dat het grootste deel van die content compleet irrelevant is. Maar ja, opschonen… Dat schuiven we voor ons uit. Want waar begin je? En hoe bepaal je wat weg kan, zonder nattevingerwerk? En weten we wel echt zeker dat het niets bijdraagt? We zijn ook gewoon bang om kwijt te raken wat we hebben als we iets ouds aanpassen.

Content opschonen: niet alleen gevoel, niet alleen data

We zijn een tijd geleden begonnen met het aanpakken van deze low quality content. en dat wil eigenlijk zeggen, we zijn gaan kijken wat nou wel werkt en wat niet, wat is Low quality uberhaupt? Eerst deden we dat handmatig – goed werk kost nou eenmaal tijd, en het is ook nog eens erg “satis” (ja ik probeer ook jong van taal te blijven) om alles handmatig te valideren. Maar zodra je honderd(en) pagina’s moet nalopen, weet je: dit is niet schaalbaar.

Daarom hebben we het omgedraaid. Niet meer denken vanuit “is deze tekst goed?”, maar vanuit:

  • Helpt het de bezoeker écht verder?
  • Is het relevant?
  • Doet deze pagina überhaupt nog iets?

En dat bepaal je niet alleen op gevoel, maar vooral op basis van data én een schaalbare manier om inhoudelijke relevantie te meten.

De basis: eerst weten wát je hebt

Voordat je ook maar nadenkt over verwijderen of aanpassen, moet je één ding helder hebben: wat staat er allemaal live, en wat doet het? En om daar achter te komen geen sprookjes of luchtkastelen, maar gewoon echt analyseren. Data vergaren en dat doet deze dino echt nog steeds in Excel.

We hebben daarom alle content bij elkaar geharkt in een overzicht. Maar niet alleen URL’s en titels, ook:

  • Publicatie- en update-datum
  • Data uit Google Search Console: vertoningen, klikken, CTR
  • Data uit GA4: sessies, transacties, omzet, kanalen (organisch vs. betaald vs. direct)
  • Data uit SE Ranking & Sistrix: aantal rankende zoekwoorden per pagina, gemiddelde positie
  • Crawldata via JetOctopus, Sitebulb en contentking: indexeerbaarheid, statuscodes, interne links, bot visits, crawl depth
  • En straks: een check op inhoudelijke relevantie (daar komen de embeddings om de hoek)

Het resultaat is geen mooie grafiek of dashboard, maar een monstrueuze sheet vol data en feiten. Alles samengebracht in een draaitabel, waarin je met wat slimme Excel-indexformules elk onderwerp kunt terugvinden, analyseren en onderbrengen in overzichtelijke draaitabellen. Zo zie je wat echt presteert, wat achterblijft, en wat alleen maar doet alsof het belangrijk is.

Hoe weet je of content écht relevant is?

Je hebt nu een mooie set data. Je weet welke pagina’s/secties of onderwerpen verkeer krijgen, welke indexeerbaar zijn, en welke gewoon vulling zijn zonder enige prestatie. Daar kun je al keuzes op maken, maar misschien is de content in potentie juist wel goed maar heeft het aanpassing nodig. Je weet dus na die analyse nog steeds niet of die content ook inhoudelijk iets toevoegt.

En nee, daar heb je geen Yoast-bolletje of keyword dichtheid of minimaal aantal woorden of weetikveel dan ook voor nodig.

Wat je wél nodig hebt, is een manier om te meten of een pagina antwoord geeft op een vraag van je bezoeker. Niet of een bepaald zoekwoord erin voorkomt, maar of de inhoud aansluit bij de bedoeling achter die vraag. Dat kan aan de ene kant door handmatig de recordings uit Mouseflow of Hotjar te raadplegen, maar ook dat is niet schaalbaar.

Dat is waar embeddings in beeld komen.

Embeddings: betekenis in plaats van woorden tellen

Klinkt spannend, maar het is eigenlijk heel simpel.

Embeddings zorgen ervoor dat je tekst niet meer als losse woorden ziet, maar als een getallenreeks die de betekenis van die tekst vastlegt. Een soort coördinaat in een digitale ruimte waar teksten die inhoudelijk op elkaar lijken, automatisch dicht bij elkaar liggen.

Dus stel, je hebt de vraag:

“Hoe was ik mijn hond op de juiste manier?”

En je hebt een blog met de titel:

“Tips voor het wassen van een hond.”

Met embeddings kun je berekenen hoe dicht die twee bij elkaar liggen qua betekenis. Dat gaat veel verder dan simpel keyword-matchen. Je ziet of de content écht antwoord geeft op de vraag, ook als de exacte woorden anders zijn (in dit voorbeeld gat het om de hele tekst achter de titel, niet alleen om het matchen van de titel dus).

Wat heb je nodig?

  • Een lijst met klantvragen vanuit surveys, klantenservice of user research
    • Kan ook uit bijv. AlsoAsked, Search Console, of een keywordtool, maar die zijn minder secifiek voor jou of je klant
  • De teksten van je bestaande contentpagina’s
  • Een Python script en toegang tot een embedding-model (bijv. van OpenAI)

Je laat Python voor elke vraag en elke contentpagina een embedding berekenen, en daarna vergelijk je die met elkaar. De uitkomst is een relevantie-score. Hoe hoger die score, hoe beter jouw content aansluit op de vraag.

En dan?

Je voegt die score toe aan je bestaande data (je Excel-lijst). Zo krijg je een compleet beeld:

URLVertoningenCTRKeywordsSessiesBezoekersTransactiesRelevantie-score
/blog/hond-wassen12003.2%1518025150.89
/blog/hoe-vaak-wassen301.1%232000.22
/faq/wassen-hond00%10300.91

Nu wordt het interessant. Maar onthoud: deze data is input voor beslissingen, niet de beslissing zelf:

  • Lage score + weinig verkeer = overweeg verwijderen, maar check met het team
  • Hoge score + weinig verkeer = potentieel voor optimalisatie
  • Lage score + veel verkeer = waardevol signaal, mogelijk aanpassen
  • Hoge score + goed verkeer = behouden en mogelijk uitbreiden

Aan de slag: In 6 stappen van SEObulk naar relevantie

Ja, dit kun je heel lang vooruit blijven duwen maar het is een kwestie van gewoon doen. Dit is hoe je jouw content kritisch tegen het licht houdt met data, embeddings en een beetje Python.

Stap 1: Haal alles boven water

Begin met een volledige export van je content. Nee, niet alleen de URL’s, maar álle relevante data:

  • Google Search Console: vertoningen, klikken, CTR, gemiddelde positie
  • GA4: sessies, transacties, omzet (split per kanaal: organisch, betaald, direct, sociaal, referral)
  • SE Ranking: aantal rankende zoekwoorden per pagina, zoekvolumes, positieverdeling, indexstatus
  • JetOctopus: indexeerbaarheid, statuscodes, bot visits, crawl frequentie, interne links
    • Of ScreamingFrog, Sitebulb, Conductor, Xenu (jaja) of welke crawltool dan ook
  • CMS data: publicatie- en laatste update-datum

Gooi alles in één overzicht. Excel is prima – maak hier je centrale dashboard van. Elke regel is een URL, elke kolom een belangrijke metric. Het hoeft niet mooi, het moet compleet zijn.

Stap 2: Verzamel échte klantvragen

Niet verzonnen SEO-zoekwoorden, maar vragen die mensen daadwerkelijk stellen:

  • Een lijst met klantvragen vanuit surveys, klantenservice of user research
  • Kan dus ook uit bijv. AlsoAsked
  • Vul aan met queries uit Search Console

Doel: een lijst met échte vragen waarop jouw content antwoord zou moeten geven.

Stap 3: Bereken inhoudelijke relevantie

Hier komt de magie:

  • Gebruik een Python-script om embeddings te genereren van jouw klantvragen en de contentpagina’s
  • Bereken de similarity score (cosine similarity voor de liefhebber)
  • Resultaat: een score tussen 0 en 1 die zegt hoe goed je content inhoudelijk aansluit op elke vraag

Ik deel straks een voorbeeldscript waarmee je zo aan de slag kunt. Maar let op, dit is MIJN knutselwerk en ik ben GEEN programmeur.

Stap 4: Combineer alles in je analyse

Voeg die relevantie-scores toe aan je Excel-lijst. Nu heb je per pagina:

  • Wat doet het qua verkeer & conversie?
  • Is het indexeerbaar?
  • Hoe relevant is het inhoudelijk?

Dit is waar het overzicht ontstaat. Geen discussies meer over gevoel, maar harde feiten als basis voor een teambeslissing. Nogmaals de data dient als input, niet als reden.

Stap 5: Bepaal per pagina wat je doet

Gebruik een scorecard-systeem waarbij elke factor bijdraagt aan de totale waarde van een pagina. Let op! Dit is een voorbeeld, jouw uiteindelijke beslissing is case-afhankelijk en dient ook samengenomen te worden met het gehele team:

Performance Scorecard (0-100 punten)

FactorWegingUitleg
Verkeer (alle kanalen)25%Organisch, betaald, direct, social, referral – diversiteit is positief
Conversiewaarde25%Directe omzet, leads, micro-conversies
SEO prestaties15%Rankings, CTR, vertoningen, aantal keywords
Content relevantie15%Embedding-score, bounce rate, time on page
Technische gezondheid10%Crawlability, Core Web Vitals, mobile-ready
Strategische waarde10%Past bij doelgroep, ondersteunt customer journey, merkpositionering

Actie op basis van totaalscore:

  • 80-100: Premium content – behouden, uitbreiden, intern promoten
  • 60-79: Solide basis – behouden, kleine optimalisaties doorvoeren
  • 40-59: Potentieel – grondige analyse nodig, grote update of herpositionering
  • 20-39: Zwakke content – samenvoegen met andere content of compleet herschrijven
  • 0-19: Verwijderen – redirect naar relevante pagina of 410 status

Praktische implementatie:

  1. Bereken voor elke factor een score van 0-100
  2. Pas de weging toe
  3. Tel op voor de totaalscore
  4. Neem beslissing op basis van de scorecard in combinatie met zelf (en met het team) goed nadenken

Bonus: Contextfactoren

  • Seizoenaliteit: Betreft het seizoensgebonden content?
  • Content type: Blog vs. Advies vs. Koophulp etc.
  • Fase van de klant: Welk framework je dan ook gebruikt
  • Concurrentie: Hoe uniek is deze content in de markt?

Deze methode zorgt ervoor dat geen enkele metric dominant is, maar dat de gezamenlijke waarde van content bepaalt wat je ermee doet. Gebruik de data als hulpmiddel, niet als eindoordeel.

  • Dubbele content? → Samenvoegen en redirecten
  • Content gap? → Nieuwe content maken, maar check eerst of bestaande content niet geoptimaliseerd kan worden

Stap 6: Ruimen maar (en blijf het doen)

Opschonen is geen eenmalige actie. Plan dit periodiek in. Nu je het proces deels hebt geautomatiseerd, is het makkelijk om regelmatig te checken wat nog waardevol is.

En onthoud: less is more. Liever 100 goede pagina’s dan 500 die alleen maar in de weg staan.

Zo draai je zelf een content-relevantie analyse (zonder developer te zijn)

Nee, je hoeft écht geen developer te zijn. Je moet gewoon even weten welke stappen je zet. Met deze uitleg draai je binnen no-time je eigen contentanalyse.

Ik ben zelf pas net begonnen met Python. Er zijn waarschijnlijk veel betere, snellere en slimmere methodes om dit aan te pakken. Zie dit vooral als een eerste opstap en inspiratie. Zoals met alles geldt: er zijn duizend wegen naar Rome. Gebruik wat voor jou werkt en schroom niet om het aan te passen!

Stap 1: Installeer Python & Visual Studio Code

Eerst even wat huiswerk:

  • Python installeren: Download via python.org. Gewoon de nieuwste versie. Tijdens installatie vink je even “Add Python to PATH” aan. Check na installatie of het gelukt is door python –version te typen in je terminal.
  • Visual Studio Code (VS Code) installeren: Download via code.visualstudio.com. Dit is een gratis en simpele code-editor waarin je je script straks gaat draaien.

Klaar? Mooi.

Stap 2: Zet je bestanden klaar

Maak op je computer een duidelijke map. Bijvoorbeeld zoiets:

/content-analyse/
├── vragen.csv (je klantvragen uit AlsoAsked of GSC)
├── content.csv (je huidige website-content)
├── analyse_script.py (dit is straks jouw Python script)
└── output/ (hier komt straks je resultaat)

Tip: Heb je HTML-bestanden of onhandige formats? Gebruik een eenvoudige editor als Notepad++ (gratis download) met een HTML-plugin. Daarmee maak je snel schoon leesbare teksten voor je analyse.

Stap 3: Regel je OpenAI API-key

Ga naar platform.openai.com en maak een betaald account aan. Ja, helaas niet gratis, maar ook niet duur (denk aan paar euro per analyse).

  • API-key aanmaken: klik op je account > “View API keys”
  • Maak een nieuwe sleutel aan, sla ‘m veilig op
  • Tip: Zet je API-key nooit direct in je code. Gebruik een .env file voor betere security

Welk model heb je nodig?

  • text-embedding-ada-002: Voor relevantie checken (goedkoop, snel)
  • GPT-3.5/4: Als je korte samenvattingen of extra analyses wil maken (iets duurder)

Stap 4: Zet het script op

Hieronder de basiscode van het Python-script (anoniem en compact). Maak in VS Code het bestand analyse_script.py aan en plak dit erin:

import pandas as pd
import openai
import numpy as np
import os
from sklearn.metrics.pairwise import cosine_similarity

# Vul hier je eigen API key in
openai.api_key = "JOUW_API_KEY_HIER" # Beter: gebruik os.getenv('OPENAI_API_KEY')

# Laad je bestanden
try:
    vragen_df = pd.read_csv('vragen.csv', encoding='utf-8')
    content_df = pd.read_csv('content.csv', encoding='utf-8')
except FileNotFoundError as e:
    print(f"Fout: Bestand niet gevonden - {e}")
    exit()

# Functie om embeddings op te halen
def get_embedding(text):
    response = openai.Embedding.create(
        input=text,
        model='text-embedding-ada-002'
    )
    return response['data'][0]['embedding']

# Maak embeddings
vragen_df['embedding'] = vragen_df['vraag'].apply(get_embedding)
content_df['embedding'] = content_df['content'].apply(get_embedding)

# Bereken relevantie
resultaten = []
for _, vraag_row in vragen_df.iterrows():
    for _, content_row in content_df.iterrows():
        score = cosine_similarity(
            [vraag_row['embedding']], [content_row['embedding']]
        )[0][0]
        resultaten.append({
            'vraag': vraag_row['vraag'],
            'pagina': content_row['url'],
            'score': score
        })

# Opslaan als CSV
resultaten_df = pd.DataFrame(resultaten)
resultaten_df.to_csv('output/resultaten.csv', index=False)
print("Klaar! Check je 'output/resultaten.csv'.")

Belangrijk:

  • Check of je CSV-bestanden de juiste kolomnamen hebben (vraag, content, url)
  • Je kunt altijd kolomnamen aanpassen in je script

Stap 5: Run je script

Open in VS Code onderaan de terminal (Ctrl+`) en voer uit:

pip install openai pandas numpy scikit-learn

Daarna start je het script met:

python analyse_script.py

Je ziet nu vanzelf hoe Python voor je aan de slag gaat.

Foutmeldingen? Geen stress!

Zie je errors en kom je er niet uit? Gewoon even aan ChatGPT vragen:

“Ik krijg deze foutmelding [kopieer de fout]. Kun je me helpen?”

Serieus, werkt altijd.

Handige tips

  • Tokenmanagement: lange teksten (>2000 tekens) kun je beter afkappen om tokens en dus kosten te besparen. Het text-embedding-ada-002 model kan ongeveer 8,000 tokens verwerken.
  • Grote datasets: splits je bestanden als het script te lang duurt. 500-1000 pagina’s per keer werkt prima
  • Drempelwaardes: meestal is een relevantiescore boven de 0.7 sterk, daaronder minder. Test wat werkt voor jouw content
  • Encoding problemen: Krijg je errors bij het inlezen van CSV’s? Voeg encoding=’utf-8′ toe aan je pd.read_csv() functie

Wat krijg je nu als resultaat?

Je hebt nu in /output/resultaten.csv een heldere lijst:

vraagpaginascore
Hoe was ik een hond?/blog/hond-wassen0.89
Hoe vaak was je een kat?/blog/hoe-vaak-wassen0.45

Zo zie je direct welke pagina’s écht antwoorden op je klantvragen, en welke niet.

Belangrijkste inzichten & valkuilen

Ik heb nu uitgelegd hoe je content snel en slim kunt beoordelen op basis van data én inhoudelijke relevantie. Werkt prima, maar ik wil nog even wat valkuilen en tips delen uit eigen ervaring:

  • Blind vertrouwen op cijfers: Verkeer betekent niet altijd relevantie. Blijf zelf kritisch kijken naar inhoud, en betrek altijd je team bij belangrijke beslissingen.
  • Embeddings zijn geen magie: Ze zijn goed, maar soms geven ze rare scores. Vertrouw op je verstand, en gebruik embeddings als ondersteuning, niet als absolute waarheid.
  • Te veel automatiseren: Niet alles hoeft automatisch. Je moet zelf nog wel nadenken over welke pagina’s je écht weggooit of aanpast.
  • Team betrekken: Content-beslissingen hebben impact op meerdere afdelingen. Neem de scores mee als input voor een teambeslissing, niet als eindbeslissing.

Kortom: cijfers én gezond verstand samen gebruiken, en belangrijke beslissingen altijd valideren met je team.

De conclusie: Minder content, méér waarde

Contentmarketing draait niet om zo veel mogelijk publiceren. Het gaat om wat je toevoegt aan het leven van je klant.

Met deze aanpak kun je concreet zien wat weg kan, wat beter moet, en waar je niets aan hoeft te doen. Je houdt content over die ertoe doet, en je maakt je site beter voor je klant. En ja, daar worden zoekmachines óók blij van.

Stop met content produceren “voor de SEO”. Begin met content produceren omdat iemand er daadwerkelijk wat aan heeft.

 

Persoonlijke noot: Ik deel dit als inspiratie en leermoment. Ik ben geen LLM-expert of developer, maar een praktijkprofessional die graag experimenteert. Er zijn ongetwijfeld betere manieren om dit aan te pakken – laat me weten als jij die kent!

Lees eens meer blogs