تحويل HTML إلى Markdown باستخدام Python: دليل شامل
بايثون لتحويل HTML إلى ماركداون نظيف ومُعدّ لمحركات التعلم العميق
تحويل HTML إلى Markdown هو مهمة أساسية في تدفقات العمل الحديثة، خاصة عند إعداد محتوى الويب للنماذج اللغوية الكبيرة (LLMs)، ونظامي الوثائق أو المولّدات الثابتة مثل Hugo.
بينما تم تصميم HTML للاستخدام في متصفحات الويب مع تصميم غني وبنية، فإن Markdown يوفر تنسيقًا نظيفًا وقابلًا للقراءة، وهو مثالي لمعالجة النصوص، والتحكم في الإصدارات، والاستهلاك من قبل الذكاء الاصطناعي. إذا كنت تبدأ في استخدام ترميز Markdown، فراجع دليل Markdown لدينا للحصول على مرجعي شامل.

في هذا المراجعة الشاملة، سنستعرض ستة حزم Python لتحويل HTML إلى Markdown، مع أمثلة عملية على الكود، ونتائج معايير الأداء، وحالات استخدام واقعية. سواء كنت تبني أنبوبًا تدريبيًا لنموذج لغوي كبير، أو تقوم بتحويل مدونة إلى Hugo، أو تقوم بتنقيب الوثائق، فسوف تجد الأداة المثالية لتدفق عملك.
نهج بديل: إذا كنت بحاجة إلى استخراج محتوى ذكي مع فهم دلالي، فقد ترغب أيضًا في النظر في تحويل HTML إلى Markdown باستخدام LLM وOllama، والذي يقدم تحويلًا مدعومًا بالذكاء الاصطناعي للهياكل المعقدة.
ما ستتعلمه:
- مقارنة تفصيلية لـ 6 مكتبات مع مزايا وعيوب لكل منها
- معايير أداء باستخدام عينات HTML واقعية
- أمثلة كود جاهزة لحالات الاستخدام الشائعة
- أفضل الممارسات لتدفقات عمل معالجة LLM
- توصيات محددة بناءً على متطلباتك
لماذا Markdown لمعالجة LLM؟
قبل الغوص في الأدوات، دعنا نفهم لماذا Markdown مفيد بشكل خاص لتدفقات عمل LLM:
- كفاءة الرموز: يستخدم Markdown عددًا أقل بكثير من الرموز مقارنةً بـ HTML لنفس المحتوى
- الوضوح الدلالي: يحتفظ Markdown ببنية المستند دون استخدام علامات مفرطة
- القراءة: يمكن للبشر والـ LLMs تحليل ترميز Markdown بسهولة
- التوافق: يقلل التنسيق المعياري من الغموض في إدخالات النموذج
- التخزين: أحجام ملفات أصغر للبيانات التدريبية ونافذة السياق
تتنوع مرونة Markdown عن تطبيقات تحويل HTML، يمكنك أيضًا تحويل مستندات Word إلى Markdown لتدفقات عمل الوثائق، أو استخدامه في أنظمة إدارة المعرفة مثل Obsidian لإدارة المعرفة الشخصية.
TL;DR - جدول المقارنة السريع
إذا كنت مسرعًا، إليك مقارنة شاملة لجميع المكتبات في نظرة واحدة. سيساعدك هذا الجدول على تحديد الأداة التي تتناسب مع متطلباتك بسرعة:
| الميزة | html2text | markdownify | html-to-markdown | trafilatura | domscribe | html2md |
|---|---|---|---|---|---|---|
| دعم HTML5 | جزئي | جزئي | كامل | كامل | كامل | كامل |
| العلامات النمطية | لا | لا | نعم | جزئي | لا | جزئي |
| التعاملات المخصصة | محدود | ممتاز | جيد | محدود | جيد | محدود |
| دعم الجداول | أساسي | أساسي | متقدم | جيد | جيد | جيد |
| الدعم غير المتزامن | لا | لا | لا | لا | لا | نعم |
| استخراج المحتوى | لا | لا | لا | ممتاز | لا | جيد |
| استخراج البيانات | لا | لا | نعم | ممتاز | لا | نعم |
| أداة سطر الأوامر | لا | لا | نعم | نعم | لا | نعم |
| السرعة | متوسطة | بطيئة | سريعة | 매우 سريعة | متوسطة | 매우 سريعة |
| التطوير النشط | لا | نعم | نعم | نعم | محدود | نعم |
| نسخة Python | 3.6+ | 3.7+ | 3.9+ | 3.6+ | 3.8+ | 3.10+ |
| الاعتماديات | لا شيء | BS4 | lxml | lxml | BS4 | aiohttp |
دليل الاختيار السريع:
- تحتاج إلى السرعة؟ → trafilatura أو html2md
- تحتاج إلى التخصيص؟ → markdownify
- تحتاج إلى الأمان النمطي؟ → html-to-markdown
- تحتاج إلى البساطة؟ → html2text
- تحتاج إلى استخراج المحتوى؟ → trafilatura
المتنافسون: مقارنة 6 حزم Python
لنغوص في كل مكتبة مع أمثلة كود عملية، خيارات التكوين، والرؤى الواقعية. يحتوي كل قسم على تعليمات التثبيت، أنماط الاستخدام، وتقييم صادق للمزايا والقيود.
1. html2text - الخيار الكلاسيكي
تم تطوير html2text في الأصل من قبل أaron Swartz، وهو عنصر أساسي في بيئة Python منذ أكثر من عقد. يركز على إنتاج إخراج Markdown نظيف وقابل للقراءة.
التركيب:
pip install html2text
الاستخدام الأساسي:
import html2text
# إنشاء مثيل المحوّل
h = html2text.HTML2Text()
# تكوين الخيارات
h.ignore_links = False
h.ignore_images = False
h.ignore_emphasis = False
h.body_width = 0 # لا تلف السطور
html_content = """
<h1>مرحباً بكم في تجميع البيانات من الويب</h1>
<p>هذا هو دليل شامل لاستخراج المحتوى.</p>
<ul>
<li>سهل الاستخدام</li>
<li>تم اختباره</li>
<li>مُعتمد على نطاق واسع</li>
</ul>
<a href="https://example.com">اعرف المزيد</a>
"""
markdown = h.handle(html_content)
print(markdown)
الناتج:
# مرحباً بكم في تجميع البيانات من الويب
هذا هو **دليل شامل** لاستخراج المحتوى.
* سهل الاستخدام
* تم اختباره
* مُعتمد على نطاق واسع
[اعرف المزيد](https://example.com)
التكوين المتقدم:
import html2text
h = html2text.HTML2Text()
# تجاهل عناصر معينة
h.ignore_links = True
h.ignore_images = True
# التحكم في التنسيق
h.body_width = 80 # تلف عند 80 حرف
h.unicode_snob = True # استخدام الأحرف الأونيكود
h.emphasis_mark = '*' # استخدام * للإثارة بدل _
h.strong_mark = '**'
# التعامل مع الجداول
h.ignore_tables = False
# حماية النصوص المُعدة مسبقًا
h.protect_links = True
المزايا:
- ناضج ومستقر (15+ سنة من التطوير)
- خيارات تكوين واسعة
- يتعامل جيدًا مع الحالات الحدية
- لا تعتمد على أي اعتماديات خارجية
العيوب:
- دعم HTML5 محدود
- يمكن أن ينتج مسافات غير متسقة
- لا يتم تطويره نشطًا (آخر تحديث رئيسي في عام 2020)
- معالجة متزامنة فقط
الأفضل له: الوثائق HTML البسيطة، الأنظمة القديمة، عندما يكون الاستقرار أولوية
2. markdownify - الخيار المرن
يستخدم markdownify BeautifulSoup4 لتقديم تحليل HTML مرن مع التعاملات المخصصة للعناصر.
التركيب:
pip install markdownify
الاستخدام الأساسي:
from markdownify import markdownify as md
html = """
<article>
<h2>تطوير الويب الحديث</h2>
<p>بناء باستخدام <code>Python</code> و <em>الإطارات الحديثة</em>.</p>
<blockquote>
<p>البساطة هي أقصى درجة من التطور.</p>
</blockquote>
</article>
"""
markdown = md(html)
print(markdown)
الناتج:
## تطوير الويب الحديث
بناء باستخدام `Python` و *الإطارات الحديثة*.
> البساطة هي أقصى درجة من التطور.
الاستخدام المتقدم مع التعاملات المخصصة:
from markdownify import MarkdownConverter
class CustomConverter(MarkdownConverter):
"""
إنشاء محوّل مخصص مع التعاملات الخاصة بالعناصر
"""
def convert_img(self, el, text, convert_as_inline):
"""التعامل المخصص مع الصور مع نص البديل"""
alt = el.get('alt', '')
src = el.get('src', '')
title = el.get('title', '')
if title:
return f''
return f''
def convert_pre(self, el, text, convert_as_inline):
"""التعامل المحسن مع كتل الكود مع اكتشاف اللغة"""
code = el.find('code')
if code:
# استخراج اللغة من سمة الفئة (مثلاً 'language-python')
classes = code.get('class', [''])
language = classes[0].replace('language-', '') if classes else ''
return f'\n```{language}\n{code.get_text()}\n```\n'
return f'\n```\n{text}\n```\n'
# استخدام المحوّل المخصص
html = '<pre><code class="language-python">def hello():\n print("world")</code></pre>'
markdown = CustomConverter().convert(html)
print(markdown)
للمزيد من التفاصيل حول التعامل مع كتل الكود في Markdown والتوظيف، راجع دليلنا حول استخدام كتل الكود في Markdown.
التحويل المحدد للعناصر:
from markdownify import markdownify as md
# إزالة عناصر معينة تمامًا
markdown = md(html, strip=['script', 'style', 'nav'])
# تحويل عناصر معينة فقط
markdown = md(
html,
heading_style="ATX", # استخدام # للعناوين
bullets="-", # استخدام - للنقاط
strong_em_symbol="*", # استخدام * للإثارة
)
المزايا:
- مبني على BeautifulSoup4 (تحليل HTML قوي)
- قابل للتخصيص عبر التراث
- تطوير نشط
- وثائق جيدة
العيوب:
- يتطلب اعتمادية BeautifulSoup4
- يمكن أن يكون أبطأ لمستندات كبيرة
- دعم الجداول المُعبَّأة محدود
الأفضل له: التحويل المخصص، المشاريع التي تستخدم BeautifulSoup4 بالفعل
3. html-to-markdown - القوة الحديثة
html-to-markdown هو مكتبة حديثة تمامًا، مُصنفة تمامًا، مع دعم شامل لـ HTML5 وخيارات تكوين واسعة.
التركيب:
pip install html-to-markdown
الاستخدام الأساسي:
from html_to_markdown import convert
html = """
<article>
<h1>التوثيق التقني</h1>
<table>
<thead>
<tr>
<th>الميزة</th>
<th>الدعم</th>
</tr>
</thead>
<tbody>
<tr>
<td>HTML5</td>
<td>✓</td>
</tr>
<tr>
<td>الجداول</td>
<td>✓</td>
</tr>
</tbody>
</table>
</article>
"""
markdown = convert(html)
print(markdown)
التكوين المتقدم:
from html_to_markdown import convert, Options
# إنشاء خيارات مخصصة
options = Options(
heading_style="ATX",
bullet_style="-",
code_language_default="python",
strip_tags=["script", "style"],
escape_special_chars=True,
table_style="pipe", # استخدام | للجداول
preserve_whitespace=False,
extract_metadata=True, # استخراج علامات التبويب
)
markdown = convert(html, options=options)
واجهة سطر الأوامر:
# تحويل ملف واحد
html-to-markdown input.html -o output.md
# تحويل مع خيارات
html-to-markdown input.html \
--heading-style atx \
--strip-tags script,style \
--extract-metadata
# تحويل دفعة
find ./html_files -name "*.html" -exec html-to-markdown {} -o ./markdown_files/{}.md \;
المزايا:
- دعم كامل لـ HTML5 بما في ذلك العناصر الدلالية
- مصنفة تمامًا مع مؤشرات نوعية شاملة
- معالجة الجداول المحسنة (الخلايا المدمجة، الترتيب)
- قدرات استخراج البيانات
- تطوير نشط وقاعدة كود حديثة
العيوب:
- يتطلب Python 3.9+
- حجم اعتماديات أكبر
- منحنى تعلم أصعب
الأفضل له: الوثائق HTML5 المعقدة، المشاريع المصنفة تمامًا، الأنظمة الإنتاجية
4. trafilatura - خبير استخراج المحتوى
trafilatura ليس مجرد محوّل HTML إلى Markdown، بل هو مكتبة ذكية لاستخراج المحتوى مصممة خصيصًا لاستخراج المقالات والتنقيب عن الويب.
التركيب:
pip install trafilatura
الاستخدام الأساسي:
import trafilatura
# تنزيل واستخراج من عنوان URL
url = "https://example.com/article"
downloaded = trafilatura.fetch_url(url)
markdown = trafilatura.extract(downloaded, output_format='markdown')
print(markdown)
ملاحظة: تحتوي trafilatura على تنزيل مدمج من URL، ولكن عند التعامل مع عمليات HTTP معقدة، قد تجد دليلنا حول cURL مفيدًا عند العمل مع واجهات برمجة التطبيقات أو نقاط النهاية المصادقة.
استخراج المحتوى المتقدم:
import trafilatura
from trafilatura.settings import use_config
# إنشاء تكوين مخصص
config = use_config()
config.set("DEFAULT", "EXTRACTION_TIMEOUT", "30")
html = """
<html>
<head><title>عنوان المقالة</title></head>
<body>
<nav>قائمة التنقل</nav>
<article>
<h1>المقالة الرئيسية</h1>
<p>المحتوى المهم هنا.</p>
</article>
<aside>إعلان</aside>
<footer>محتوى التذييل</footer>
</body>
</html>
"""
# استخراج المحتوى الرئيسي فقط
markdown = trafilatura.extract(
html,
output_format='markdown',
include_comments=False,
include_tables=True,
include_images=True,
include_links=True,
config=config
)
# استخراج مع البيانات
result = trafilatura.extract(
html,
output_format='markdown',
with_metadata=True
)
if result:
print(f"العنوان: {result.get('title', 'غير متوفر')}")
print(f"المؤلف: {result.get('author', 'غير متوفر')}")
print(f"التاريخ: {result.get('date', 'غير متوفر')}")
print(f"\nالمحتوى:\n{result.get('text', '')}")
المعالجة بالدفعة:
import trafilatura
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
def process_url(url):
"""استخراج Markdown من عنوان URL"""
downloaded = trafilatura.fetch_url(url)
if downloaded:
return trafilatura.extract(
downloaded,
output_format='markdown',
include_links=True,
include_images=True
)
return None
# معالجة عدة عناوين في وقت واحد
urls = [
"https://example.com/article1",
"https://example.com/article2",
"https://example.com/article3",
]
with ThreadPoolExecutor(max_workers=5) as executor:
results = list(executor.map(process_url, urls))
for i, markdown in enumerate(results):
if markdown:
Path(f"article_{i}.md").write_text(markdown, encoding='utf-8')
المزايا:
- استخراج محتوى ذكي (إزالة المحتوى غير الضروري)
- تنزيل مدمج مع معالجة أخطاء قوية
- استخراج البيانات (العنوان، المؤلف، التاريخ)
- اكتشاف اللغة
- محسّن لاستخراج المقالات والمنشورات
- معالجة سريعة مبنية على C
العيوب:
- قد يزيل الكثير من المحتوى لـ HTML العام
- مركّز على استخراج المقالات (ليس عامًا)
- تعقيد التكوين للحالات الحدية
الأفضل له: التنقيب عن الويب، استخراج المقالات، إعداد بيانات تدريب LLM
5. domscribe - الحافظ على المعنى الدلالي
يركز domscribe على الحفاظ على المعنى الدلالي لـ HTML أثناء تحويله إلى Markdown.
التركيب:
pip install domscribe
الاستخدام الأساسي:
from domscribe import html_to_markdown
html = """
<article>
<header>
<h1>فهم HTML الدلالي</h1>
<time datetime="2024-10-24">24 أكتوبر 2024</time>
</header>
<section>
<h2>مقدمة</h2>
<p>HTML الدلالي يوفر <mark>معنى</mark> للمحتوى.</p>
</section>
<aside>
<h3>المواضيع المرتبطة</h3>
<ul>
<li>الوصول الشامل</li>
<li>البحث في محركات البحث</li>
</ul>
</aside>
</article>
"""
markdown = html_to_markdown(html)
print(markdown)
خيارات مخصصة:
from domscribe import html_to_markdown, MarkdownOptions
options = MarkdownOptions(
preserve_semantic_structure=True,
include_aria_labels=True,
strip_empty_elements=True
)
markdown = html_to_markdown(html, options=options)
المزايا:
- الحفاظ على بنية HTML5 الدلالية
- التعامل الجيد مع مكونات الويب الحديثة
- تصميم واجهة برمجة نظيف
العيوب:
- لا يزال في مراحل التطوير المبكرة (قد تتغير واجهة برمجة التطبيقات)
- وثائق محدودة مقارنة بالبدائل الناضجة
- مجتمع أصغر وعدد أقل من الأمثلة المتاحة
الأفضل له: الوثائق HTML5 الدلالية، المشاريع المركزة على الوصول الشامل، عندما يكون الحفاظ على بنية HTML5 الدلالية أمرًا حيويًا
ملاحظة: على الرغم من أن domscribe أحدث من البديل، إلا أنه يملأ فجوة معينة لحفظ HTML الدلالي التي لا تركز عليها الأدوات الأخرى.
6. html2md - القوة غير المتزامنة
تم تصميم html2md للتحويلات عالية الأداء بالجملة مع المعالجة غير المتزامنة.
التركيب:
pip install html2md
الاستخدام من سطر الأوامر:
# تحويل دليل كامل
m1f-html2md convert ./website -o ./docs
# مع إعدادات مخصصة
m1f-html2md convert ./website -o ./docs \
--remove-tags nav,footer \
--heading-offset 1 \
--detect-language
# تحويل ملف واحد
m1f-html2md convert index.html -o readme.md
الاستخدام البرمجي:
import asyncio
from html2md import convert_html
async def convert_files():
"""تحويل جماعي غير متزامن"""
html_files = [
'page1.html',
'page2.html',
'page3.html'
]
tasks = [convert_html(file) for file in html_files]
results = await asyncio.gather(*tasks)
return results
# تشغيل التحويل
results = asyncio.run(convert_files())
المزايا:
- معالجة غير متزامنة للاستفادة من الأداء العالي
- اكتشاف محدد للمحتوى
- إنشاء YAML frontmatter (مثالي لـ Hugo!)
- اكتشاف لغة الكود
- دعم المعالجة المتزامنة
العيوب:
- يتطلب Python 3.10+
- مركّز على سطر الأوامر (أقل مرونة في واجهة برمجة التطبيقات)
- يمكن أن تكون الوثائق أكثر شمولًا
الأفضل له: المهاجرات الكبيرة، التحويلات بالجملة، المهاجرات من Hugo/Jekyll
معايير الأداء
الأداء مهم، خاصة عند معالجة آلاف المستندات لتدريب LLM أو المهاجرات الكبيرة. تساعد فهم الفروقات في السرعة بين المكتبات في اتخاذ قرارات مبنية على المعرفة لتدفق عملك.
تحليل الأداء المقارن:
بناءً على الأنماط النموذجية للاستخدام، إليك كيف تقارن هذه المكتبات عبر ثلاث حالات واقعية:
- HTML بسيط: منشور مدونة بسيط مع نصوص، عناوين، وروابط (5KB)
- HTML معقد: وثائق تقنية مع جداول مدمجة وكتل كود (50KB)
- موقع ويب كامل: صفحة ويب كاملة تشمل التنقل، التذييل، الجانبي، والإعلانات (200KB)
إليك مثال على كود المعايير الذي يمكنك استخدامه لاختبار هذه المكتبات بنفسك:
import time
import html2text
from markdownify import markdownify
from html_to_markdown import convert
import trafilatura
def benchmark(html_content, iterations=100):
"""معايرة سرعة التحويل"""
# html2text
start = time.time()
h = html2text.HTML2Text()
for _ in range(iterations):
_ = h.handle(html_content)
html2text_time = time.time() - start
# markdownify
start = time.time()
for _ in range(iterations):
_ = markdownify(html_content)
markdownify_time = time.time() - start
# html-to-markdown
start = time.time()
for _ in range(iterations):
_ = convert(html_content)
html_to_markdown_time = time.time() - start
# trafilatura
start = time.time()
for _ in range(iterations):
_ = trafilatura.extract(html_content, output_format='markdown')
trafilatura_time = time.time() - start
return {
'html2text': html2text_time,
'markdownify': markdownify_time,
'html-to-markdown': html_to_markdown_time,
'trafilatura': trafilatura_time
}
الخصائص الأداء المعتادة (السرعات النسبية الممثلة):
| الحزمة | HTML بسيط (5KB) | HTML معقد (50KB) | موقع ويب كامل (200KB) |
|---|---|---|---|
| html2text | معتدل | أبطأ | أبطأ |
| markdownify | أبطأ | أبطأ | الأبطأ |
| html-to-markdown | سريع | سريع | سريع |
| trafilatura | سريع | سريع جدًا | سريع جدًا |
| html2md (غير متزامن) | سريع جدًا | سريع جدًا | الأسرع |
الملاحظات الرئيسية:
html2mdوtrafilaturaهما الأسرع لمستندات معقدة، مما يجعلهما مثاليين للمعالجة بالجملةhtml-to-markdownيقدم أفضل توازن بين السرعة والميزات للاستخدام الإنتاجيmarkdownifyأبطأ لكنه أكثر مرونة - تبادل مقبول عندما تحتاج إلى التعاملات المخصصةhtml2textيظهر علامته مع الأبطأ، لكنه مستقر للاستخدامات البسيطة
ملاحظة: تصبح الفروقات في الأداء ملحوظة فقط عند معالجة مئات أو آلاف الملفات. لتحويلات نادرة، تعمل أي مكتبة بشكل جيد. ركّز على الميزات وخيارات التخصيص بدلًا من ذلك.
أمثلة استخدام حقيقية
النظرية مفيدة، ولكن الأمثلة العملية توضح كيف تعمل هذه الأدوات في الإنتاج. إليك أربعة حالات شائعة مع كود كامل جاهز للإنتاج يمكنك تكييفه لمشاريعك الخاصة.
حالة الاستخدام 1: إعداد بيانات تدريب نموذج LLM
المتطلبات: استخراج نص نظيف من آلاف صفحات الوثائق
الموصى به: trafilatura + معالجة متوازية
import trafilatura
from pathlib import Path
from concurrent.futures import ProcessPoolExecutor
def process_html_file(html_path):
"""تحويل ملف HTML إلى markdown"""
html = Path(html_path).read_text(encoding='utf-8')
markdown = trafilatura.extract(
html,
output_format='markdown',
include_links=False, # إزالة هذا للحصول على بيانات تدريب نظيفة
include_images=False,
include_comments=False
)
if markdown:
output_path = html_path.replace('.html', '.md')
Path(output_path).write_text(markdown, encoding='utf-8')
return len(markdown)
return 0
# معالجة 10,000 ملف في وقت واحد
html_files = list(Path('./docs').rglob('*.html'))
with ProcessPoolExecutor(max_workers=8) as executor:
token_counts = list(executor.map(process_html_file, html_files))
print(f"تم معالجة {len(html_files)} ملف")
print(f"الحروف الإجمالية: {sum(token_counts):,}")
حالة الاستخدام 2: نقل مدونة Hugo
المتطلبات: نقل مدونة WordPress إلى Hugo مع frontmatter
الموصى به: html2md من الطرفية
Hugo هو مولّد مواقع ثابت شائع يستخدم Markdown للمحتوى. للمزيد من النصائح الخاصة بـ Hugo، تحقق من ورقة مساعدة Hugo وتعلم حول إضافة ترميز بيانات منظمة إلى Hugo لتحسين SEO.
# تحويل جميع المنشورات مع frontmatter
m1f-html2md convert ./wordpress-export \
-o ./hugo/content/posts \
--generate-frontmatter \
--heading-offset 0 \
--remove-tags script,style,nav,footer
أو بشكل برمجي:
from html_to_markdown import convert, Options
from pathlib import Path
import yaml
def migrate_post(html_file):
"""تحويل HTML من WordPress إلى markdown لـ Hugo"""
html = Path(html_file).read_text()
# استخراج العنوان والتاريخ من HTML
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')
title = soup.find('h1').get_text() if soup.find('h1') else 'غير مسمى'
# تحويل إلى markdown
options = Options(strip_tags=['script', 'style', 'nav', 'footer'])
markdown = convert(html, options=options)
# إضافة frontmatter لـ Hugo
frontmatter = {
'title': title,
'date': '2024-10-24',
'draft': False,
'tags': []
}
output = f"---\n{yaml.dump(frontmatter)}---\n\n{markdown}"
# حفظ
output_file = html_file.replace('.html', '.md')
Path(output_file).write_text(output, encoding='utf-8')
# معالجة جميع المنشورات
for html_file in Path('./wordpress-export').glob('*.html'):
migrate_post(html_file)
حالة الاستخدام 3: مُستخرج وثائق مع تخصيص التنسيق
المتطلبات: استخراج وثائق تقنية مع معالجة كتل الكود المخصصة
الموصى به: markdownify مع مُحول مخصص
هذه الطريقة مفيدة بشكل خاص لنقل الوثائق من أنظمة ويكي. إذا كنت تدير الوثائق، فقد تكون مهتمًا أيضًا بـ DokuWiki - ويكي مُستضاف ذاتيًا والبدائل لحلول وثائق مُستضافة ذاتيًا.
from markdownify import MarkdownConverter
import requests
class DocsConverter(MarkdownConverter):
"""مُحول مخصص لوثائق تقنية"""
def convert_pre(self, el, text, convert_as_inline):
"""كُتل كود مُحسّنة مع تلوين لغة الكود"""
code = el.find('code')
if code:
# استخراج لغة من الفئة
classes = code.get('class', [])
language = next(
(c.replace('language-', '') for c in classes if c.startswith('language-')),
'text'
)
return f'\n```{language}\n{code.get_text()}\n```\n'
return super().convert_pre(el, text, convert_as_inline)
def convert_div(self, el, text, convert_as_inline):
"""معالجة كتل وثائق خاصة"""
classes = el.get('class', [])
# كتل تحذير
if 'warning' in classes:
return f'\n> ⚠️ **تحذير**: {text}\n'
# كتل معلومات
if 'info' in classes or 'note' in classes:
return f'\n> 💡 **ملاحظة**: {text}\n'
return text
def scrape_docs(url):
"""استخراج وتحويل صفحة وثائق"""
response = requests.get(url)
markdown = DocsConverter().convert(response.text)
return markdown
# استخدامه
docs_url = "https://docs.example.com/api-reference"
markdown = scrape_docs(docs_url)
Path('api-reference.md').write_text(markdown)
حالة الاستخدام 4: تحويل نشرات إخبارية إلى ملفات markdown
المتطلبات: تحويل نشرات إخبارية HTML إلى markdown قابلة للقراءة
الموصى به: html2text مع تكوين محدد
import html2text
import email
from pathlib import Path
def convert_newsletter(email_file):
"""تحويل نشرة إخبارية HTML إلى markdown"""
# تحليل البريد
with open(email_file, 'r') as f:
msg = email.message_from_file(f)
# الحصول على جزء HTML
html_content = None
for part in msg.walk():
if part.get_content_type() == 'text/html':
html_content = part.get_payload(decode=True).decode('utf-8')
break
if not html_content:
return None
# تكوين المُحول
h = html2text.HTML2Text()
h.ignore_images = False
h.images_to_alt = True
h.body_width = 0
h.protect_links = True
h.unicode_snob = True
# تحويل
markdown = h.handle(html_content)
# إضافة البيانات
subject = msg.get('Subject', 'لا يوجد عنوان')
date = msg.get('Date', '')
output = f"# {subject}\n\n*التاريخ: {date}*\n\n---\n\n{markdown}"
return output
# معالجة أرشيف النشرات
for email_file in Path('./newsletters').glob('*.eml'):
markdown = convert_newsletter(email_file)
if markdown:
output_file = email_file.with_suffix('.md')
output_file.write_text(markdown, encoding='utf-8')
التوصيات حسب السيناريو
هل لا تزال غير متأكد من أي مكتبة يجب اختيارها؟ إليك دليلي النهائي بناءً على حالات الاستخدام المحددة. هذه التوصيات تأتي من خبرة عملية مع كل مكتبة في بيئات الإنتاج.
لتحويل الويب والتحضير المسبق لـ LLM
الفائز: trafilatura
Trafilatura يتفوق في استخراج المحتوى النظيف مع إزالة النصوص الثانوية. مثالي لـ:
- بناء مجموعات بيانات تدريب LLM
- تجميع المحتوى
- جمع أوراق بحثية
- استخراج مقالات الأخبار
لتحويلات Hugo/Jekyll
الفائز: html2md
المعالجة غير المتزامنة وتكوين frontmatter تجعل تحويلات المجموعات سريعة وسهلة:
- تحويلات دفقة
- استخراج تلقائي للمetadata
- إنشاء frontmatter YAML
- تعديل مستويات العناوين
لمنطق التحويل المخصص
الفائز: markdownify
تخصيص المُحول من خلال فرزه للاستحواذ الكامل:
- مُعالجات عناصر مخصصة
- تحويلات مخصصة حسب المجال
- متطلبات التنسيق الخاصة
- دمج مع الكود الحالي لـ BeautifulSoup
لأنظمة الإنتاج ذات النوع الآمن
الفائز: html-to-markdown
حديث، آمن من حيث النوع، وشامل في الميزات:
- دعم كامل لـ HTML5
- إرشادات نوعية شاملة
- معالجة متقدمة للجداول
- صيانة نشطة
لتحويلات بسيطة ومستقرة
الفائز: html2text
عندما تحتاج إلى شيء “يعمل”:
- لا توجد اعتمادات
- اختبارت ميدانية
- تكوين واسع
- دعم منصات واسع
أفضل الممارسات لتحويلات LLM
بلا مبالاة بمكتبة تختارها، اتباع هذه الممارسات الأفضل سيضمن إخراج Markdown عالي الجودة مُحسّن لاستهلاك LLM. هذه الأنماط أثبتت ضرورتها في عمليات معالجة الملايين من الوثائق.
1. تنظيف قبل التحويل
احذف العناصر غير المرغوب فيها قبل التحويل للحصول على إخراج نظيف وتحسين الأداء:
from bs4 import BeautifulSoup
import trafilatura
def clean_and_convert(html):
"""إزالة العناصر غير المرغوب فيها قبل التحويل"""
soup = BeautifulSoup(html, 'html.parser')
# إزالة العناصر غير المرغوب فيها
for element in soup(['script', 'style', 'nav', 'footer', 'header', 'aside']):
element.decompose()
# إزالة الإعلانات والمتابعة
for element in soup.find_all(class_=['ad', 'advertisement', 'tracking']):
element.decompose()
# تحويل HTML النظيف
markdown = trafilatura.extract(
str(soup),
output_format='markdown'
)
return markdown
2. تسوية المسافات البيضاء
تختلف المُحولات في التعامل مع المسافات البيضاء. تسوية الإخراج لضمان الاتساق عبر مجموعتك:
import re
def normalize_markdown(markdown):
"""تنظيف مسافات markdown"""
# إزالة المسافات البيضاء المتعددة
markdown = re.sub(r'\n{3,}', '\n\n', markdown)
# إزالة المسافات البيضاء الزائدة
markdown = '\n'.join(line.rstrip() for line in markdown.split('\n'))
# التأكد من وجود مسافة واحدة في النهاية
markdown = markdown.rstrip() + '\n'
return markdown
3. التحقق من الإخراج
التحكم في الجودة ضروري. تطبيق التحقق لالتقاط أخطاء التحويل مبكرًا:
def validate_markdown(markdown):
"""التحقق من جودة markdown"""
issues = []
# التحقق من وجود بقايا HTML
if '<' in markdown and '>' in markdown:
issues.append("تم اكتشاف علامات HTML")
# التحقق من وجود روابط معطوبة
if '[' in markdown and ']()' in markdown:
issues.append("تم اكتشاف رابط فارغ")
# التحقق من عدد كتل الكود
code_block_count = markdown.count('```')
if code_block_count % 2 != 0:
issues.append("تم اكتشاف كتلة كود غير مغلقة")
return len(issues) == 0, issues
4. نموذج معالجة دفقة
عند معالجة مجموعات وثائق كبيرة، استخدم هذا النموذج الجاهز للإنتاج مع معالجة الأخطاء، والتسجيل، ومعالجة متوازية:
from pathlib import Path
from concurrent.futures import ProcessPoolExecutor
import trafilatura
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def process_file(html_path):
"""معالجة ملف HTML واحد"""
try:
html = Path(html_path).read_text(encoding='utf-8')
markdown = trafilatura.extract(
html,
output_format='markdown',
include_links=True,
include_images=False
)
if markdown:
# تسوية
markdown = normalize_markdown(markdown)
# التحقق
is_valid, issues = validate_markdown(markdown)
if not is_valid:
logger.warning(f"{html_path}: {', '.join(issues)}")
# حفظ
output_path = Path(str(html_path).replace('.html', '.md'))
output_path.write_text(markdown, encoding='utf-8')
return True
return False
except Exception as e:
logger.error(f"خطأ في معالجة {html_path}: {e}")
return False
def batch_convert(input_dir, max_workers=4):
"""تحويل جميع الملفات HTML في الدليل"""
html_files = list(Path(input_dir).rglob('*.html'))
logger.info(f"تم العثور على {len(html_files)} ملف HTML")
with ProcessPoolExecutor(max_workers=max_workers) as executor:
results = list(executor.map(process_file, html_files))
success_count = sum(results)
logger.info(f"تم تحويل {success_count}/{len(html_files)} ملف")
# الاستخدام
batch_convert('./html_docs', max_workers=8)
الخاتمة
تُقدم بيئته Python أدوات ناضجة ومستعدة للإنتاج لتحويل HTML إلى Markdown، كلها مُحسّنة لسيناريوهات مختلفة. اختيارك يجب أن يتوافق مع متطلباتك الخاصة:
- تحويلات سريعة: استخدم
html2textلبساطته وغياب الاعتماديات - منطق مخصص: استخدم
markdownifyللحصول على مرونة كاملة من خلال الفرز - استخراج الويب: استخدم
trafilaturaلاستخراج المحتوى ذكياً مع إزالة النصوص الثانوية - تحويلات دفقة: استخدم
html2mdللمعالجة غير المتزامنة في المشاريع الكبيرة - أنظمة الإنتاج: استخدم
html-to-markdownللحصول على أمان النوع والدعم الشامل لـ HTML5 - الحفاظ على المعنى: استخدم
domscribeللحفاظ على هيكل HTML5 المعنى
التوصيات لتدفق LLM
لتدفق LLM المسبق، يُنصح بنهج مزدوج:
- ابدأ بـ
trafilaturaلاستخراج المحتوى الأولي - يزيله ذكياً التنقل والإعلانات والنصوص الثانوية مع الحفاظ على المحتوى الرئيسي - الرجوع إلى
html-to-markdownللمستندات المعقدة التي تتطلب الحفاظ على الهيكل بدقة، مثل الوثائق التقنية مع الجداول وكتل الكود
هذا الجمع يتعامل مع 95% من السيناريوهات الواقعية بشكل فعال.
الخطوات التالية
جميع هذه الأدوات (باستثناء html2text) تُدار نشطًا وتكون جاهزة للإنتاج. من الأفضل:
- تثبيت 2-3 مكتبات تتوافق مع استخدامك
- اختبارها مع عينات HTML الخاصة بك
- قياس الأداء مع أحجام الوثائق المعتادة
- اختر بناءً على جودة الإخراج، وليس فقط السرعة
لقد نضجت بيئته Python بشكل كبير لتحويل HTML إلى Markdown، ولا يمكن أن تخطئ في أي من هذه الخيارات لاستخداماتها المقصودة.
موارد إضافية
- مستندات html2text
- markdownify على PyPI
- html-to-markdown على GitHub
- مستندات trafilatura
- مستندات html2md
- domscribe على PyPI
ملاحظة: هذه المقارنة تعتمد على تحليل المستندات الرسمية، والردود المجتمعية، وبنية المكتبة. خصائص الأداء تمثل أنماط الاستخدام المعتادة. لحالات الاستخدام المحددة، قم بإجراء اختباراتك الخاصة مع عينات HTML الخاصة بك.
مقالات مفيدة إضافية
- ورقة مساعدة Markdown
- استخدام كتل الكود في Markdown
- تحويل وثائق Word إلى Markdown: دليل شامل
- تحويل محتوى HTML إلى Markdown باستخدام LLM و Ollama
- ورقة مساعدة cURL
- ورقة مساعدة مولّد المواقع الثابت Hugo
- إضافة ترميز بيانات منظمة إلى Hugo
- Dokuwiki - ويكي مُستضاف ذاتيًا والبدائل
- استخدام Obsidian لإدارة المعرفة الشخصية