Vanhan blogini herättäminen henkiin Archive.orgilla ja paljon C#:tä (Suomi (Finnish))

Vanhan blogini herättäminen henkiin Archive.orgilla ja paljon C#:tä

Monday, 24 November 2025

//

8 minute read

Olet ehkä huomannut satoja "uusia" blogikirjoituksia Viime aikoina ilmestynyt. No, ne eivät ole lainkaan uusia - ne ovat vanhoja. Kuin 2004 vanhoja. Rakensin vihdoin työkalun, jolla voin pelastaa sisältöni digitaaliselta hautausmaalta, joka oli vanha blogini suurimmaksi osaksi lucid.co.ukissa.

Miksi Archive.org on aivan loistava?

Ennen kuin sukeltan teknisiin juttuihin, minun täytyy antaa valtava huutelu Internet-arkisto Tämä voittoa tavoittelematon järjestö on arkistoinut verkkoa hiljaa vuodesta 1996 lähtien, säilyttäen miljardit nettisivut, jotka muuten katoaisivat lopullisesti.

Jokainen blogikirjoitus, jonka kirjoitit vuonna 2005, jokainen GeoCities-sivu, jokainen MySpace-profiili - on mahdollisuus, että se on yhä saatavilla Archive.org:n kautta. He johtavat käytännössä koko internetin museota, jota rahoitetaan lahjoituksilla ja avustuksilla.

Kun vanha isännöitsijäni katosi (yhdessä varmuuskopioideni kanssa, koska olin sellainen SMART), luulin, että kaikki sisältö oli mennyttä ikuisesti. Kävi ilmi, että Wayback Machine oli kuvannut sivustoani ahkerasti vuosien ajan. Archive.org kirjaimellisesti pelasti 6+ vuotta bloggaamisestani.

Jos et ole koskaan lahjoittanut heille, harkitse sitä. He säilyttävät kollektiivisen digitaalisen historiamme.

Ongelma: blogini oli sotkuinen

Blogin pyörittämisessä 2004-2010 on kyse siitä, että nettiteknologiat muuttuivat paljon tuona aikana. Ja ilmeisesti vaihdoin bloggausasetustani ainakin kolme kertaa:

  1. Varhaiset päivät (2004): jokin kotitekoinen ASP.NET-juttu, jossa on sisältöä käärittynä <div class="post"> a:n sisällä <form> elementti (koska kaikki oli silloin muotoa)
  2. Keskimmäinen jakso: Eri mallirakenne, päivämäärät eri paikoissa
  3. Myöhemmät vuodet: Jälleen yksi uudelleenjärjestely, jossa on hieman erilaisia valitsimia

Muistosta se sitten käytti jotain custom-juttua SubText (Phil Haackin bloggausjuttu), jota seuraa Community Server (a Tähdellinen Asiaa ASP.NET käytetään isännöimään sivustoja, toinen entinen ASP, NET PM Rob Howard) . Kaikki oli erilaisia tapoja päivittää ja eri tapoja näyttää sisältöä.

Tämä tarkoitti, että minkä tahansa uuttotyökalun piti olla riittävän joustava käsittelemään useita HTML-rakenteita. "Yksi koko sopii kaikille" -kaavin ei aikonut leikata sitä.

Syötä ArchiveOrgImporter

Rakensin ArkistoOrgImporter .NET 9.0 -konsolisovellus, joka:

  1. Respects Archive.orgin käyttörajat He ovat voittoa tavoittelemattomia lahjoittajia, joten heidän palvelimiensa moukarointi olisi kamalaa.
  2. Lataukset arkistoituja sivuja konfiguroitavien päivämäärien välillä
  3. Ottaa blogin sisältöä useista HTML-rakenteista
  4. Luo puhtaan merkinnän nykyisessä blogimuodossani
  5. Käyttää Ollamaa hyödyllisten tunnisteiden tuottamiseen Miksi et heittäisi LLM-magiaa siihen?

Miten se toimii

Työkalu seuraa putkiarkkitehtuuria, jossa on kolme päävaihetta:

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

Vaihe 1: Arkiston kysely

Työkalussa käytetään Archive.orgin CDX API Tämä API palauttaa listan kiinnitetyistä URL-osoitteista, joissa on aikaleimat, MIME-tyypit ja HTTP-statuskoodit.

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

Erytropoietiini collapse=urlkey Parametri on näppärä - se palauttaa vain tuoreimman kuvan jokaisesta ainutlaatuisesta URL-osoitteesta, mikä vähentää ratkaisevasti niiden kaksoiskappaleiden määrää, joita sinun on käsiteltävä.

Käytän regex-malleja myös URL-osoitteiden suodattamiseen. Vanhat viestini seurasivat kaavaa /posts/[number].aspx, joten:

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

Näin nappaan vain varsinaiset blogikirjoitukset, en arkistosivuja, kategoriasivuja tai RSS-syötteitä.

