Back to "تزيزيز مدوّنتي القديمة مع Archary.org و a الكثير من C#"

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

.NET Archive.org Imported

تزيزيز مدوّنتي القديمة مع Archary.org و a الكثير من C#

Monday, 24 November 2025

اذاً قد تكون لاحظت مئات "الجديدة" المدونات في الآونة الأخيرة. حسناً، إنها ليست جديدة على الإطلاق، إنها كبيرة في العمر تقريباً، عمرها 2004، لقد بنيت أخيراً أداة لإنقاذ محتوياتي من المقبرة الرقمية التي كانت مدونتي القديمة في معظم الأحيان في Llucid.co.uk.

لماذا الأرشيف. org هو تماماً رائع

قبل أن أغوص في المواد التقنية يجب أن أعطي صرخة قوية المحفوظ في شبكة الإنترنت هذه المنظمة غير الربحية كانت تحفظ الشبكة بشكل هادئ منذ عام 1996، وتحافظ على بلايين صفحات الويب التي لولاها لفقدت إلى الأبد.

فكروا في ذلك للحظة. كل تدوينة كتبتها في عام 2005، كل صفحة من صفحات جيوCities، كل ملف من ملفات ماي سبيس - هناك فرصة جيدة أنها لا تزال متاحة من خلال أرشيف. org. هم أساسا يديرون متحف كامل للإنترنت، بتمويل من التبرعات والمنح.

عندما اختفى مقدم الاستضافة القديم (إلى جانب نسخي الاحتياطية لأنني كنت سمارت مثل ذلك)، فكرت أن كل هذا المحتوى قد اختفى إلى الأبد. اتضح أن آلة "وايباك" كانت تختبر موقعي منذ سنوات. أرشيف. org أنقذت حرفياً 6+ سنوات من تاريخ مدونتي.

إن لم تتبرع لهم قط، فكّر في فعل ذلك، إنهم يحافظون على تاريخنا الرقمي الجماعي.

المشكلة : كتابتي كانت مُسَخًا

هذا هو الشيء عن تشغيل مدونة من عام 2004 إلى عام 2010 -- تكنولوجيات الويب غيرت الكثير خلال ذلك الوقت. وعلى ما يبدو، غيرت إعداد مدونتي ثلاث مرات على الأقل:

  1. أيام الطفولة المبكرة (2004): بعض asp.net شيء مع المحتوى ملفوف في <div class="post"> (أ) داخل <form> (لأن كل شيء كان شكلاً في ذلك الوقت)
  2. الفترة الوسطىمختلف قالب الهيكل والتواريخ في أماكن مختلفة:
  3. السنوات الاخيرةإعادة هيكلة أخرى مع اختيارات مختلفة اختلافا طفيفا:

من الذاكرة استخدمت شيئاً مخصصاً ما ثم المُنْفج (مدوّنة فيل هاك) يتبعه خادم المجتمع المحلي (a) م SP.net تستخدم في المواقع المضيفة، من قبل Anther Express ASP, NET PM Rub Howard) وكلها لها طرق مختلفة للتحديث وطرق مختلفة لعرض المحتوى.

هذا يعني أن أي أداة استخراج تحتاج إلى أن تكون مرنة بما فيه الكفاية للتعامل مع هياكل HTML متعددة. لم يكن من المقرر أن يقطعها كشط "حجم واحد يناسب الجميع".

إدخال المحفوظ

بُنيّت أُُُُُُُُرِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِِ إلى حل هذه المشكلة المحددة جداً. هو a.net 9.0 شاشة تطبيق:

  1. حدود استخدامات الـ org - هم غير ربحي يَرْكضونَ على التبرعاتِ، لذا ضَرْرْر خوادمِهم سَيَكُونُ a شيء فظيع ليَعمَلُ
  2. المجلدات بين التواريخ
  3. مقتطفات من اقتباسات المدونات المحتوى من هياكل HTML متعددة
  4. إعدادات غير مُثبث في شكل مدونتي الحالي
  5. المستخدم إلى توليد مُمز مفيد -لأنه لمَ لا ترمي بعض السحر عليه؟

كيف تعمل

وتتبع هذه الأداة هيكل خط أنابيب يتألف من ثلاث مراحل رئيسية:

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

المرحلة 1: استعلام عن الأرشيف

استخدام الأداة للمحفوظات. 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.org
  • التعليقات على
  • دعمات مثل https://web.archive.org/web/20040527/ تحصل على مُعادِل إلى كلّ روابط

المرحلة 3: كابوس الاستخراج من المحتوى

هنا تصبح الأمور مثيرة للاهتمام. هل تذكرين أنني ذكرت أن مدونتي تغيرت هيكلها ثلاث مرات؟ إليكم كيف تعاملت معها.

