اذاً قد تكون لاحظت مئات "الجديدة" المدونات في الآونة الأخيرة. حسناً، إنها ليست جديدة على الإطلاق، إنها كبيرة في العمر تقريباً، عمرها 2004، لقد بنيت أخيراً أداة لإنقاذ محتوياتي من المقبرة الرقمية التي كانت مدونتي القديمة في معظم الأحيان في Llucid.co.uk.
قبل أن أغوص في المواد التقنية يجب أن أعطي صرخة قوية المحفوظ في شبكة الإنترنت هذه المنظمة غير الربحية كانت تحفظ الشبكة بشكل هادئ منذ عام 1996، وتحافظ على بلايين صفحات الويب التي لولاها لفقدت إلى الأبد.
فكروا في ذلك للحظة. كل تدوينة كتبتها في عام 2005، كل صفحة من صفحات جيوCities، كل ملف من ملفات ماي سبيس - هناك فرصة جيدة أنها لا تزال متاحة من خلال أرشيف. org. هم أساسا يديرون متحف كامل للإنترنت، بتمويل من التبرعات والمنح.
عندما اختفى مقدم الاستضافة القديم (إلى جانب نسخي الاحتياطية لأنني كنت سمارت مثل ذلك)، فكرت أن كل هذا المحتوى قد اختفى إلى الأبد. اتضح أن آلة "وايباك" كانت تختبر موقعي منذ سنوات. أرشيف. org أنقذت حرفياً 6+ سنوات من تاريخ مدونتي.
إن لم تتبرع لهم قط، فكّر في فعل ذلك، إنهم يحافظون على تاريخنا الرقمي الجماعي.
هذا هو الشيء عن تشغيل مدونة من عام 2004 إلى عام 2010 -- تكنولوجيات الويب غيرت الكثير خلال ذلك الوقت. وعلى ما يبدو، غيرت إعداد مدونتي ثلاث مرات على الأقل:
<div class="post"> (أ) داخل <form> (لأن كل شيء كان شكلاً في ذلك الوقت)من الذاكرة استخدمت شيئاً مخصصاً ما ثم المُنْفج (مدوّنة فيل هاك) يتبعه خادم المجتمع المحلي (a) م SP.net تستخدم في المواقع المضيفة، من قبل Anther Express ASP, NET PM Rub Howard) وكلها لها طرق مختلفة للتحديث وطرق مختلفة لعرض المحتوى.
هذا يعني أن أي أداة استخراج تحتاج إلى أن تكون مرنة بما فيه الكفاية للتعامل مع هياكل HTML متعددة. لم يكن من المقرر أن يقطعها كشط "حجم واحد يناسب الجميع".
بُنيّت أُُُُُُُُرِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِ إلى حل هذه المشكلة المحددة جداً. هو a.net 9.0 شاشة تطبيق:
وتتبع هذه الأداة هيكل خط أنابيب يتألف من ثلاث مراحل رئيسية:
Archive.org CDX API → Download HTML → Convert to Markdown → Generate Tags → Output Files
استخدام الأداة للمحفوظات. ACDX هذا API يُعيد قائمة من مع مزامنة مزامنة MIME و HTTP الحالة رمز.
// 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 البارامترات ذكية - إنها ترجع فقط أحدث لقطة لكل عنوان فريد، الذي يقلل بشكل كبير عدد التكرارات التي تحتاج للتعامل معها.
أنا أيضاً أستخدم أيضاً أنماط regex إلى مرشّح URLs. وظائفي القديمة تتبع نمط /posts/[number].aspxإذاً:
{
"IncludePatterns": ["/posts/\\d+\\.aspx$"]
}
بهذه الطريقة أقوم فقط بالاستيلاء على التدوينات الفعلية، وليس صفحات الأرشيف، أو صفحات الفئات، أو التلقيمات RSS.
الأرشيف. org هو خدمة عامة. ليس لديهم ميزانية البنية التحتية لغوغل أو الأمازون. لذا فإن التحميل محافظ عمداً:
// Default: 5 seconds between requests, single-threaded downloads
"RateLimitMs": 5000,
"MaxConcurrentDownloads": 1
نعم، هذا يعني أن تنزيل المئات من الوظائف يستغرق بعض الوقت. لكنه الشيء الصحيح الذي يجب القيام به. الأداة أيضاً تتعامل مع 429 (حد أقصى للمعدل) ردود الفعل بشكل مهذب مع عكسي أسي.
هناك أيضا بعض التنظيف المطلوب لتنزيل الملفات. Archeive. org يضيف نصوص نصية على شريط الأدوات و Translations URLs في HTML المأسور. المُحمّل يُشرّح كل ذلك:
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;
}
الـ مَنْظُومات مَسْؤُولية:
<!-- BEGIN WAYBACK TOOLBAR INSERT -->...<!-- END WAYBACK TOOLBAR INSERT --> الـ أداة شريط الأدوات HTML<script> playback.archive.orghttps://web.archive.org/web/20040527/ تحصل على مُعادِل إلى كلّ روابطهنا تصبح الأمور مثيرة للاهتمام. هل تذكرين أنني ذكرت أن مدونتي تغيرت هيكلها ثلاث مرات؟ إليكم كيف تعاملت معها.
ويستخدم الاستخراج الأولي مُنَقِّذاً من الخدمة الأمنية الشاملة:
{
"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"
]
}
بمجرد أن يكون لدينا محتوى (HTML) نظيفاً، عكس ويتعامل مع الحمل الثقيل لتحويله إلى علامة (جيت هوب) المزخرفة.
لكن الإخراج يحتاج إلى بعض ما بعد المعالجة. HTML القديم في كثير من الأحيان كان لديه تأرجح غريب الذي من شأنه أن يخلط علامات أسفل pasers (الخطوط غير المُضافة تصبح كتل رمزية!). لذلك هناك التنظيف:
// Removes leading whitespace from non-code lines
// Preserves code block formatting (respects ``` fences)
// Removes excessive blank lines (max 2 consecutive)
تشمل المخرجات النهائية الشكل الرئيسي لمدونتي:
# Article Title
Article content here...
الآن بالنسبة للجزء الممتع. مقالات المدونات القديمة غالباً ما لا تحمل أي علامات على الإطلاق، أو علامات غير منطقية لبنية موقعي الحالي. لذا قمت بدمج أوليما لتحليل المحتوى وتوليد العلامات ذات الصلة.
الـ تشكيل هو:
{
"Ollama": {
"BaseUrl": "http://localhost:11434",
"Model": "gemma3:4b",
"Temperature": 0.3,
"MaxTags": 5,
"Enabled": true
}
}
أنا استخدم gemma3:4b وكما هو سريع وصغير بما يكفي لتشغيل محلياً دون الكثير من الضجة. إن انخفاض درجة الحرارة (0.3) يبقي الناتج متسقاً ــ لا نريد هلوسات إبداعية في بطاقاتنا. ملاحظة؛ بالنسبة لمدونتي نجح هذا كما كانت الإعلانات قصيرة، إذا كان لديك أطول من ذلك تأكد من النظر إلى تقنيات التقطيع والتلخيص fo يلائم في نافذة سياق نموذجك.
هذه حدود عملية: LLLs لها نوافذ سياقية، وضخ تدوينة كاملة فيها لـ بطاقة توليد هو مُبَرِّر. الأداة تَقْطعُ المحتوى إلى 3000 حرف:
var truncatedContent = content.Length > 3000
? content[..3000] + "..."
: content;
بالنسبة لتوليد العلامة، فإن أول 3000 محارف عادة ما تحتوي على سياق كاف لفهم ما هو الموضوع. الحث على توجيه النموذج للتركيز على الفئات الخاصة بالتكنولوجيا:
Generate up to 5 tags, short (1-3 words), focusing on:
.NET, C#, ASP.NET, JavaScript, Docker, Database, API, Security, DevOps, Cloud
والإعراب عن الاستجابة هو دفاعي ــ إذا أعاد أولاما القمامة أو أوقات الخروج، فإننا مجرد الحصول على قائمة بطاقات فارغة بدلاً من تحطيم كامل خط الأنابيب.
العثور على تاريخ النشر الأصلي صعب جداً. لقد خزنت مدونتي القديمة تواريخ في أماكن مختلفة على مر السنين. تحاول الأداة استراتيجيات متعددة:
.postfoot)article:published_time, DC.date.issued<time> أولاً - مقدمة.date, .post-date, .entry-dateأحد الأشكال المزعجة بشكل خاص كان قالب مدونتي القديم "ملصق يوم الخميس، 27 مايو، 2004 11: 21 PM" سلسلة. هناك إعراب محدد لذلك.
أروع جزء معماري هو كيف يتم التنزيل والتحويل بشكل متوازي باستخدام قنوات شبكة الإنترنت:
var channel = Channel.CreateBounded<string>(10);
// Producer: downloads and writes file paths to channel
// Consumer: reads file paths and converts to markdown
وهذا يعني أن التحويل يبدأ بمجرد أول تنزيلات للملف، بدلاً من انتظار استكمال جميع التنزيلات. السعة المقيدة (10 بنود) توفر ضغطاً خلفياً - إذا تأخر التحويل، فإن التنزيلات تبطئ لمطابقتها.
دعونا نكون صادقين حول ما لا تستطيع هذه الأداة القيام به:
إنها خاصة جداً بمدونتي - الاختيارات، والأنماط، واستخراج التاريخ كلها محاذاة لـ limalucid.co.uk. كنت بحاجة إلى تخصيص كل شيء لموقع مختلف.
المحفوظات. ليس لدى (جورج) كل شيء - بعض الصفحات لم تكن محفوظة، أو كانت محفوظة مع كسر CSS/صورة.
الصور هي الأفضل -الأداة تحاول تنزيل الصور من آلة "طريق العودة"، لكن العديد منها ببساطة قد ذهب إلى الأبد.
الوصلات المرجعية في كل مكان - وصلات خارجية من عام 2004 إلى مواقع لم تعد موجودة. أنا أعمل على حل منفصل لهذا (Autotomatic Archenical archive.org
LLLمات هي ناقص - عادة ما تكون العلامات التي تنتجها أولاما معقولة، ولكنها تفوت العلامة أحيانا، ويوصى باستعراض الدليل.
اقراص CDX AP - بالنسبة للمواقع التي تحتوي على آلاف الصفحات، قد يعود الـ CDX API إلى نتائج مجزأة، ويتعامل الشفرة مع هذا برشاقة ولكن قد تفوتك بعض الصفحات.
إذا كنت تريد تكييف هذا لموقعك الخاص (وسوف تحتاج إلى التخصيص) فإن الأوامر هي:
# 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) ويمكنها أن تستأنف من حيث توقفت بما أن الملفات مخبأة محلياً.
بعد تشغيل هذا على مدونتي القديمة، تعافيت من مواقع يعود تاريخها إلى الأول من كانون الثاني/يناير 2004 والقراءة من خلالها هي رحلة رائعة عبر الزمن. مناقشات تطوير الويب من قبل وجود JQuery. الوظائف حول التكنولوجيات التي أصبحت الآن بالية تماما. وبعض الآراء المحرجة التي كنت أحملها كمطور أصغر سنا.
يمكنك أن تجد كل الوظائف المستوردة باستخدام رمز العلامـة.
المحتوى المستورد يحتوي على الكثير من الروابط الميتة -- هذا فقط طبيعة محتوى الويب منذ 20 عاما. بنيت حلاً وسطياً - أن:
بناء هذه الأداة كان مشروع عطلة نهاية أسبوع الذي تحول إلى شيء مفيد حقا. إذا كنت قد فقدت المحتوى من مدونة قديمة، هناك فرصة جيدة للمحفوظات. org لديه ذلك. وإذا كنت مرتاحا مع C#، فإن التقنيات هنا (CDX API الاستعلام، HTML المحتوى الاستخراج، جيل العلامة، LLM الوسم) يمكن تكييفها لمشروع التعافي الخاص بك.
الشفرة موجودة مواد تغليف النبتاتإنها ليست مكتبة مصقولة -- إنها أداة مصممة خصيصاً لوضعي الخاص -- لكنها قد تعطيك أفكاراً لمغامرات أرشيفك الخاصة.
وعلى محمل الجد، اذهب للتبرع إلى أرشيف.org. انهم يقومون بعمل مهم.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.