Artikel · 9 oktober 2026

Ontbrekende content vinden met embeddings in 6 stappen

Welke pagina's van je site gaan over hetzelfde onderwerp, en waar ontbreekt iets? Zo groepeer ik pagina's met embeddings en interne links, met een kleine zakelijke site die ik meet als voorbeeld en een script dat je zelf kunt draaien.

Geschreven door Ferry Jansen
Bijgewerkt op 9 oktober 2026
Hoort bij stap 6 van de SEO/GEO-gidsOntbrekende onderwerpen en verdieping vinden ← Terug naar stap 6
Kort antwoord

Ik maak van de tekst van elke pagina een embedding, een reeks getallen die de betekenis van de tekst vastlegt, en groepeer pagina’s die elkaars dichtstbijzijnde buren zijn. Per groep tel ik de links in de tekst, en ik leg de vertoningen uit Search Console ernaast, het aantal keer dat een pagina in de zoekresultaten stond. Daarna kijk ik naar groepen zonder pagina die de andere verbindt, pagina’s die bij elkaar horen maar niet naar elkaar linken, korte pagina’s met relatief veel vertoningen en onderwerpen van mijn lijst zonder eigen groep.

Een crawl is het ophalen van alle pagina’s van je site met een programma als Screaming Frog. Die lijst URL’s zegt nog niet welke pagina’s over hetzelfde onderwerp gaan, en daarmee ook niet welk onderwerp ontbreekt.

Een embedding, ook wel vector, is een reeks getallen die een AI-model van een tekst maakt. Teksten met dezelfde betekenis krijgen embeddings die dicht bij elkaar liggen, ook als ze andere woorden gebruiken. Google beschrijft neural matching als een AI-systeem dat de begrippen in zoekopdrachten en pagina’s begrijpt en aan elkaar koppelt.1

In dit stuk groepeer ik de pagina’s van een kleine zakelijke site die ik meet op hun embeddings. Daarna leg ik de interne links ernaast, de links van de ene pagina van je site naar een andere, en de vertoningen (impressions), het aantal keer dat een pagina in de zoekresultaten stond. Het script dat de groepen en de links telt, staat onderaan en kun je zelf draaien.

Wat je nodig hebt

  • Een crawl. Screaming Frog of een andere crawler, met per pagina het aantal woorden (de kolom Word Count) en de export All Inlinks voor de links.
  • Embeddings van je pagina’s. Die maak je met een embeddingmodel van een AI-aanbieder, via je eigen account en de koppeling (API) van die aanbieder. Elke aanroep kost geld bij die aanbieder, dus kijk het tarief na voordat je begint. Mijn systeem gebruikt text-embedding-004 van Google op de eerste 8.000 tekens van de tekst van een pagina, en dat geeft 768 getallen per pagina.2
  • Python 3 met numpy, voor het script. Numpy installeer je met pip install numpy.
  • Google Search Console, voor de vertoningen per pagina.
  • Tijd. Het script deed de 23 pagina’s van die site in minder dan een seconde. De crawl en het maken van de embeddings komen daar bovenop.

Het script begint bij een CSV met de embeddings. Code om het model aan te roepen staat niet in dit stuk, omdat die per aanbieder verschilt.

Werk je met Screaming Frog, dan kan die sinds versie 22 zelf embeddings laten maken via een AI-aanbieder. Volgens Screaming Frog gaat dat verder dan de vergelijking van tekst die het programma voor dubbele inhoud doet.3 Het programma markeert daarmee ook pagina’s die weinig samenhangen met het onderwerp van de rest van de site.4 De groepen en de links per groep uit dit stuk maak je met het script.

1. Kies de pagina’s met genoeg tekst

Neem alleen HTML-pagina’s met status 200 en eigen tekst. Laat pdf’s, doorverwijzingen (redirects) en pagina’s met bijna alleen een formulier weg. De embedding van een pagina met weinig tekst zegt weinig over een onderwerp.

  1. Open in Screaming Frog het tabblad Internal en filter op HTML.
  2. Houd de pagina’s met statuscode 200 die indexeerbaar zijn, dus pagina’s die Google mag opnemen.
  3. Exporteer de lijst met de kolommen Address en Word Count.

Het script slaat pagina’s met minder dan 500 tekens tekst over. Het gaat dan om de tekst die je naar het model stuurde, die je in stap 2 als kolom tekens meegeeft; Word Count telt woorden en is iets anders. Op de voorbeeldsite hadden 3 van de 26 pagina’s met een embedding minder tekst, waaronder het contactformulier, en bleven er 23 over.2

