Genereer je sitemap opnieuw op basis van de voltooide openbare paginaset wanneer je publiceert en upload ze daarna samen. Deze Mac-workflow gebruikt een klein Python-script om automatisch toegevoegde pagina’s op te nemen en verwijderde pagina’s weg te laten, met controles van het openbare resultaat.

De taak hier is het onderhouden van een sitemap voor een kleine statische website die vanaf een Mac is geëxporteerd. Het voorbeeld gebruikt synthetische pagina’s over kleuren. Het gaat ervan uit dat je bestaande publicatieproces de exportmap kan uploaden en verouderde bestanden van de openbare website kan verwijderen.

Kies waar het opnieuw genereren van de sitemap thuishoort

Controleer eerst of je publicatiesysteem al een sitemap genereert. Google merkt op dat veel contentmanagementsystemen er automatisch een leveren. Als dat bij jou zo is, controleer dan hoe die sitemap reageert nadat je een testpagina hebt toegevoegd en verwijderd, voordat je een nieuwe generator introduceert. Meer informatie over sitemaps.

Gebruik voor een statische export deze volgorde: rond het exporteren van de pagina’s af, genereer de sitemap op basis van die export en publiceer de resulterende map. Dit is een voorgesteld implementatiepatroon: zo beschrijft de sitemap dezelfde paginaset die de publicatietool ontvangt.

Door de sitemap tijdens het publiceren te genereren, vallen toevoegingen en verwijderingen ook onder één consistente regel. Een pagina die in de voltooide export staat, wordt opgenomen; een pagina die er niet in staat, wordt weggelaten. Er is geen aparte lijst die je moet onthouden bij te werken.

Kies de integratie die bij je bestaande configuratie past:

Bestaande publicatieconfiguratie Waar het opnieuw genereren thuishoort
Een CMS beheert de sitemap al Behoud die generator en test hoe die op paginawijzigingen reageert
Een statische exporter ondersteunt een opdracht na het exporteren Voer de generator daar uit, vóór het uploaden
Een bestaande opdracht publiceert een voltooide map Voer die uit via het optionele publicatieargument van de generator
Je uploadt via een desktopinterface Genereer de sitemap eerst en upload daarna de volledige map; voor automatisch bijwerken van de openbare site is een ondersteunde publicatie-integratie nodig

Een lokaal script kan een externe website niet zelfstandig wijzigen. De onderstaande workflow automatiseert het genereren van de sitemap en kan een bestaande publicatieopdracht starten. Het daadwerkelijke uploaden blijft de verantwoordelijkheid van je bestaande publicatietool.

Bepaal precies welke pagina’s in de sitemap thuishoren

Voor gewone pagina-URL’s accepteert Google een tekstsitemap met één volledige URL per regel. XML is voor deze taak optioneel. Neem voor elke pagina de voorkeurs-URL op die openbaar toegankelijk is, in plaats van meerdere URL-versies van dezelfde inhoud. Een sitemap maken en indienen.

De tekstindeling vereist UTF-8-codering en bevat alleen URL’s, zonder koppen of opmerkingen. Eén bestand mag maximaal 50.000 URL’s en 52.428.800 bytes bevatten. Plaats de sitemap in dit voorbeeld in de hoofdmap van de site, zodat deze de geëxporteerde pagina’s onder die locatie omvat. Sitemaps-protocol: tekstbestanden en locatie.

De generator gebruikt bewust een eenvoudige exportconventie:

Geëxporteerd bestand Voorbeeld van openbare URL
public/index.html https://example.com/
public/colors/blue.html https://example.com/colors/blue.html
public/tiles/index.html https://example.com/tiles/

Gebruik deze conventie alleen als je host precies die URL’s aanbiedt. Als je publicatietool blue.html omzet in /colors/blue/, of de site aanbiedt onder een pad zoals /collection/, gebruik dan de routelijst van die tool of pas de koppeling aan voordat je publiceert. Een scan van bestandsnamen kan aangepaste routering niet afleiden.

