Så du kanske har märkt hundratals av "nya" blogginlägg visas nyligen. Tja, de är inte nya alls - de är OLD. Som, 2004 gammal. Jag byggde äntligen ett verktyg för att rädda mitt innehåll från den digitala kyrkogården som var min gamla blogg på mestadels lucid.co.uk.
Innan jag dyker in i de tekniska grejerna, måste jag ge en massiv ropa ut till Internetarkiv och deras Wayback Machine. Denna ideella organisation har i tysthet arkiverat webben sedan 1996, bevara miljarder webbsidor som annars skulle gå förlorade för alltid.
Tänk på det för en sekund. Varje blogginlägg du skrev 2005, varje GeoCities sida, varje MySpace profil - det finns en anständig chans att det fortfarande är tillgänglig via Archive.org. De driver i huvudsak ett museum över hela internet, finansieras av donationer och bidrag.
När min gamla hosting leverantör försvann (tillsammans med mina säkerhetskopior eftersom jag var SMART som det), trodde jag att allt detta innehåll var borta för alltid. Visar sig Wayback Machine hade flitigt ögonblicksbilda min webbplats i år. Archive.org ganska bokstavligen sparat 6+ år av min blogg historia.
Om du aldrig har donerat till dem, överväga att göra det. De bevarar vår kollektiva digitala historia.
Så här är det med att köra en blogg från 2004 till 2010 - webbteknik förändrade en LOT under den tiden. Och tydligen, Jag ändrade min blogging setup minst tre gånger:
<div class="post"> på insidan av en <form> element (eftersom allt var en form då)Från minnet använde den något anpassat då Undertext (Phil Haacks bloggande grej). Följt av Community Server (a) Telligentt Ordförande sak ASP.NET brukade använda för att vara värd webbplatser, av ANother ex ASP,NET PM Rob Howard) . Alla hade olika sätt att uppdatera och olika sätt att visa innehåll.
Detta innebar att alla extraktionsverktyg behövde vara flexibla nog att hantera flera HTML-strukturer. En "en storlek passar alla" skrapmaskin skulle inte skära det.
Jag byggde ArkivOrgImporterare för att lösa detta mycket specifika problem. Det är en .NET 9.0 konsol program som:
Verktyget följer en rörledningsarkitektur med tre huvudfaser:
Archive.org CDX API → Download HTML → Convert to Markdown → Generate Tags → Output Files
Verktyget använder Archive.org's CDX- API för att hitta alla arkiverade ögonblicksbilder av min blogg. API:et returnerar en lista med fångade webbadresser med tidsstämplar, MIME- typer och HTTP- statuskoder.
// The CDX query builds a URL like this:
// https://web.archive.org/cdx/search/cdx?url=mostlylucid.co.uk/posts/&output=json&collapse=urlkey
och collapse=urlkey parameter är smart - det returnerar bara den senaste ögonblicksbilden för varje unik URL, vilket dramatiskt minskar antalet dubbletter du behöver ta itu med.
Jag använder också regex mönster för att filtrera webbadresser. Mina gamla inlägg följde mönstret /posts/[number].aspx, så:
{
"IncludePatterns": ["/posts/\\d+\\.aspx$"]
}
På så sätt tar jag bara riktiga blogginlägg, inte arkivsidor, kategorisidor eller RSS-flöden.
Archive.org är en offentlig tjänst. De har inte infrastruktur budgeten för Google eller Amazon. Så downloader är medvetet konservativ:
// Default: 5 seconds between requests, single-threaded downloads
"RateLimitMs": 5000,
"MaxConcurrentDownloads": 1
Ja, detta innebär att ladda ner hundratals inlägg tar ett tag. Men det är det rätta att göra. Verktyget hanterar också 429 (frekvensgräns) svar graciöst med exponentiell backoff.
Det finns också en del städning som behövs för nerladdade filer. Archive.org lägger till verktygsradsskript och skriver om webbadresser i den fångade HTML. Downloader tar bort allt:
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önstren hanterar:
<!-- BEGIN WAYBACK TOOLBAR INSERT -->...<!-- END WAYBACK TOOLBAR INSERT --> - verktygsradens HTML<script> taggar hänvisning playback.archive.orghttps://web.archive.org/web/20040527/ som blir förberedd på alla länkarDet är här det blir intressant. Kommer du ihåg att jag nämnde min blogg ändrade struktur tre gånger? Så här hanterade jag det.
Den primära extraktionen använder en CSS-väljare:
{
"ContentSelector": "div.post"
}
Men här är en rolig sak - i vissa versioner av min gamla webbplats, div.post Ingen känd frekvens: <form> Koden måste extrahera innehåll INNAN oönskade element tas bort, annars tar bort <form> Tags skulle nuke den faktiska bloggen innehåll:
// 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);
och 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å reservväljare om den primära misslyckas:
div.blogpost, div.singlepost, article#content, #main-content, #PostBody.post-content, .entry-content, .article-content<body> om allt annat misslyckasSedan finns det en lång lista med element att ta bort efter innehållsextraktion:
{
"RemoveSelectors": [
"nav", "header", "footer", ".sidebar", ".advertisement",
".comments", ".social-share", ".related-posts", "script",
"style", "noscript", "iframe", "#commentform", ".postNav"
]
}
När vi har rent HTML-innehåll, Omvänd markering hanterar den tunga lyft av konvertera den till GitHub-flavored Markdown.
Men utmatningen behövde en del efterbehandling. Gamla HTML hade ofta konstig indentering som skulle förvirra Markdown-tolkar (indenterade rader blir kodblock!). Så det finns upprensning:
// Removes leading whitespace from non-code lines
// Preserves code block formatting (respects ``` fences)
// Removes excessive blank lines (max 2 consecutive)
Den slutliga utmatningen inkluderar min bloggs front mater format:
# Article Title
Article content here...
Nu för den roliga delen. Gamla blogginlägg hade ofta inga taggar alls, eller taggar som inte gjorde vettigt för min nuvarande webbplats struktur. Så jag integrerade Ollama för att analysera innehåll och generera relevanta taggar.
Konfigurationen är enkel:
{
"Ollama": {
"BaseUrl": "http://localhost:11434",
"Model": "gemma3:4b",
"Temperature": 0.3,
"MaxTags": 5,
"Enabled": true
}
}
Jag använder gemma3:4b Eftersom den är snabb och liten nog att köra lokalt utan mycket väsen. Låg temperatur (0.3) håller resultatet konsekvent – vi vill inte ha kreativa hallucinationer i våra taggar. Observera; för min blogg fungerade detta som inläggen var korta, om din är längre se till att titta på bitning och summering tekniker för att passa i din modells sammanhangsfönster.
Här är en praktisk begränsning: LLMs har sammanhangsfönster, och att pumpa in ett helt blogginlägg i dem för tagggenerering är slöseri. Verktyget trunkerar innehåll till 3000 tecken:
var truncatedContent = content.Length > 3000
? content[..3000] + "..."
: content;
För tagggenerering, de första 3000 tecken innehåller vanligtvis tillräckligt med sammanhang för att förstå vad inlägget handlar om. Prompten instruerar modellen att fokusera på tech-specifika kategorier:
Generate up to 5 tags, short (1-3 words), focusing on:
.NET, C#, ASP.NET, JavaScript, Docker, Database, API, Security, DevOps, Cloud
Svarstolkningen är defensiv – om Ollama returnerar skräp eller tider ut, får vi bara en tom lista istället för att krascha hela rörledningen.
Att hitta det ursprungliga publiceringsdatumet är förvånansvärt knepigt. Min gamla blogg lagrade datum på olika platser under åren. Verktyget försöker flera strategier:
.postfoot)article:published_time, DC.date.issued<time> grundämnen.date, .post-date, .entry-dateEn särskilt irriterande format var min gamla blogg mall är "posted on torsdag 27 maj 2004 11:21" sträng. Det finns specifik tolkning för det.
Den coolaste arkitektoniska biten är hur nedladdning och konvertering körs parallellt med .NET Kanaler:
var channel = Channel.CreateBounded<string>(10);
// Producer: downloads and writes file paths to channel
// Consumer: reads file paths and converts to markdown
Det betyder att konverteringen börjar så fort den första filhämtningen, snarare än att vänta på att alla nedladdningar ska slutföras. Den begränsade kapaciteten (10 objekt) ger mottryck - om konverteringen hamnar efter, saktar nedladdningen ner för att matcha.
Låt oss vara ärliga om vad detta verktyg inte kan göra:
Det är mycket specifikt för MIN blogg – Selectors, mönster, och datum extraktion är alla trimmade för mestadelslucid.co.uk. Du skulle behöva anpassa allt för en annan webbplats.
Archive.org har inte allt – Vissa sidor arkiverades inte, eller arkiverades med trasiga CSS/bilder.
Bilder är bäst-ansträngning - Verktyget försöker ladda ner bilder från Wayback Machine, men många är helt enkelt borta för alltid.
Döda länkar överallt - Externa länkar från 2004 pekar på webbplatser som inte längre finns. Jag arbetar på en separat lösning för detta (automatisk Archive.org länk substitution i en middleware - blogginlägg kommer snart!).
LLM-taggar är ofullständiga – De Ollama-genererade taggarna är oftast förnuftiga, men ibland missa märket. Manuell granskning rekommenderas.
CDX API- trunkering – För webbplatser med tusentals sidor, CDX API kan returnera trunkerade resultat. Koden hanterar detta graciöst men du kan missa vissa sidor.
Om du vill anpassa detta för din egen webbplats (det kommer att behöva anpassning), kommandona är:
# 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 stöder graciös avstängning (Ctrl+C) och kan återupptas från där det slutade eftersom filer är cachad lokalt.
Efter att ha kört detta på min gamla blogg, hittade jag inlägg som går tillbaka till 1 januari 2004 Och innan! Läsa igenom dem är en fascinerande resa genom tiden. Webbutveckling diskussioner från innan jQuery existerade. Inlägg om teknik som nu är helt föråldrade. Och några pinsamma åsikter jag höll som en yngre utvecklare.
Du kan hitta alla importerade inlägg med hjälp av Importerad Kategorimärke.
Det importerade innehållet har en LOT av döda länkar – det är bara arten av 20-åriga webbinnehåll. I byggt en mellanutrustningslösning där
Att bygga detta verktyg var ett helgprojekt som förvandlades till något verkligt användbart. Om du har förlorat innehåll från en gammal blogg, det finns en anständig chans Archive.org har det. Och om du är bekväm med C#, teknikerna här (CDX API fråga, HTML innehåll utvinning, Markdown generation, LLM taggning) kan anpassas för din egen återhämtningsprojekt.
Koden är på github.com/scottgal/mestlylucid.nugetpaket. Det är inte ett polerat bibliotek – det är ett specialbyggt verktyg för min specifika situation – men det kan ge dig idéer för dina egna arkiväventyr.
Och allvarligt talat, gå och donera till Archive.org. De gör ett viktigt arbete.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.