Controle. Elke pagina op je lijst heeft status 200 en een eigen tekst van meer dan een paar zinnen.

2. Maak van elke pagina een embedding

Stuur de hoofdtekst van elke pagina, zonder menu en voettekst, naar het embeddingmodel en bewaar per pagina de URL en de getallen. Gebruik voor alle pagina’s hetzelfde model, want embeddings van verschillende modellen kun je niet met elkaar vergelijken.

Zet de uitkomst in een CSV met per pagina één regel:

  • url, het adres van de pagina;
  • vector, de getallen van de embedding, gescheiden door spaties of komma’s;
  • woorden, het aantal woorden uit de crawl (mag leeg);
  • tekens, het aantal tekens van de tekst die je naar het model stuurde (mag leeg).

Controle. Elke regel heeft evenveel getallen. Het script stopt als de regels niet even lang zijn. Dat vangt een tweede model alleen op als dat een ander aantal getallen geeft, dus houd zelf bij welk model je gebruikte.

3. Bereken hoe dicht de pagina’s bij elkaar liggen

De cosinusovereenkomst (cosine similarity) is een maat voor hoe dicht twee embeddings bij elkaar liggen, van -1 tot 1. Hoe dichter bij 1, hoe meer de teksten op elkaar lijken. Het script rekent hem uit voor elk paar pagina’s.

Op de voorbeeldsite lag de overeenkomst over de 253 paren tussen 0,67 en 0,97, met 0,84 als gemiddelde.5 Ook het minst gelijke paar lag nog op 0,67. Dat past bij een site waar alle pagina’s over hetzelfde vak gaan.

Een vaste grens, zoals “boven 0,9 hoort bij elkaar”, valt op zo’n site anders uit dan op een site met uiteenlopende onderwerpen. Daarom groepeer ik op de buren van elke pagina en niet op een vast getal.

0,84

gemiddelde cosinusovereenkomst tussen de embeddings van twee pagina's van een kleine zakelijke site, over 253 paren, met 0,67 als laagste en 0,97 als hoogste

Eigen meting RankFellow · 23 pagina's · september tot oktober 2026

Controle. Het script toont het gemiddelde, de laagste en de hoogste overeenkomst. Zo zie je hoe ver de pagina’s van je site uit elkaar liggen, voordat je de groepen leest.

4. Groepeer pagina’s die elkaars dichtstbijzijnde buren zijn

De regel in het script heeft drie delen.

  1. Zoek voor elke pagina de twee pagina’s met de hoogste overeenkomst, de dichtstbijzijnde buren.
  2. Twee pagina’s horen bij elkaar als ze allebei bij de ander in die twee staan.
  3. Een groep is een aaneengesloten keten van zulke paren. Een pagina zonder zo’n paar blijft los.

Met --buren kies je een ander aantal buren. Meer buren geeft grotere groepen.

Op die site gaf de regel 6 groepen van twee of drie pagina’s en 9 losse pagina’s.6 De indeling komt uit de embeddings; in de tabel noem ik per groep alleen het soort pagina’s.

De groepen van de voorbeeldsite

Per groep het aantal pagina’s, het aantal woorden en de laagste overeenkomst tussen twee pagina’s van de groep.

GroepPagina’sWoorden per paginaLaagste overeenkomst
Blogs over een eerste thema3730 tot 8260,93
Dienstpagina’s3421 tot 6640,93
Blogs over een tweede thema21.205 tot 1.3100,91
Blogs over een derde thema21.383 tot 1.4400,93
Blogs over een vierde thema21.141 tot 1.2060,92
Een casepagina en een productpagina2793 tot 1.2390,92

Schuif opzij voor alle kolommen →

Eigen meting RankFellow · 23 pagina's · september tot oktober 2026

Los staan de homepage, de pagina met het aanbod, het blogoverzicht, het overzicht van de cases, het overzicht van de dienstpagina’s, de pagina over de eigenaar, een casepagina, de pagina van een tool en nog één blog.

Controle. Lees per groep de titels. Gaan ze over hetzelfde onderwerp, dan klopt de groep. Valt er een pagina uit de toon, kijk dan of de tekst die je naar het model stuurde echt de hoofdtekst was.

Google gebruikt links als signaal voor de relevantie van pagina’s en om nieuwe pagina’s te vinden.7 Ik tel alleen de links in de tekst, omdat links in het menu en de voettekst op bijna elke pagina staan en dus niets zeggen over welke pagina’s bij elkaar horen.

  1. Exporteer in Screaming Frog Bulk Export, Links, All Inlinks.
  2. Geef het bestand aan het script met --links.

