Parsing HTML in C++: Libraries and Examples for Working with DOM and XPath

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Parsing HTML in C++: Overview of Tools and Practical Examples



Parsing HTML in C++ is a task that developers face when creating web page parsers, content analyzers, or tools for automated data collection. Unlike Python or JavaScript, C++ does not have a built-in library for working with HTML documents, but there are several mature and high-performance solutions. In this article, we will review the main libraries for parsing HTML in C++, their features, and provide code examples.



Main Libraries for Parsing HTML in C++



The choice of library depends on your tasks: whether you need support for CSS selectors, XPath, working with malformed HTML, or maximum speed. Let's look at the most popular options.



  • Gumbo-parser — a library from Google that implements HTML5 parsing according to the specification. It provides a DOM tree after parsing but does not include built-in tools for navigation via selectors. Requires manual node traversal.
  • MyHTML — a fork of Gumbo with improved CSS selector support and a more convenient API. Allows searching for elements by classes, tags, and attributes.
  • Lexbor — a modern library focused on speed and standards compliance. Supports both HTML and CSS selectors, as well as XPath (via an additional module).
  • htmlcxx — a simple library for parsing HTML into a tree. Suitable for small projects but does not support HTML5.
  • Boost.PropertyTree (with XML parser) — can be used for parsing XHTML but is not intended for invalid HTML.


Installation and Setup



Let's look at installing two of the most popular libraries: Gumbo-parser and MyHTML. For C++17 projects, it is recommended to use the vcpkg or Conan package manager.



// Installation via vcpkgvcpkg install gumbo-parservcpkg install myhtml

// Setup in CMakeLists.txtfind_package(gumbo REQUIRED)target_link_libraries(your_project PRIVATE gumbo)

find_package(myhtml REQUIRED)target_link_libraries(your_project PRIVATE myhtml)


Example 1: Parsing HTML with Gumbo-parser (Manual DOM Traversal)



In this example, we will parse a simple HTML document and extract all text from <p> tags.



#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) { // Process child nodes 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; } // Recursive traversal for other elements 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>First paragraph</p><p>Second paragraph</p></body></html>)"; GumboOutput* output = gumbo_parse(html.c_str()); extract_text(output->root); gumbo_destroy_output(&kGumboDefaultOptions, output); return 0;}


Example 2: Using MyHTML with CSS Selectors



MyHTML provides a more convenient interface for finding elements. In this example, we will find all links with the class link and output their href attribute.



Recommendations