Mijn oude blog herrijzen met Archive.org en veel C# (Nederlands (Dutch))

Mijn oude blog herrijzen met Archive.org en veel C#

Monday, 24 November 2025

//

10 minute read

Dus je hebt misschien honderden "nieuwe" blogberichten verschijnen onlangs. Nou, ze zijn helemaal niet nieuw - ze zijn oud. Net als, 2004 oud. Ik eindelijk bouwde een tool om mijn inhoud te redden van de digitale begraafplaats dat was mijn oude blog op veelallucid.co.uk.

Waarom Archive.org absoluut briljant is

Voordat ik in de technische spullen duik, moet ik een enorme schreeuw geven aan de Internet Archief en hun Wayback Machine. Deze non-profit organisatie is stil bezig met het archiveren van het web sinds 1996, het behoud van miljarden webpagina's die anders voor altijd verloren zouden gaan.

Denk daar eens over na. Elke blogpost die je schreef in 2005, elke GeoCities pagina, elk MySpace profiel - er is een fatsoenlijke kans dat het nog steeds toegankelijk is via Archive.org. Ze runnen in wezen een museum van het hele internet, gefinancierd door donaties en subsidies.

Toen mijn oude hosting provider verdween (samen met mijn back-ups omdat ik SMART was), dacht ik dat al die inhoud was verdwenen voor altijd. Blijkt dat de Wayback Machine was ijverig snapshotting mijn site voor jaren. Archive.org vrij letterlijk gered 6+ jaar van mijn blogging geschiedenis.

Als je nooit aan hen hebt gedoneerd, overweeg dan om dat te doen. Ze bewaren onze collectieve digitale geschiedenis.

Het probleem: Mijn blog was een puinhoop

Hier is het ding over het runnen van een blog van 2004 tot 2010 - web technologieën veranderd LOT in die tijd. En blijkbaar, Ik veranderde mijn blogging setup ten minste drie keer:

  1. Vroege dagen (2004): Sommige homebrew ASP.NET ding met inhoud verpakt in <div class="post"> binnen een <form> element (omdat alles toen een vorm was)
  2. Middelste periode: Verschillende template structuur, data op verschillende plaatsen
  3. Latere jaren: Nog een herstructurering met iets verschillende keuzemogelijkheden