Het script houdt de hyperlinks over met Link Position Content, de plek die Screaming Frog aan links in de hoofdtekst geeft. Daarnaast laat het een link weg als 60% of meer van de pagina’s naar hetzelfde adres linkt, en zo’n link behandel ik als menu of vast blok.8 Dat getal en de 500 tekens uit stap 1 zijn mijn keuzes; je past ze aan met --sjabloon en --min-tekens.

Daarna telt het script per groep de links tussen de pagina’s van die groep. Bij groepen van drie of meer noemt het de centrale pagina, of meldt het dat alle pagina’s naar elkaar linken. Een centrale pagina is een pagina die naar alle andere pagina’s van de groep linkt of door alle andere gelinkt wordt, zoals een overzichtspagina (hub-pagina) dat doet.

Controle. Neem één groep en kijk op de pagina’s zelf of de getelde links in de tekst staan.

6. Leg de vertoningen ernaast en lees af wat ontbreekt

Exporteer in Search Console onder Prestaties, Zoekresultaten het tabblad Pagina’s over de laatste 28 dagen, en tel per groep de vertoningen van de pagina’s op.

GroepLinks in de tekst onderlingVertoningen in 28 dagen
Blogs over een eerste thema2 van 60
Dienstpagina’s6 van 684
Blogs over een tweede thema2 van 222
Blogs over een derde thema2 van 20
Blogs over een vierde thema0 van 26
Een casepagina en een productpagina1 van 223

Eigen meting RankFellow · 23 pagina's · 9 september tot en met 6 oktober 2026

Nul vertoningen zegt alleen dat de pagina’s niet in beeld komen, niet dat er content ontbreekt. Dat lees je af aan vier signalen, die volgen uit mijn werkwijze voor deze stap.

  • Een overzichtspagina. Een groep van drie of meer pagina’s zonder centrale pagina. Op de voorbeeldsite is dat de groep blogs over het eerste thema, met 2 van de 6 mogelijke links en geen vertoningen in 28 dagen. Of je dan een overzichtspagina bouwt of een bestaande pagina verdiept, staat in Pillar-pagina of hub, wanneer bouw je een overzichtspagina?.
  • Links in de tekst. Twee pagina’s die bij elkaar horen maar niet naar elkaar linken, zoals de twee blogs over het vierde thema.
  • Verdieping. Een korte pagina die relatief veel vertoningen krijgt. Het script noemt een pagina kort als hij minder woorden heeft dan de helft van de mediaan, het middelste aantal woorden van de pagina’s in je bestand. Op de voorbeeldsite is dat de pagina over de eigenaar, met 341 woorden en 66 vertoningen in 28 dagen, van de losse pagina’s het meest na de homepage.9 Op welke zoektermen hij verschijnt, heb ik voor dit stuk niet bekeken; zijn het zoekopdrachten op de naam van de eigenaar, dan voegt verdieping weinig toe.
  • Een ontbrekend onderwerp. Een onderwerp van je onderwerpenlijst waar geen groep en geen losse pagina over gaat.

Voor dat laatste leg je je onderwerpenlijst uit stap 5 van de gids naast de groepen. Bij een korte lijst zoek je per onderwerp met de hand de groep die erbij hoort, op de titels. Bij een lange lijst maak je ook van elk onderwerp een embedding, van de naam en de zoektermen, en zoek je de pagina die er het dichtst bij ligt. Mijn systeem doet iets verwants in de module content coverage. Het vergelijkt de embeddings van de eigen pagina’s met groepen tussenkoppen en vragen uit de SERP.

Je kunt een taalmodel per groep de titels en de eerste alinea’s geven en het laten voorstellen over welk onderwerp de groep gaat. De indeling zelf laat ik op de embeddings rusten en niet op het oordeel van zo’n model.

Controle. Elk onderwerp van je lijst heeft een groep, een losse pagina of het label ontbreekt.

Het script

groepeer_paginas.py doet stap 3, 4 en 5 in één keer. Het leest de CSV uit stap 2 en, als je die meegeeft, de export All Inlinks.

python groepeer_paginas.py vectoren.csv --links all_inlinks.csv --uit groepen.csv

De mogelijkheden:

  • --buren, het aantal dichtstbijzijnde buren, standaard 2;
  • --min-tekens, pagina’s met minder tekst overslaan, standaard 500;
  • --kort, je eigen grens voor korte pagina’s in woorden; zonder grens is dat de helft van de mediaan van de pagina’s in je bestand;
  • --links, de export All Inlinks van Screaming Frog;
  • --sjabloon, het aandeel pagina’s vanaf waar een link als menu of vast blok telt, standaard 0,60;
  • --uit, de groepen ook naar een CSV schrijven.