Neem alleen pagina’s op die voor de exportmap bedoeld zijn. Dit voorbeeld slaat paden over die met een punt beginnen en bestanden met de naam 404.html; het controleert geen paginametadata, canonical-verwijzingen of omleidingsregels. Genereer voor sites met zulke aanvullende voorwaarden de sitemap op basis van de inventaris van pagina’s die volgens de publicatietool in aanmerking komen.

Blijf ook de gewone navigatielinks onderhouden. De WHATWG definieert hyperlinks die worden gemaakt met a-elementen met een kenmerk href, en Google legt uit dat pagina’s met correcte links doorgaans via navigatie kunnen worden ontdekt. Werk de sitemap bij en pas ook links aan die verwijzen naar toegevoegde of verwijderde pagina’s. WHATWG HTML Standard: links, Meer informatie over sitemaps.

Maak de generator op je Mac

Je hebt Python 3.8 of hoger en een eenvoudige teksteditor nodig. Voer in Terminal python3 --version uit om te controleren welke interpreter beschikbaar is. Als je Python nodig hebt, volg dan de macOS-installatie-instructies van de Python Software Foundation. De documentatie beschrijft ook hoe je scripts vanuit Terminal uitvoert met python3. Python gebruiken op macOS.

Maak op je bureaublad een map met de naam sitemap-demo. Sla het volgende volledige programma daarin op als regenerate_sitemap.py. Het programma gebruikt de standaardbibliotheek van Python en vereist geen extra pakketten.

import argparse
from pathlib import Path, PurePosixPath
import subprocess
import tempfile
from urllib.parse import quote, urlsplit


def make_sitemap(paths, origin):
    parsed = urlsplit(origin)
    if (parsed.scheme not in ("http", "https") or not parsed.hostname
            or parsed.netloc != parsed.hostname
            or parsed.path not in ("", "/")
            or parsed.query or parsed.fragment):
        raise ValueError("Use a site origin, such as https://example.com")
    base = origin.rstrip("/")
    urls = set()
    for relative in paths:
        path = PurePosixPath(relative)
        if path.name == "index.html":
            parent = path.parent.as_posix()
            route = "" if parent == "." else parent + "/"
        else:
            route = path.as_posix()
        urls.add(base + "/" + quote(route, safe="/"))
    if not urls:
        raise ValueError("No eligible pages; sitemap was not replaced")
    if len(urls) > 50000:
        raise ValueError("Split the sitemap: more than 50,000 URLs")
    data = ("\n".join(sorted(urls)) + "\n").encode("utf-8")
    if len(data) > 50 * 1024 * 1024:
        raise ValueError("Split the sitemap: larger than 50 MB")
    return data


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("folder")
    parser.add_argument("origin")
    parser.add_argument("publish", nargs=argparse.REMAINDER)
    args = parser.parse_args()
    root = Path(args.folder).resolve()
    if not root.is_dir():
        parser.error("The export folder must already exist")
    paths = []
    for file in root.rglob("*.html"):
        relative = file.relative_to(root)
        if (file.is_file() and file.name != "404.html"
                and not any(p.startswith(".") for p in relative.parts)):
            paths.append(relative.as_posix())
    data = make_sitemap(paths, args.origin)
    target = root / "sitemap.txt"
    temporary = None
    try:
        with tempfile.NamedTemporaryFile(dir=root, delete=False) as handle:
            temporary = Path(handle.name)
            handle.write(data)
        temporary.replace(target)
    finally:
        if temporary is not None:
            temporary.unlink(missing_ok=True)
    print(f"Wrote {len(data.splitlines())} URLs to {target}", flush=True)
    if args.publish:
        subprocess.run(args.publish, check=True)


if __name__ == "__main__":
    main()

