我的旧博客用档案库@. @org 和大量 C#_#来重现我的老部落格
所以,你可能已经注意到数百个 @"_new"}博客文章 我终于建立了一个工具, 用来从数字墓地中拯救我的内容。 这是我在[email protected] @._uk#.的旧博客
为何归档@. @org绝对辉煌?
在我潜入技术领域之前 我必须先大呼小叫 互联网归档 这个非营利组织自“1996,”以来一直悄悄地将网络归档, 保存数十亿个否则会永远丢失的网页@.}
想想看,你写在“2005,”中的每一篇博客文章。 每个地理城市页面都写了“MS K2”,每个我的空间简介“-”都有一个很好的机会通过档案馆(Calabication)<.>@org_.}他们基本上经营着整个互联网的博物馆,}由捐款和赠款资助的「.」
当我的旧主机提供商因为我像SMART那样 失踪了(和我的备份 因为我以为所有的内容都永远消失了 .
如果你从未向它们捐赠过, 请考虑这样做。 他们保存了我们共同的数字历史。
问题@: @我的博客一团糟
@.}显然我至少换了三次博客设置,
- 早日 @ (2004) @: 一些主机 ASP=.NET的东西,内容包裹在
<div class="post">内有一个<form>元素“(”因为当时一切都是表单 - 中中期不同的模板结构 @,}日期在不同的地方
- 后来年份@: 又一次改组,选择者稍有不同
从记忆中它使用了一些自定义的东西 子图文 @(Phil Haack'}部落格主題@).}依據社群伺服器{(}(a) 线人 ASP=.NET 用于主机站点 @,}由前ASP@,#NET PM Rob Howard)}♪.
这意味着任何提取工具必须足够灵活, 才能处理多个 HTML 结构@ . @ a\ MS K1one 大小符合所有 @ "}\ scrapper wasQ'} t to cut it @ MPK4}
输入归档Org进口器
我建造的 归档导入器 解决这个非常特殊的问题@. @ it'}这是一个“._NET” @9.0{主控台应用程序
- 尊重归档@._org @'}使用限制 他们不是-的盈利者 所以敲他们的服务器是件可怕的事情
- 在可配置日期之间下载存档页面
- 从多个 HTML 结构中提取博客内容
- 生成清洁标记 以我当前博客格式
- 生成有用标签的 Ostellama 为何不把LLM魔力扔到它身上?
如何运作
该工具遵循管道结构,分为三个主要阶段:
Archive.org CDX API → Download HTML → Convert to Markdown → Generate Tags → Output Files
阶段 @ 1:查询归档
此工具使用归档@. @org_'%s CDX API 以查找所有我的博客“.”的存档快照。 此 API 返回了包含时间戳@ , MIME type @ MS K2 和 HTTP 状态代码@ MPK3
// The CDX query builds a URL like this:
// https://web.archive.org/cdx/search/cdx?url=mostlylucid.co.uk/posts/&output=json&collapse=urlkey
缩略 collapse=urlkey 参数是智能的 @-} 它只返回每个唯一的 URL ,} 的最新快照, 这将显著减少您要处理@. 需要的复制件数量 。
我还使用 Regex 模式过滤 URLs @ . 我的旧日志遵循了此模式 /posts/[number].aspx{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}所以
{
"IncludePatterns": ["/posts/\\d+\\.aspx$"]
}
这样我只能抓取真实的博客poss@,}而不是档案页面 @,}分类页面,}或RSS feedQ.}
阶段2: 做一个有利率限制的好公民
org 是一个公共事业单位 他们有Google或Amazon的基建预算 所以下载者故意保守:
// Default: 5 seconds between requests, single-threaded downloads
"RateLimitMs": 5000,
"MaxConcurrentDownloads": 1
这表示下载上百个文章需要一段时间., 但是这代表了做.的正确选择。 工具也处理着“ MSK4” 429 和 “ MS K5” 限制@)”) 用指数反弹优雅地回应了“.”
下载文件需要清理@. @Aglication_.org, 添加工具栏脚本并重写 HTML @.}在所捕捉的HTML#MSK3 下载机条中包含所有%:}
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 模式正在处理@ : @
<!-- BEGIN WAYBACK TOOLBAR INSERT -->...<!-- END WAYBACK TOOLBAR INSERT -->-工具栏 HTML<script>标签查找playback.archive.org- 存档元数据评论
- URL 前缀等
https://web.archive.org/web/20040527/进入所有链接的预览
“内容提取噩梦”阶段
还记得我提到我的博客改变了三次结构吗?
主要采掘使用 CSS 选择器 @: @%
{
"ContentSelector": "div.post"
}
但在我旧网站的一些版本中, div.post 曾经在 <form> 元素 . 代码在移除不想要的元素前必须提取内容@, 否则删除 <form> 将会引爆实际博客内容@: @%
// 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);
缩略 ExtractMainContent 方法使用等级搜索查找内容@: @%
// 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));
如果主机失败, 此工具还有后退选择器@ : @
div.blogpost,div.singlepost,article#content,#main-content,#PostBody.post-content,.entry-content,.article-content- 最后,,
<body>如果所有其他都失败
然后' 长长的元素列表 从内容提取后剥离出来:
{
"RemoveSelectors": [
"nav", "header", "footer", ".sidebar", ".advertisement",
".comments", ".social-share", ".related-posts", "script",
"style", "noscript", "iframe", "#commentform", ".postNav"
]
}
阶段 *4: 标记生成
一旦我们有干净的 HTML 内容 @ , @ 反向上下负向 处理将它转换为 GitHub-flavered MarkdownMS K1的重型升降机
但输出需要一些后端的“-”处理@.}旧 HTML通常有奇怪的缩进, 这会混淆Markdown 解析器 @(}缩进的线条成为代码块{!).} 所以这里是‘'’s cleanup_:}
// Removes leading whitespace from non-code lines
// Preserves code block formatting (respects ``` fences)
// Removes excessive blank lines (max 2 consecutive)
最后的输出包括我的博客' @s front matter格式@:
# Article Title
Article content here...
阶段 5:LLM-授权标签生成
现在,对于有趣的部分“.” 旧博客文章通常没有标签@,或标记,
配置是直截了当的@: @%
{
"Ollama": {
"BaseUrl": "http://localhost:11434",
"Model": "gemma3:4b",
"Temperature": 0.3,
"MaxTags": 5,
"Enabled": true
}
}
我用的是 gemma3:4b 低温 @(0.3) 保持输出一致性@–}我们不想要在标签中出现创造性的幻觉,
更长期员额
这里的' 是一个实际的限制@:LMs有上下文窗口 @,,
var truncatedContent = content.Length > 3000
? content[..3000] + "..."
: content;
对于标签元件组来说,第一个“,”字符通常包含足够多的上下文来理解该文章的内容@.。 即时指示模型聚焦于ech{-}特定类别 @:}
Generate up to 5 tags, short (1-3 words), focusing on:
.NET, C#, ASP.NET, JavaScript, Docker, Database, API, Security, DevOps, Cloud
如果 Ollama 返回垃圾或乘数出@,, 我们只需要一个空标签列表,
采掘日期=:}一个多-}战略方法
寻找原始出版日期是令人惊讶的狡猾@. @我的旧博客在过去几年里在不同地方存储了日期_.}这个工具尝试多种策略:
- 已配置的选择器 (E.G.,
.postfoot) - 元元标签:
article:published_time,DC.date.issued - HTML5
<time>元素要素 - 共同日期班级:
.date,.post-date,.entry-date - Regex 模式 在原始的 HTML 上 @ ( @ ISO 格式@ MS K1 @ slash} @ MPK2 @ sparated_ , @ etc _ .)}
- 后退档案快照日期本身
一个特别令人烦恼的格式是我旧的博客模板“' @%s "}张贴在星期四@,May @27,} @#2004 @{11:21P"_字符串}.}上面有<'>的具体解析
管道管弦
最酷的建筑比特是使用“.+NET channels@:”来平行下载和转换如何运行。
var channel = Channel.CreateBounded<string>(10);
// Producer: downloads and writes file paths to channel
// Consumer: reads file paths and converts to markdown
这意味着转换在第一个文件下载@ , @ 而不是等待所有下载完成 .} 连接能力 < MS K2 items\ ) > 如果转换落后于,}下载速度减慢以匹配 提供回压 *\ MPK4}
限制和困难
让我们让' @%s诚实地知道这个工具能用到什么 @ ' @ t doQ:}
与我的博客非常具体。 @– @% 1 选择器@ ,} 模式 @ MS K2} 日期提取都按大多数时间调整 : mostlucid_ .co @ MPK4uk @ I.} 您需要定制不同站点的所有内容@.}
org does'}没有拥有一切 @– @% 某些页面是'_ t存档@,}或被损坏的 CSS=/#images @MS K4}归档
图像为最佳@- @effort @-_% 此工具试图从回溯机下载图像@ ,}但许多已永远消失 #.#
任何地方的死连结 @-_@ 2004} 外部链接指向已不存在的站点@.I'm,
LLM 标签不完善 @–_Ollama-}(OllamaMSK1产生的標籤通常很合情合理) @MS K2}但偶尔会错过 mark@.}手册审查,
CDX API 截断 CDX API 可能会返回截断的结果@. @% 此代码优雅地处理, 但您可能错过一些 pages @.}
运行中
如果您想要调整此选项以适应您自己的站点 @ (it'}需要自定义@ MS K2, 命令是 @ I:}
# 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
此工具支持优雅的关闭@ ( @ Ctrl+}C)}并可以从剩余部分恢复, 因为文件已缓存本地@ MPK3}
结果
在我的旧博客“MSMK0”上播放这篇文章后, 1月 1st, NSK2 @._Posts 有关现已完全过时的技术的文章@.}和一些我以年轻开发者的身份所持有的尴尬看法*#.
您可使用 : 已进口 分类标签@. @%
下一步是什么?
进口内容含有大量死链接@–, 构建中间软件解决方案 {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}这
- 为旧的 URL 检测404 @%s
- 自动找到最接近的归档@ . @ org 快照
- 重定向或显示存档版本
正在上打包
建立这个工具是一个周末项目, 它变成了真正有用的@. @ @ 如果您在旧博客“,Q”中丢失了内容的话\ '}(那里)'}档案库{.org有一个不错的机会
代码在 GithubMS K0com/Scottgal}/}大多是平庸的 .Nnuget packages@.@ it' @% 不是一个光滑的图书馆 @ – @ it'} 为我的具体情况而设计的“ MS K4” 工具@- @ but it might give you ideas for your own crigical adventions @. @
认真的去捐给档案馆 他们正在做重要工作