تحليل HTML في C++: نظرة عامة على أفضل المكتبات
تحليل (تفكيك) مستندات HTML هي إحدى المهام الرئيسية عند تطوير المحللات، وأدوات استخراج بيانات الويب، وأدوات تحليل البيانات. على الرغم من أن لغة C++ ليست اللغة الأكثر شيوعًا لمثل هذه المهام (تأتي بعد Python أو JavaScript)، إلا أن هناك مكتبات قوية وعالية الأداء تسمح بالعمل بكفاءة مع HTML. في هذه المقالة، سنستعرض ثلاثة من أكثر الحلول نضجًا: Gumbo-parser من Google، وMyHTML، وhtmlcxx. سنشرح واجهات برمجتها، وميزاتها، ونقدم أمثلة عملية على الكود.
1. Gumbo-parser (Google)
Gumbo هي مكتبة لتحليل HTML5، طورها مهندسو Google. وهي متوافقة تمامًا مع مواصفات WHATWG HTML5 وتتميز بمقاومة عالية لرموز HTML "غير النظيفة". المزايا الرئيسية:
- واجهة برمجية نقية بلغة C بدون تبعيات خارجية.
- دعم جميع عناصر HTML5، بما في ذلك SVG وMathML.
- إرجاع شجرة DOM كاملة مع تداخل صحيح.
- سرعة عالية في العمل (تظهر المعايير الأصلية سرعة تصل إلى 50 ميجابايت/ثانية).
مثال على استخدام Gumbo-parser
في هذا المثال، سنستخرج جميع الروابط (<a>) من مستند HTML:
#include <iostream>#include <string>#include "gumbo.h"
void extract_links(GumboNode* node) { if (node->type != GUMBO_NODE_ELEMENT) return;
GumboAttribute* href = nullptr; if (node->v.element.tag == GUMBO_TAG_A) { href = gumbo_get_attribute(&node->v.element.attributes, "href"); if (href) { std::cout << "تم العثور على رابط: " << href->value << std::endl; } }
// اجتياز تكراري للعناصر الفرعية const GumboVector* children = &node->v.element.children; for (unsigned int i = 0; i < children->length; ++i) { extract_links(static_cast<GumboNode*>(children->data[i])); }}
int main() { std::string html = "<html><body><a href='https://example.com'>مثال</a></body></html>"; GumboOutput* output = gumbo_parse(html.c_str()); extract_links(output->root); gumbo_destroy_output(&kGumboDefaultOptions, output); return 0;}كما ترى، يتطلب العمل مع Gumbo إدارة يدوية للذاكرة واجتيازًا تكراريًا للشجرة. بالنسبة للمستندات الكبيرة، يُوصى باستخدام نهج تكراري أو مكدس.
2. MyHTML — محلل سريع وخفيف
MyHTML هي مكتبة مكتوبة بلغة C مع التركيز على أقصى أداء. إنها لا تبني شجرة DOM كاملة، بل تستخدم نهجًا مشابهًا لـ SAX (اجتياز تسلسلي للرموز). وهذا يجعلها مثالية للمهام التي تتطلب استخراج سريع للبيانات دون بناء تسلسل هرمي معقد.
الميزات الرئيسية لـ MyHTML
- بنية معيارية: محلل + مسلسل + واجهة برمجية تدفقية.
- دعم الترميزات (UTF-8، Windows-1251، KOI8-R وغيرها).
- إمكانية العمل مع أجزاء من HTML (بدون <html> إلزامي).
- استهلاك منخفض للذاكرة — لا يخزن الشجرة بأكملها.
مثال: عد جميع الوسوم <div> ذات الفئة "content"
#include <iostream>#include "myhtml/api.h"
int main() { // تهيئة المحلل myhtml_t* myhtml = myhtml_create(); myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0);
// تحليل HTML const char* html = "<div class='content'>الكتلة 1</div><div>الكتلة 2</div>"; myhtml_tree_t* tree = myhtml_tree_create(); myhtml_tree_init(tree, myhtml); myhtml_parse(tree, MyENCODING_UTF_8, html, strlen(html));
// البحث عن العناصر باستخدام محدد CSS myhtml_collection_t* collection = myhtml_collection_create(1, 1); myhtml_css_match_selector(tree, tree->node, "div.con