Elke uitvoering bouwt de volledige URL-lijst opnieuw op. Het programma sorteert en ontdubbelt het resultaat, codeert tekens zoals spaties in paden en schrijft een tijdelijk bestand voordat het sitemap.txt vervangt. Generatiefouten stoppen het programma voordat de optionele publicatieopdracht wordt uitgevoerd.

Een lege export veroorzaakt bewust een fout en laat de vorige sitemap ongemoeid. Zo wordt een per ongeluk geselecteerde of onvolledige map opgemerkt. Als je opzettelijk alle pagina’s wilt verwijderen, vereist dat een afzonderlijke publicatiebeslissing; gebruik daarvoor geen lege export in deze workflow.

Test een toevoeging en verwijdering voordat je de publicatie koppelt

Ga in Terminal naar je demonstratiemap:

cd "$HOME/Desktop/sitemap-demo"

Maak met deze volledige configuratieopdracht twee synthetische pagina’s. Gebruik de opdracht in de nieuwe demonstratiemap; deze schrijft de twee genoemde voorbeeldbestanden.

python3 - <<'PY'
from pathlib import Path

root = Path("public")
(root / "colors").mkdir(parents=True, exist_ok=True)
pages = {
    "index.html": "<!doctype html><title>Color collection</title><p>Color collection.</p>",
    "colors/blue.html": "<!doctype html><title>Blue tile</title><p>A blue tile.</p>",
}
for name, content in pages.items():
    (root / name).write_text(content, encoding="utf-8")
PY

Genereer de sitemap en bekijk de lokale versie. De voorbeeldorigin is ter illustratie; deze opdrachten publiceren er niets naartoe.

python3 regenerate_sitemap.py public https://example.com
cat public/sitemap.txt

Het verwachte bestand bevat precies deze twee regels:

https://example.com/
https://example.com/colors/blue.html

Vervang nu de synthetische blauwe pagina door een groene pagina:

python3 - <<'PY'
from pathlib import Path

root = Path("public")
(root / "colors/blue.html").unlink()
(root / "colors/green.html").write_text(
    "<!doctype html><title>Green tile</title><p>A green tile.</p>",
    encoding="utf-8",
)
PY
python3 regenerate_sitemap.py public https://example.com
cat public/sitemap.txt

Het verwachte resultaat is de URL van de startpagina, gevolgd door https://example.com/colors/green.html. De blauwe URL verdwijnt omdat het geëxporteerde bestand ervan weg is. Zo worden beide richtingen van de wijziging gecontroleerd, zonder afhankelijk te zijn van een zoekmachine die de wijziging opmerkt.

Maak het opnieuw genereren onderdeel van elke publicatie

Vervang voor je echte site de demonstratiemap en origin door de daadwerkelijke voltooide exportmap en openbare origin. Voer de generator pas uit nadat het exporteren is voltooid en wijzig die map niet totdat het publiceren is afgerond. Voer publicaties na elkaar uit.

Als je al een werkend publicatiescript met de naam deploy-site.sh in de projectmap hebt, genereert de volgende integratieopdracht de sitemap en voert vervolgens dat script uit. Voor dit voorbeeld is het bestaande script vereist; de generator maakt het niet aan en levert geen hostingconfiguratie.

python3 regenerate_sitemap.py public https://example.com sh ./deploy-site.sh

Je publicatiescript moet dezelfde map public uploaden, inclusief sitemap.txt, en openbare bestanden verwijderen die niet meer in de export staan. Het mag de pagina’s niet opnieuw opbouwen nadat de sitemap is gegenereerd. Genereer de sitemap bij een publicatietool die de site ook bouwt tussen de bouw- en uploadfase.

Als het genereren mislukt, wordt de publicatieopdracht overgeslagen. Als het publiceren mislukt, meldt Python de fout, maar kan de externe site al gedeeltelijk zijn gewijzigd. Controleer het openbare resultaat voordat je het opnieuw probeert. Als je host publicatie van een volledige release in één keer ondersteunt, gebruik dan het gedocumenteerde mechanisme daarvoor.