Ik heb het getest op de embeddings en de links van de voorbeeldsite uit september en oktober 2026. Het gaf dezelfde groepen, dezelfde laagste overeenkomst per groep en hetzelfde aantal links als mijn berekening in BigQuery. Een deel van de uitvoer, met algemene adressen in plaats van de echte:

23 pagina's, 15 groepen, waarvan 6 met meer dan één pagina
Overeenkomst over alle paren: gemiddeld 0.84, laagste 0.67, hoogste 0.97
Kort: minder dan 400 woorden (de helft van de mediaan van 800 woorden)

Groep 1: 3 pagina's, laagste overeenkomst binnen de groep 0.93, links in de tekst onderling 2 van 6, centrale pagina: geen
  example.com/blog/blog-1  (826 woorden)
  example.com/blog/blog-2  (797 woorden)
  example.com/blog/blog-3  (730 woorden)
Groep 2: 3 pagina's, laagste overeenkomst binnen de groep 0.93, links in de tekst onderling 6 van 6, alle pagina's linken naar elkaar
  example.com/diensten/dienst-1  (445 woorden)
  example.com/diensten/dienst-2  (421 woorden)
  example.com/diensten/dienst-3  (664 woorden)
Groep 13: 1 pagina
  example.com/over  (341 woorden, kort)

Met de vier signalen uit stap 6 vul je in stap 6 van de gids de kolom Besluit van je onderwerpenlijst.

Veelgestelde vragen

Wat is de betekenis van "semantisch"?
Semantisch betekent dat het over de betekenis gaat. In SEO bedoel je daarmee de betekenis van een tekst of zoekopdracht, en niet alleen de woorden die erin staan. Een embeddingmodel legt die betekenis vast als een reeks getallen. Zo herken je pagina’s die over hetzelfde onderwerp gaan, ook als ze andere woorden gebruiken.
Wat is een semantische relatie?
Een semantische relatie is een verband in betekenis tussen woorden of teksten, zoals tussen prijs en kosten, of tussen een onderwerp en een deelonderwerp. In embeddings liggen teksten met zo’n verband dicht bij elkaar. Daarom kun je met embeddings pagina’s groeperen die over hetzelfde gaan, ook als ze verschillende woorden gebruiken.
Wat zijn clusters?
Een cluster is een groep die meer op elkaar lijkt dan op de rest. In SEO zijn dat meestal zoektermen die op één pagina horen, of pagina’s die over hetzelfde onderwerp gaan. In dit stuk zijn het groepen pagina’s, waarbij twee pagina’s bij elkaar horen als ze elkaars dichtstbijzijnde buren zijn.

Bronnen en eigen metingen

  1. 1Google Search Central (2025). A guide to Google Search ranking systems. Documentatie, engels. Gecontroleerd op 9 oktober 2026.
  2. 2Eigen meting RankFellow · 26 pagina's · september tot oktober 2026. 23 van 26 pagina's van een kleine zakelijke site met een embedding van 768 getallen hadden genoeg tekst (500 tekens of meer).
  3. 3Screaming Frog (2025). Screaming Frog SEO Spider Update (version 22.0). Documentatie, engels. Gecontroleerd op 9 oktober 2026.
  4. 4Screaming Frog (2025). Low Relevance Content. Documentatie, engels. Gecontroleerd op 9 oktober 2026.
  5. 5Eigen meting RankFellow · 23 pagina's · september tot oktober 2026. 0,84 gemiddelde cosinusovereenkomst tussen de embeddings van twee pagina's van een kleine zakelijke site, over 253 paren, met 0,67 als laagste en 0,97 als hoogste.
  6. 6Eigen meting RankFellow · 23 pagina's · september tot oktober 2026. 6 groepen van twee of drie pagina's en 9 losse pagina's, bij een groepering van een kleine zakelijke site op de embeddings van de pagina's.
  7. 8Eigen meting RankFellow · 23 pagina's · crawl van 4 oktober 2026. 2 van 6 mogelijke links in de tekst tussen de drie pagina's van een groep blogs over één thema, zonder centrale pagina.
  8. 9Eigen meting RankFellow · 23 pagina's · 9 september tot en met 6 oktober 2026. 0 vertoningen in 28 dagen voor de drie blogs in een groep over één thema.

Verder in de gids

Zien wat Fellow voor jouw website zou voorstellen?