ويستخدم الاستخراج الأولي مُنَقِّذاً من الخدمة الأمنية الشاملة:

{
  "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));

الـ أداة لـ الأوّل الأوّل:

  1. div.blogpost, div.singlepost, article
  2. #content, #main-content, #PostBody
  3. .post-content, .entry-content, .article-content
  4. <body> إذا فشل كل شيء آخر

ثم هناك قائمة طويلة من العناصر لإزالة ما بعد استخراج المحتوى:

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

المرحلة 4: التدرج

بمجرد أن يكون لدينا محتوى (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...

المرحلة 5:

الآن بالنسبة للجزء الممتع. مقالات المدونات القديمة غالباً ما لا تحمل أي علامات على الإطلاق، أو علامات غير منطقية لبنية موقعي الحالي. لذا قمت بدمج أوليما لتحليل المحتوى وتوليد العلامات ذات الصلة.

الـ تشكيل هو:

{
  "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

والإعراب عن الاستجابة هو دفاعي ــ إذا أعاد أولاما القمامة أو أوقات الخروج، فإننا مجرد الحصول على قائمة بطاقات فارغة بدلاً من تحطيم كامل خط الأنابيب.

تاريخ الاستخراج: نهج متعدد الاستراتيجيات

العثور على تاريخ النشر الأصلي صعب جداً. لقد خزنت مدونتي القديمة تواريخ في أماكن مختلفة على مر السنين. تحاول الأداة استراتيجيات متعددة:

  1. منفذ (مثلاً، مثلاً، .postfoot)
  2. ****: article:published_time, DC.date.issued
  3. HTML 5 <time> أولاً - مقدمة
  4. دروس في التواريخ المشتركة: .date, .post-date, .entry-date
  5. دال - الأنماط HTML الخام (تنسيق ISSO، مجز- مفصل، وما إلى ذلك)
  6. الشا خلفيةالارشيف تاريخ اللمحة نفسها

أحد الأشكال المزعجة بشكل خاص كان قالب مدونتي القديم "ملصق يوم الخميس، 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 بنود) توفر ضغطاً خلفياً - إذا تأخر التحويل، فإن التنزيلات تبطئ لمطابقتها.

المُحَدِّي والمُسْتَقَدِيْنِ وَالِتَيْقِيْسِ وَلِسَتَيْ المُسِيَّاتِ والمُسْتَقِلَّاتِ

دعونا نكون صادقين حول ما لا تستطيع هذه الأداة القيام به:

  1. إنها خاصة جداً بمدونتي - الاختيارات، والأنماط، واستخراج التاريخ كلها محاذاة لـ limalucid.co.uk. كنت بحاجة إلى تخصيص كل شيء لموقع مختلف.

  2. المحفوظات. ليس لدى (جورج) كل شيء - بعض الصفحات لم تكن محفوظة، أو كانت محفوظة مع كسر CSS/صورة.

  3. الصور هي الأفضل -الأداة تحاول تنزيل الصور من آلة "طريق العودة"، لكن العديد منها ببساطة قد ذهب إلى الأبد.

  4. الوصلات المرجعية في كل مكان - وصلات خارجية من عام 2004 إلى مواقع لم تعد موجودة. أنا أعمل على حل منفصل لهذا (Autotomatic Archenical archive.org

  5. LLLمات هي ناقص - عادة ما تكون العلامات التي تنتجها أولاما معقولة، ولكنها تفوت العلامة أحيانا، ويوصى باستعراض الدليل.

  6. اقراص 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 عاما. بنيت حلاً وسطياً - أن:

  1. كشف 404s لـ القديم
  2. اعثر تلقائياً على أقرب قدر من الأرشيف. org
  3. إعادة توجيه أو عرض النسخة المحفوظ

أعلى أعلى

بناء هذه الأداة كان مشروع عطلة نهاية أسبوع الذي تحول إلى شيء مفيد حقا. إذا كنت قد فقدت المحتوى من مدونة قديمة، هناك فرصة جيدة للمحفوظات. org لديه ذلك. وإذا كنت مرتاحا مع C#، فإن التقنيات هنا (CDX API الاستعلام، HTML المحتوى الاستخراج، جيل العلامة، LLM الوسم) يمكن تكييفها لمشروع التعافي الخاص بك.

الشفرة موجودة مواد تغليف النبتاتإنها ليست مكتبة مصقولة -- إنها أداة مصممة خصيصاً لوضعي الخاص -- لكنها قد تعطيك أفكاراً لمغامرات أرشيفك الخاصة.

وعلى محمل الجد، اذهب للتبرع إلى أرشيف.org. انهم يقومون بعمل مهم.

logo

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