Vaihe 2: Hyvänä kansalaisena oleminen, jolla on hintaraja

Archive.org on julkinen palvelu. Heillä ei ole Googlen tai Amazonin infrastruktuuribudjettia. Lataaja on siis tarkoituksellisesti konservatiivinen:

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

Kyllä, tämä tarkoittaa, että satojen viestien lataaminen vie aikaa. Mutta se on oikein. Työkalu käsittelee myös 429 (korkoraja) vastausta sulavasti eksponentiaalisella takaiskulla.

Arkisto.org lisää työkalupalkkiskriptejä ja kirjoittaa URL-osoitteita kaapattuun HTML:ään. Ladattava lataa kaikki tiedot:

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;
}

Regex-kuvioiden kahva:

  • <!-- BEGIN WAYBACK TOOLBAR INSERT -->...<!-- END WAYBACK TOOLBAR INSERT --> - työkalupalkki HTML
  • <script> tagien viitteet playback.archive.org
  • Arkiston metatietoja koskevat kommentit
  • URL-etuliitteet kuten https://web.archive.org/web/20040527/ joka saa valmistautumaan kaikkiin lenkkeihin

Vaihe 3: Sisällönpoisto Painajainen

Tässä kohtaa asiat muuttuvat mielenkiintoisiksi. Muistatko, kun mainitsin blogini muuttaneen rakennetta kolme kertaa? Näin hoidin asian.

Ensisijainen uutto käyttää CSS-valitsinta:

{
  "ContentSelector": "div.post"
}

Mutta tässä on hauska oikku - joissakin versioissa minun vanha sivusto, div.post oli INSIDE a <form> elementti. Koodin täytyy poimia sisältöä ennen kuin poistat ei-toivottuja elementtejä, muuten poistat <form> tunnisteet räjäyttäisivät varsinaisen blogin sisällön:

// 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);

Erytropoietiini ExtractMainContent Menetelmä käyttää hierarkkista hakua sisällön löytämiseksi:

// 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));

Työkalussa on myös varavalitsimia, jos ensisijainen epäonnistuu:

  1. div.blogpost, div.singlepost, article
  2. #content, #main-content, #PostBody
  3. .post-content, .entry-content, .article-content
  4. Viimeinkin vain <body> jos kaikki muu epäonnistuu

Sitten on pitkä lista elementtejä, jotka poistavat sisällönoton JÄLKEEN:

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

Vaihe 4: Markdown Generation

Kun meillä on puhdasta HTML-sisältöä, KäänteinenMarkdown Hoitaa raskaan noston, kun se muutetaan GitHub-makuiseksi Markdowniksi.

Mutta ulostuloon tarvittiin jälkikäsittelyä. Vanhassa HTML:ssä oli usein outo sisennys, joka sekoitti Markdownin parserit (sisältävät rivit muuttuvat koodilohkoiksi!).

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

Lopullinen tulos sisältää blogini etusivun ainemuodon:

# Article Title




Article content here...

Vaihe 5: LLM-Powered Tag Generation

Nyt hauska osa. Vanhoilla blogikirjoituksilla ei useinkaan ollut tunnisteita tai tunnisteita, joissa ei ollut järkeä nykyisen sivustoni rakenteelle. Integroin Ollaman analysoimaan sisältöä ja luomaan merkityksellisiä tunnisteita.

Konfiguraatio on yksinkertainen:

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

Käytän gemma3:4b Koska se on tarpeeksi nopea ja pieni pyöriäkseen paikallisesti ilman suurta hämminkiä. Matala lämpötila (0.3) pitää tuotoksen tasaisena – emme halua luovia hallusinaatioita tunnisteisiimme. Huomaa, että blogissani tämä toimi, koska viestit olivat lyhyitä, jos omasi on pidempään varmistunut katsomasta pilkkomis- ja yhteenvetotekniikoita, jotka sopivat mallisi konteksti-ikkunaan.

Pitempien viestien käsittely

Tässä käytännön rajoitus: LLM:issä on konteksti-ikkunat, ja kokonaisen blogikirjoituksen pumppaaminen niihin tunnisteiden tuottamista varten on tuhlausta. Työkalu lyhentää sisällön 3000 merkkiin:

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

Merkkisukupolvea varten ensimmäiset 3000 merkkiä sisältävät yleensä tarpeeksi kontekstia ymmärtääkseen, mistä viestissä on kyse. Nopea ohjeistus ohjeistaa mallin keskittymään teknis-kohtaisiin kategorioihin:

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

Vastausluku on puolustusvoittoinen – jos Ollama palauttaa roskat tai ajat pois, saamme vain tyhjän listan sen sijaan, että kaadamme koko putken.

Päiväysuutto: Moniportainen lähestymistapa