Vanuit het geheugen gebruikte het een aangepaste ding toen Subtekst (Phil Haack's blogging ding) gevolgd door Community Server (a Telligent ding ASP.NET gebruikt om sites te hosten, door ANOTHER ex ASP,NET PM Rob Howard) . Allen hadden verschillende manieren van updaten en verschillende manieren om inhoud weer te geven.

Dit betekende dat elk extractiegereedschap flexibel genoeg moest zijn om meerdere HTML-structuren te hanteren. Een "one size fits all" schraper was niet van plan om het te knippen.

Voer het archiefOrgImporter in

Ik bouwde ArchiefOrgImporter om dit zeer specifieke probleem op te lossen. Het is een .NET 9.0 console applicatie die:

  1. Respecteert de gebruikslimieten van Archive.org - Ze zijn non-profit op donaties, dus het hameren van hun servers zou vreselijk zijn om te doen.
  2. Downloads gearchiveerde pagina's tussen configureerbare data
  3. Extracten blog inhoud uit meerdere HTML structuren
  4. Genereert clean Markdown in mijn huidige blog formaat
  5. Gebruikt Ollama om nuttige tags te genereren Waarom gooi je er geen LLM magie naar?

Hoe het werkt

De tool volgt een pijplijn architectuur met drie hoofdfasen:

Archive.org CDX API → Download HTML → Convert to Markdown → Generate Tags → Output Files

Fase 1: Opvragen van het archief

Het gereedschap maakt gebruik van Archive.org's CDX API om alle gearchiveerde snapshots van mijn blog te vinden. Deze API geeft een lijst met opgenomen URL's met tijdstempels, MIME-typen en HTTP-statuscodes terug.

// The CDX query builds a URL like this:
// https://web.archive.org/cdx/search/cdx?url=mostlylucid.co.uk/posts/&output=json&collapse=urlkey

De collapse=urlkey parameter is slim - het geeft alleen de nieuwste snapshot voor elke unieke URL, die drastisch vermindert het aantal duplicaten die u nodig hebt om mee om te gaan.

Ik gebruik ook regex patronen om URL's te filteren. Mijn oude berichten volgden het patroon /posts/[number].aspx, dus:

{
  "IncludePatterns": ["/posts/\\d+\\.aspx$"]
}

Op deze manier grijp ik alleen echte blogberichten, niet de archiefpagina's, categoriepagina's of RSS-feeds.

Fase 2: Een goede burger zijn met snelheidsbeperking

Archive.org is een openbare dienst. Ze hebben niet het infrastructuurbudget van Google of Amazon. Dus de downloader is bewust conservatief:

// Default: 5 seconds between requests, single-threaded downloads
"RateLimitMs": 5000,
"MaxConcurrentDownloads": 1

Ja, dit betekent het downloaden van honderden berichten duurt een tijdje. Maar het is het juiste ding om te doen. Het gereedschap behandelt ook 429 (snelheidslimiet) reacties sierlijk met exponentiële backoff.

Er is ook enige opruiming nodig voor gedownloade bestanden. Archive.org voegt werkbalkscripts toe en herschrijft URL's in de opgenomen HTML. De downloader stript dat allemaal uit:

private static string CleanWaybackArtifacts(string html)
{
    // Remove the interactive Wayback toolbar
    html = WaybackToolbarRegex().Replace(html, string.Empty);
    // Remove playback.archive.org script references
    html = WaybackScriptRegex().Replace(html, string.Empty);
    // Strip archival metadata comments
    html = WaybackCommentRegex().Replace(html, string.Empty);
    // Rewrite archived URLs back to original paths
    html = WaybackUrlRewriteRegex().Replace(html, "$1$2");
    return html;
}

De regex patronen handvat:

  • <!-- BEGIN WAYBACK TOOLBAR INSERT -->...<!-- END WAYBACK TOOLBAR INSERT --> - de werkbalk HTML
  • <script> verwijzing naar tags playback.archive.org
  • Archiefmetadata-commentaar
  • URL-voorvoegsels zoals https://web.archive.org/web/20040527/ die zich voorbereiden op alle links

Fase 3: De inhoud extractie nachtmerrie

Dit is waar dingen interessant worden. Weet je nog dat ik mijn blog veranderde structuur drie keer? Hier is hoe ik het behandeld.

De primaire extractie maakt gebruik van een CSS-selector:

{
  "ContentSelector": "div.post"
}

Maar hier is een leuke grill - in sommige versies van mijn oude site, de div.post was INDIVIDE a <form> element. De code moet inhoud extraheren alvorens ongewenste elementen te verwijderen, anders verwijderen <form> tags zou nuke de werkelijke blog inhoud:

// In ConvertFileAsync - the order here is critical
var contentNode = ExtractMainContent(doc);
if (contentNode == null)
{
    _logger.LogWarning("Could not find main content in {File}", htmlFilePath);
    return articles;
}

// NOW we can safely remove unwanted elements from within the extracted content
RemoveUnwantedElementsFromNode(contentNode);

De ExtractMainContent methode gebruikt een hiërarchische zoekopdracht om de inhoud te vinden:

// For selectors like "div.post", split and search by element + class
node = doc.DocumentNode.Descendants()
    .FirstOrDefault(n =>
        n.Name.Equals(elementName, StringComparison.OrdinalIgnoreCase) &&
        HasExactClass(n, className));

De tool heeft ook fallback selectors als de primaire faalt:

  1. div.blogpost, div.singlepost, article
  2. #content, #main-content, #PostBody
  3. .post-content, .entry-content, .article-content
  4. Eindelijk, alleen de <body> als al het andere mislukt

Dan is er een lange lijst van elementen om te verwijderen NA de inhoud extractie:

{
  "RemoveSelectors": [
    "nav", "header", "footer", ".sidebar", ".advertisement",
    ".comments", ".social-share", ".related-posts", "script",
    "style", "noscript", "iframe", "#commentform", ".postNav"
  ]
}

Fase 4: Opwaarderingsgeneratie

Zodra we schone HTML-inhoud hebben, Omgekeerde markering behandelt het zware tillen van het omzetten naar GitHub-smaak Markdown.

Maar de uitvoer had een aantal post-processing nodig. Oude HTML had vaak rare inspringen dat zou verwarren Markdown parsers (geïndenteerde lijnen worden code blokken!). Dus er is opruiming:

// Removes leading whitespace from non-code lines
// Preserves code block formatting (respects ``` fences)
// Removes excessive blank lines (max 2 consecutive)

De uiteindelijke output bevat mijn blog's front material formaat:

# Article Title




Article content here...

Fase 5: LLM-aangedreven taggeneratie

Nu voor het leuke deel. Oude blogberichten hadden vaak helemaal geen tags, of tags die geen zin hadden voor mijn huidige sitestructuur. Dus heb ik Ollama geïntegreerd om inhoud te analyseren en relevante tags te genereren.

De configuratie is eenvoudig:

{
  "Ollama": {
    "BaseUrl": "http://localhost:11434",
    "Model": "gemma3:4b",
    "Temperature": 0.3,
    "MaxTags": 5,
    "Enabled": true
  }
}

Ik gebruik gemma3:4b want het is snel en klein genoeg om lokaal te draaien zonder veel drukte. De lage temperatuur (0.3) houdt de output consistent . . We willen geen creatieve hallucinaties in onze tags. Opmerking; voor mijn blog dit werkte als de berichten waren kort, als de jouwe is langer zeker om te kijken naar chunking en samenvatting technieken fo passen in het context venster van uw model.

Behandeling van langere berichten

Hier is een praktische beperking: LLM's hebben contextvensters, en het pompen van een hele blogpost in hen voor tag generatie is verspilling. De tool truncates inhoud tot 3000 tekens:

var truncatedContent = content.Length > 3000
    ? content[..3000] + "..."
    : content;

Voor het genereren van tags bevatten de eerste 3000 tekens meestal genoeg context om te begrijpen waar het bericht over gaat. De prompt geeft het model de opdracht zich te concentreren op technische specifieke categorieën:

Generate up to 5 tags, short (1-3 words), focusing on:
.NET, C#, ASP.NET, JavaScript, Docker, Database, API, Security, DevOps, Cloud

De response parsing is defensief als Ollama afval of times out retourneert, krijgen we gewoon een lege tag lijst in plaats van crashen van de hele pijplijn.

Datumwinning: een multistrategiebenadering

Het vinden van de oorspronkelijke publicatiedatum is verrassend lastig. Mijn oude blog opgeslagen data op verschillende plaatsen door de jaren heen. De tool probeert meerdere strategieën:

  1. Geconfigureerde selector (b.v., .postfoot)
  2. Meta-tags: article:published_time, DC.date.issued
  3. HTML5 <time> elementen
  4. Gemeenschappelijke datumklassen: .date, .post-date, .entry-date
  5. Regex-patronen op ruwe HTML (ISO-formaat, slash-gescheiden, enz.)
  6. Terugval: Het archief snapshot dateert zelf

Een bijzonder vervelend formaat was mijn oude blog template "gepost op donderdag 27 mei 2004 11:21 PM" string. Er is specifieke parsing voor dat.

De Pipeline Orkestratie

De coolste architectonische bit is hoe downloaden en conversie loopt parallel met behulp van .NET kanalen:

var channel = Channel.CreateBounded<string>(10);

// Producer: downloads and writes file paths to channel
// Consumer: reads file paths and converts to markdown

Dit betekent dat conversie begint zodra de eerste bestandsdownloads worden gedownload, in plaats van te wachten tot alle downloads zijn voltooid. De begrensde capaciteit (10 items) zorgt voor tegendruk - als de conversie achter blijft, vertraagt het downloaden om overeen te komen.

Beperkingen en Gotcha's

Laten we eerlijk zijn over wat deze tool niet kan doen:

  1. Het is zeer specifiek voor MIJN blog De selectoren, patronen, en datum extractie zijn allemaal afgestemd voor de meestelucid.co.uk. U moet alles aanpassen voor een andere site.

  2. Archive.org heeft niet alles Sommige pagina's werden niet gearchiveerd, of werden gearchiveerd met gebroken CSS / afbeeldingen.

  3. Afbeeldingen zijn best-forfort - De tool probeert afbeeldingen te downloaden van de Wayback Machine, maar velen zijn gewoon voor altijd verdwenen.

  4. Overal dode links - Externe links uit 2004 wijzen naar sites die niet meer bestaan. Ik werk aan een aparte oplossing hiervoor (automatic Archive.org link substitutie in een middleware - blog post binnenkort!).

  5. LLM-tags zijn onvolmaakt De door Ollama gegenereerde tags zijn meestal verstandig, maar soms missen de markering. Handmatige beoordeling wordt aanbevolen.

  6. CDX-API-afknotting Voor sites met duizenden pagina's kan de CDX API afgekorte resultaten retourneren. De code handelt dit sierlijk af, maar je zou enkele pagina's kunnen missen.

Starten.

Als je dit wilt aanpassen voor je eigen site (het moet aangepast worden), zijn de commando's:

# Full pipeline (download + convert)
dotnet run -- full

# Just download HTML from Archive.org
dotnet run -- download

# Just convert existing HTML files to Markdown
dotnet run -- convert

De tool ondersteunt sierlijke shutdown (Ctrl+C) en kan hervatten van waar het is gebleven omdat bestanden lokaal worden gecached.

Resultaten

Na het uitvoeren van dit op mijn oude blog, Ik herstelde berichten daterend terug naar 1 januari 2004 en voor! Het lezen door hen is een fascinerende reis door de tijd. Web ontwikkeling discussies van voor jQuery bestond. Berichten over technologieën die nu volledig verouderd zijn. En sommige beschamende meningen die ik hield als een jongere ontwikkelaar.

U kunt alle geïmporteerde berichten te vinden met behulp van de Geïmporteerd categorie label.

Wat is het volgende?

De geïmporteerde inhoud heeft een LOT van dode links dat is gewoon de aard van 20-jaar-oude web-inhoud. I bouwde een middleware oplossing dat:

  1. 404s voor oude URL's detecteren
  2. Automatisch het dichtstbijzijnde Archive.org snapshot vinden
  3. De gearchiveerde versie doorsturen of weergeven

Omwikkelen

Het bouwen van deze tool was een weekend project dat is veranderd in iets echt nuttigs. Als je inhoud hebt verloren van een oude blog, is er een fatsoenlijke kans Archive.org heeft het. En als je comfortabel met C#, de technieken hier (CDX API querying, HTML content extractie, Markdown generatie, LLM tagging) zou kunnen worden aangepast voor uw eigen herstel project.

De code is: github.com/scottgal/meestallucid.nugetpackagesHet is geen gepolijste bibliotheek, het is een speciaal gebouwd hulpmiddel voor mijn specifieke situatie - maar het kan je ideeën geven voor je eigen archiefavonturen.

En serieus, ga doneren aan Archive.org. Ze doen belangrijk werk.

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.