This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Att återuppliva min gamla blogg med Archive
Monday, 24 November 2025
Så ni kanske har märkt hundratals " ny" bloggar framträdande nyligen. Ja, , de ' är inte så nya överhuvudtaget | - | De ' | de är gamla |. | Likt , | 2004 | gamla . | Jag byggde till slut ett verktyg för att rädda mina innehåll från den digitala kyrkogården som var min gamla blogg på mestlucid
Varför Archive.org är absolut lysande
Innan jag dyker in i de tekniska grejerna Internetarchiv och deras Wayback Machine. Denna icke-profit organisation har i tystnad arkiverat webben sedan dess, och bevarat miljarder webbsidor som annars skulle förloras för alltid.
Tänk på det en sekund.
När min gamla hosting-provider försvann ( tillsammans med mina backups eftersom jag var smart som den där ), Jag trodde att allt det innehållet hade försvunnit för alltid . Det visade sig att Wayback Machinen hade jobbat hårt med att ta kort på min sida i åratal
Om du aldrig har donerat till dem, tänk på att göra det. De bevarar vår kollektiva digitala historia.
Problemet: Min blogg var ett meddelande
Här är "'", vad som händer med att köra en blogg från 2004 till ♫ 2010 . ♫ ♫ Webtekniken ändrade LOT under den tiden. ♫
- I tidiga dagar (2004): Något hembröst ASP.NET sak med innehåll ompackat
<div class="post">inuti en<form>element ( eftersom allt var en form på den tiden - Medeltiden: Olika templatestrukturer , datum på olika ställen
- senare år: En ny omstrukturering med lite annorlunda sorter
Från minnet användes det någon speciell sak då Subteks (Phil Haack's blogging-grej Trånglande sak som ASP.NET brukade använda för att hosta webbplatser
Detta innebar att varje extraktionsverktyg behövde vara tillräckligt flexibelt för att hantera flera HTML-strukturer.
Ge in ArchiveOrgImporter
Jag byggde ArchivOrgImporter för att lösa det här specifika problemet.
- Omfamnar Archivs gränser för användande De är en icke-profit organisation som arbetar med donationer, så det vore fruktansvärt att hugga deras server
- ladda ned arkiverade sidor mellan konfigurerade datum
- Extraherar blogginnehåll från flera HTML-strukturer
- Genererar ren markering i mitt nuvarande bloggformat
- använder Ollama för att generera användbara tag - för varför inte kasta lite LLM magi på det
Hur det fungerar
verktyget följer en pipeline-Architektur med tre huvudfaser:
Archive.org CDX API → Download HTML → Convert to Markdown → Generate Tags → Output Files
Fas 1: Fråga Archivet
verktyget använder Archive.org's CDX API för att hitta alla arkiverade ögonblicksbilder på min blogg. Den här APIn ger tillbaka en lista av fångade URL-adresser med tidstämpningar
// The CDX query builds a URL like this:
// https://web.archive.org/cdx/search/cdx?url=mostlylucid.co.uk/posts/&output=json&collapse=urlkey
Den collapse=urlkey parameter är smart - den ger bara den senaste kieken för varje unik URL , vilket dramatiskt minskar antalet kopior du behöver hantera
Jag använder också regex-mönster för att filtrera URLs. Mina gamla Beiträge följde mönstret /posts/[number].aspx, såM SK1
{
"IncludePatterns": ["/posts/\\d+\\.aspx$"]
}
På det här sättet tar jag bara riktiga bloggposter, inte arkivsidorna, kategorisidorna eller RSS-flöden.
Fasen 2: Att vara en god medborgare med begränsade kostnader
Archiv.org är en offentlig tjänst. De har inte den infrastrukturella budgeten som Google eller Amazon har.
// Default: 5 seconds between requests, single-threaded downloads
"RateLimitMs": 5000,
"MaxConcurrentDownloads": 1
Ja, det betyder att att ladda ner hundratals meddelanden tar ett tag . Men det är också rätt sak att göra . verktyget hanterar också 429 | ( hastighetsgränsen, ) responser graciöst med exponentiell bakåtgång, M SK7
Det finns också någon städning som behövs för laddade plier.. Archiv, .org lägger till verktygsfältets skript och skriver om URL: t i formatet.
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-mönster handleder:
<!-- BEGIN WAYBACK TOOLBAR INSERT -->...<!-- END WAYBACK TOOLBAR INSERT -->- verktygsfältet HTML<script>tagbeteckningarplayback.archive.org- Argief metadata kommentarer
- URL- prefixer som
https://web.archive.org/web/20040527/som blir beroende av alla länkar
Fasen 3: Inhaltsextraktionens mardröm
Det är här som saker blir intressanta. Kom ihåg att jag nämnde att min blogg ändrade struktur tre gånger
Den primära extraktionen använder en CSS-selektor:
{
"ContentSelector": "div.post"
}
Men här är ett roligt skämt - i några versioner av min gamla sida div.post var INSIDE en <form> element. Koden måste extrahera innehåll innan den tar bort oönskade elementen <form> tag skulle nukera den faktiska blogg innehållet
// 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);
Den ExtractMainContent metod använder en hierarkisk sökning för att hitta innehållet:
// 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));
verktyget har också fallbackslektorer om den primära misslyckas:
div.blogpost,div.singlepost,article#content,#main-content,#PostBody.post-content,.entry-content,.article-content- Till slut
<body>om allt annat misslyckas
Sedan finns det "'", en lång lista med element som kan utplånas efter innehållsextraktionen.
{
"RemoveSelectors": [
"nav", "header", "footer", ".sidebar", ".advertisement",
".comments", ".social-share", ".related-posts", "script",
"style", "noscript", "iframe", "#commentform", ".postNav"
]
}
Fas 4: Markdown Generation
När vi har ren HTML innehåll Omvända markerdown hanterar den svåra lyftningen av att konvertera den till GitHub
Men utgången krävde lite efterprocessing.
// Removes leading whitespace from non-code lines
// Preserves code block formatting (respects ``` fences)
// Removes excessive blank lines (max 2 consecutive)
Den slutgiltiga utgången består av min blogg
# Article Title
Article content here...
Fas 5: LLM-Attag generation
Nu till den roliga delen. Gamla bloggare hade ofta inga tag överhuvudtaget , eller tag som inte var relevanta för min nuvarande webbplatsstruktur . Så jag integrerade Ollama för att analysera innehållet och generera relevanta tag
Konfigurationen är enkel:
{
"Ollama": {
"BaseUrl": "http://localhost:11434",
"Model": "gemma3:4b",
"Temperature": 0.3,
"MaxTags": 5,
"Enabled": true
}
}
Jag använder gemma3:4b eftersom det' är snabbt och litet nog att köra lokalt utan störning . Den låga temperaturen | (0.3) | håller utgången konstant |– | vi vill inte att ' ska ha kreativa hallucinationer i våra tag | МSK5 | Beteckningen | ; | för min blogg fungerade detta eftersom jag hade korta Beiträgen ♫ , | om din är längre så titta på nedskiljande och sammanfattningstekniker som passar in i din modell ♫
Att hantera längre poster
Här' är en praktisk begränsning : LLMs har kontextfenster , och att pumpa in en hel bloggpost i dem för att skapa tag är slösaktigt. verktyget skär ner innehållet till M SK4 tecken M SK5
var truncatedContent = content.Length > 3000
? content[..3000] + "..."
: content;
När det gäller taggenerering, så innehåller de första tecknen usually tillräckligt med kontext för att förstå vad meddelandet handlar om.
Generate up to 5 tags, short (1-3 words), focusing on:
.NET, C#, ASP.NET, JavaScript, Docker, Database, API, Security, DevOps, Cloud
Reaktionsanalys är försvarsmässigt. – om Ollama återgår med skräp eller utkallar dem, får vi bara en tom taglist istället för att förstöra hela pipelinen.
Datums extraktion
Att hitta den ursprungliga publiceringsdagen är förvånansvärt krångligt. Min gamla blogg bevarade datum på olika ställen under åren . verktyget prövar flera strategier
- Konfigurerad selector (eM SK1g.,
.postfoot) - Meta-tag:
article:published_time,DC.date.issued - HTML5
<time>element - De vanliga datumklassen:
.date,.post-date,.entry-date - Regex-mönster på rå HTML (ISO format, strimplatt -separeratM SK3 osv.
- Fallback: Argief snapshot datumet själv
Ett särskilt irriterande format var min gamla blogg-template 's "posted on Thursday, May 27, M2004 ♫ 11:21 PMM SK6 string ♫ . ♫ Där är ' ♫ det specifika parsinget för det ♫
Pipelineorkestern
Den häftigaste arkitektoniska biten är hur ladda ned och konvertera går parallellt med hjälp av .NET-kanaler
var channel = Channel.CreateBounded<string>(10);
// Producer: downloads and writes file paths to channel
// Consumer: reads file paths and converts to markdown
Detta betyder att omvandlingen börjar så fort den första pliken laddas ner, snarare än att vänta på att alla laddade upp ska göras klart. Den begränsade kapaciteten M SK2 elementen ) ger baktrycket - om om omvandlingen faller efterMska5 laddandet saktar ned till att matchaM Ska6
Begränsningar och Gotchas
Låt oss vara ärliga om vad detta verktyg kan göra.
Det är väldigt specifikt för min blogg – Selektorerna , mönster , och datumextraktionen är alla tunnade för mestlucidM SK3co.ukMST5 DuMSP6 måste anpassa allting till en annan plats
Archive.org har inte allt – En del sidorna var inte archiverade
Bilder är bäst-effort - verktyget försöker ladda ner bilder från Wayback Machinen, men många är helt enkelt för alltid borta.
Döda länkar överallt - Externa länkar från ♫ 2004 ♫ leder till platser som inte längre finns ♫. ♫ Jag ♫ МSK3 ♫ arbetar med en separat lösning för det här ♫
LLM-tag är ofullständiga – Ollamas genererade tag är vanligtvis begripliga, men ibland misslyckas med märken.
CDX API-avkortning – För webbplatser med tusentals sidor , kan CDX-API återskapa truncated resultat
Att köra den
Om du vill anpassa detta till din egen sida (itM SK1 kommer att behöva personaliseringen ), så är kommandorna
# 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
verktyget supporterar eleganta avstängningar (Ctrl+CM SK2 och kan återgå från där det lämnade av eftersom plier är kasserade lokalt
Resultaten
Efter att ha gjort detta på min gamla blogg, fick jag återhämta poster från Januari 1st, 2004 och före! Att läsa igenom dem är en fascinerande resa genom tid .' Web utvecklingsdiskussioner från innan jQuery existerade . Beiträge om tekniker som nu är helt föråldrade. Och några pinsamma åsikter jag hade som ung utvecklare
Du kan hitta alla ingevoerde meddelanden med hjälp av Importerade kategorisetikett.
Vad' är nästa
Den ingevoerde innehållet har en LITT av döda länkar. – att ' är bara naturen i 20-år skapade en middleware lösning att:
- Detektor 404s för gamla URL-adresser
- Automatiskt hitta närmaste Archiv.org-snapshot
- Redirectera eller visa den arkiverade versionen
Att skriva upp
Att bygga det här verktyget var ett helgprojekt som blev något riktigt användbart.
Koden är github.comM SK1scottgal/mostlylucid .nugetpackages. Det är inte en poliserad bibliotek, det är en mening, - det är ett verktyg skapat för min specifik situation, men det kan ge dig idéer om dina egna arkivupplevelser.
Och seriöst, gå och donera till Archiven. De gör ett viktigt jobb.