Alkuperäisen julkaisupäivän löytäminen on yllättävän hankalaa. Vanha blogini tallensi päivämääriä eri paikkoihin vuosien varrella. Työkalussa kokeillaan useita strategioita:

  1. Asetettu valitsin (esim. .postfoot)
  2. Metatunnisteet: article:published_time, DC.date.issued
  3. HTML5 <time> elementit
  4. Yhteiset päiväysluokat: .date, .post-date, .entry-date
  5. Regex-kuviot raa'assa HTML:ssä (ISO-muodossa, roiskeena jne.)
  6. Varautus: Arkistokuvapäivä itsessään

Erityisen ärsyttävä formaatti oli vanhan blogimallini "postattu torstaina 27. toukokuuta 2004 kello 23.21".

Putkijohdon orkesteri

Siistein arkkitehtuuribitti on se, miten lataus ja muuntaminen suoritetaan rinnakkain .NET-kanavien avulla:

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

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

Tämä tarkoittaa, että muuntaminen alkaa heti ensimmäisen tiedoston latauksen jälkeen sen sijaan, että odotettaisiin kaikkien latausten valmistumista. Rajoitettu kapasiteetti (10 kappaletta) antaa vastapaineen - jos muuntaminen jää jälkeen, lataus hidastuu vastaamaan.

Rajoitukset ja gotchat

Ollaan rehellisiä siitä, mihin tämä työkalu ei pysty:

  1. Se on hyvin tarkka minun blogiini – Valittajat, kuviot ja päivämäärän poisto on viritetty suurimmaksi osaksi lucid.co.uk:ta varten. Kaikki on räätälöitävä eri sivustolle.

  2. Archive.orgilla ei ole kaikkea – Joitakin sivuja ei arkistoitu tai arkistoitu rikkinäisillä CSS-kuvilla.

  3. Kuvat ovat parasta tehoa - Työkalu yrittää ladata kuvia Wayback Machinesta, mutta monet ovat yksinkertaisesti poissa iäksi.

  4. Kuolleet lenkit kaikkialle - Ulkoiset linkit vuodelta 2004 sivustoille, joita ei enää ole. Työstän tähän erillistä ratkaisua (automaattinen Archive.org-linkkikorvaus keskiohjelmistossa - blogikirjoitus tulossa pian!).

  5. LLM-tagit ovat epätäydellisiä – Ollaman tuottamat tunnisteet ovat yleensä järkeviä, mutta eivät osu silloin tällöin merkkiin. Manuaalinen tarkastelu on suositeltavaa.

  6. CDX API-tyrehdytys – Sivustoille, joilla on tuhansia sivuja, CDX API voi palauttaa lyhennetyt tulokset. Koodi käsittelee tätä sulavasti, mutta joiltakin sivuilta voi jäädä huomaamatta.

Suoritan sitä

Jos haluat mukauttaa tämän omalle sivustollesi (se tarvitsee räätälöinnin), komennot ovat:

# 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

Työkalu tukee sulavaa sammutusta (Ctrl+C) ja voi jatkaa siitä, mihin se jäi, koska tiedostot on välimuistissa paikallisesti.

Tulokset

Esitettyäni tämän vanhassa blogissani, sain takaisin viestejä, jotka ovat peräisin 1. tammikuuta 2004 Ja ennen! Lukeminen on kiehtova matka ajassa. Web-kehityskeskustelut ennen jQueryn olemassaoloa. Viestit teknologioista, jotka ovat nyt täysin vanhentuneita. Ja joitain kiusallisia mielipiteitä, joita pidin nuorempana kehittäjänä.

Löydät kaikki maahantuodut viestit osoitteesta Tuotu kategorian tunnus.

Mitä seuraavaksi?

Tuodulla sisällöllä on paljon kuolleita linkkejä – se on vain 20-vuotiaan verkkosisällön luonne. I rakensi keskiohjelmistoratkaisun että:

  1. Tunnista 404s vanhoille URL-osoitteille
  2. Löydä automaattisesti lähin Archive.org-kuva
  3. Ohjaa tai näytä arkistoitu versio uudelleen

Käärin

Tämän työkalun rakentaminen oli viikonloppuprojekti, joka muuttui aidosti hyödylliseksi. Jos olet menettänyt sisältöä vanhasta blogista, on hyvä mahdollisuus, että Archive.org:lla on se. Ja jos olet tyytyväinen C#:hen, täällä olevat tekniikat (CDX API:n kysely, HTML-sisältöjen poisto, Markdown-sukupolvi, LLM-tagging) voidaan mukauttaa omaan elvytysprojektiin.

Koodi on osoitteessa github.com/scottgal/mostlylucid.nuget-pakkauksetSe ei ole kiillotettu kirjasto – se on tarkoituksenmukainen työkalu erityistilanteelleni – mutta se voi antaa ideoita omiin arkistoseikkailuihin.

Ja oikeasti, mene lahjoittamaan Archive.orgille. He tekevät tärkeää työtä.

Finding related posts...
logo

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