Парсинг HTML в C++: библиотеки и примеры для работы с DOM и XPath

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Парсинг HTML в C++: обзор инструментов и практические примеры

Парсинг HTML на C++ — задача, с которой сталкиваются разработчики при создании парсеров веб-страниц, анализаторов контента или инструментов для автоматизированного сбора данных. В отличие от Python или JavaScript, в C++ нет встроенной библиотеки для работы с HTML-документами, однако существует несколько зрелых и производительных решений. В этой статье мы рассмотрим основные библиотеки для парсинга HTML в C++, их особенности и приведём примеры кода.

Основные библиотеки для парсинга HTML в C++

Выбор библиотеки зависит от ваших задач: нужна ли поддержка CSS-селекторов, XPath, работа с повреждённым HTML или максимальная скорость. Рассмотрим самые популярные варианты.

  • Gumbo-parser — библиотека от Google, реализующая парсинг HTML5 по спецификации. Она предоставляет DOM-дерево после разбора, но не включает встроенных средств для навигации по селекторам. Требует ручного обхода узлов.
  • MyHTML — форк Gumbo с улучшенной поддержкой CSS-селекторов и более удобным API. Позволяет искать элементы по классам, тегам и атрибутам.
  • Lexbor — современная библиотека с фокусом на скорость и соответствие стандартам. Поддерживает как HTML, так и CSS-селекторы, а также XPath (через дополнительный модуль).
  • htmlcxx — простая библиотека для разбора HTML в дерево. Подходит для небольших проектов, но не поддерживает HTML5.
  • Boost.PropertyTree (с XML-парсером) — может использоваться для разбора XHTML, но не предназначен для невалидного HTML.

Установка и подключение

Рассмотрим установку двух наиболее популярных библиотек: Gumbo-parser и MyHTML. Для проектов на C++17 рекомендуется использовать менеджер пакетов vcpkg или Conan.

// Установка через vcpkg
vcpkg install gumbo-parser
vcpkg install myhtml

// Подключение в CMakeLists.txt
find_package(gumbo REQUIRED)
target_link_libraries(your_project PRIVATE gumbo)

find_package(myhtml REQUIRED)
target_link_libraries(your_project PRIVATE myhtml)

Пример 1: Парсинг HTML с Gumbo-parser (ручной обход DOM)

В этом примере мы разберём простой HTML-документ и извлечём все тексты из тегов <p>.

#include <iostream>
#include <string>
#include <gumbo.h>

void extract_text(GumboNode* node) {
    if (node->type == GUMBO_NODE_TEXT) {
        std::cout << node->v.text.text;
        return;
    }
    if (node->type == GUMBO_NODE_ELEMENT &&
        node->v.element.tag == GUMBO_TAG_P) {
        // Обрабатываем дочерние узлы
        GumboVector* children = &node->v.element.children;
        for (unsigned int i = 0; i < children->length; ++i) {
            extract_text(static_cast<GumboNode*>(children->data[i]));
        }
        std::cout << std::endl;
        return;
    }
    // Рекурсивный обход для других элементов
    if (node->type == GUMBO_NODE_ELEMENT) {
        GumboVector* children = &node->v.element.children;
        for (unsigned int i = 0; i < children->length; ++i) {
            extract_text(static_cast<GumboNode*>(children->data[i]));
        }
    }
}

int main() {
    std::string html = R"(<html><body><p>Первый параграф</p><p>Второй параграф</p></body></html>)";
    GumboOutput* output = gumbo_parse(html.c_str());
    extract_text(output->root);
    gumbo_destroy_output(&kGumboDefaultOptions, output);
    return 0;
}

Пример 2: Использование MyHTML с CSS-селекторами

MyHTML предоставляет более удобный интерфейс для поиска элементов. В этом примере мы найдём все ссылки с классом link и выведем их атрибут href.

#include <iostream>
#include <myhtml/api.h>

int main() {
    // Инициализация
    myhtml_t* myhtml = myhtml_create();
    myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0);
    
    myhtml_tree_t* tree = myhtml_tree_create();
    myhtml_tree_init(tree, myhtml);
    
    std::string html = R"(
        <html><body>
            <a href="https://example.com" class="link">Example<                    

Рекомендаций