Парсинг HTML в C++: Обзор лучших библиотек
Разбор (парсинг) HTML-документов — одна из ключевых задач при разработке парсеров, веб-скраперов и инструментов анализа данных. Несмотря на то, что C++ не является самым популярным языком для таких задач (уступая Python или JavaScript), существуют мощные и высокопроизводительные библиотеки, позволяющие эффективно работать с HTML. В этой статье мы рассмотрим три наиболее зрелых решения: Gumbo-parser от Google, MyHTML и htmlcxx. Разберём их API, особенности и приведём практические примеры кода.
1. Gumbo-parser (Google)
Gumbo — это библиотека для парсинга HTML5, разработанная инженерами Google. Она полностью соответствует спецификации WHATWG HTML5 и отличается высокой устойчивостью к "грязному" HTML-коду. Основные преимущества:
- Чистый C API без внешних зависимостей.
- Поддержка всех элементов 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
- Модульная архитектура: парсер + сериализатор + потоковый API.
- Поддержка кодировок (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.content", collection, NULL);
std::cout << "Найдено элементов: " << collection->length << std::endl;
// Очистка
myhtml_collection_destroy(collection);
myhtml_tree_destroy(tree);
myhtml_destroy(myhtml);
return 0 Также в библиотеке
JSON обработка в C# (.NET): полное руководство с примерами
Socket.io для JavaScript (Node.js): полное руководство с примерами
Генерация QR-кодов на PHP: библиотека phpqrcode и полный гайд