Genereer bij een desktop-uploader eerst de sitemap en selecteer daarna de exportmap om te uploaden. Controleer of de uploader de bestaande sitemap vervangt en verwijderde pagina’s afhandelt. Je moet nog steeds zelf de upload starten; automatisch lokaal genereren zorgt op zichzelf niet voor automatische publicatie naar de openbare site.

Controleer de openbare sitemap en verwijderde pagina afzonderlijk

Open na een geslaagde publicatie de daadwerkelijke openbare sitemap.txt-URL in een browser. Controleer of de toegevoegde pagina erin staat en de verwijderde pagina er niet in staat. Ga daarna rechtstreeks naar elke betrokken pagina. Zo maak je onderscheid tussen een correcte lokale export en een correcte openbare release.

Het verwijderen van een sitemapvermelding bepaalt niet welke HTTP-respons wordt gegeven op het oude adres van die pagina. Controleer bij een verwijderde pagina zonder vervanging of de host een passende respons voor een ontbrekende pagina geeft. RFC 9110 definieert 404 voor een resource zonder actuele weergave en 410 wanneer bekend is dat de onbeschikbaarheid waarschijnlijk permanent is. RFC 9110: HTTP-semantiek.

Een pagina die een melding over een ontbrekende pagina toont maar 200 retourneert, kan worden behandeld als een soft 404. Google documenteert ook dat eerder geïndexeerde URL’s die toepasselijke 4xx-responsen retourneren na verloop van tijd uit de index worden verwijderd. De URL uit een sitemap verwijderen is dus slechts één onderdeel van het verwijderen van de pagina. Hoe HTTP-statuscodes de crawlers van Google beïnvloeden.

Gebruik deze diagnostische volgorde als iets niet goed lijkt:

Waarneming Volgende controle
De lokale sitemap vermeldt nog steeds een verwijderde pagina Zoek naar een achtergebleven geëxporteerd bestand of de verkeerde exportmap
De lokale sitemap klopt, maar de openbare versie wijkt af Controleer de geüploade map, bestemming en caching
De openbare sitemap klopt, maar de verwijderde pagina is nog bereikbaar Controleer of de publicatie het oude externe bestand heeft verwijderd
Een gegenereerde URL opent de verkeerde pagina Controleer de routetoewijzing van de host aan de hand van de bestandsnaamconventie
Een nieuwe URL is openbaar, maar ontbreekt in zoekresultaten Behandel ontdekking en indexering door zoekmachines als een afzonderlijk proces

Caching kan verklaren waarom de openbare sitemap ongewijzigd lijkt. RFC 9111 definieert hoe gecachete responsen actueel blijven en opnieuw worden gevalideerd. Als je host configuratie van responsheaders ondersteunt, vereist Cache-Control: no-cache een geslaagde validatie voordat een opgeslagen respons opnieuw wordt gebruikt; alleen een lokaal bestand wijzigen configureert die header niet. RFC 9111: HTTP-caching.

Behoud één vast sitemapadres

Zorg dat de openbare sitemap vindbaar is door de vaste URL ervan in te dienen via het rapport Sitemaps van Search Console of ernaar te verwijzen in het bestaande bestand robots.txt van de site. Google beschrijft beide methoden en merkt op dat een inzending slechts een hint is. Een sitemap maken en indienen.

Voor de voorbeeldsite zou de ontdekkingsregel er zo uitzien:

Sitemap: https://example.com/sitemap.txt

Houd het sitemapadres vast en vervang tijdens het publiceren de inhoud ervan. De praktische eindcontrole is dat de openbare sitemap overeenkomt met de voltooide export, de toegevoegde pagina op de vermelde URL opent en de verwijderde pagina de beoogde respons geeft. Zoekmachines verwerken deze wijzigingen volgens hun eigen schema; opname in een sitemap garandeert niet dat er wordt gecrawld of geïndexeerd. Meer informatie over sitemaps.

Bronnen