Parsing HTML in C++: Overview of the Best Libraries
Parsing HTML documents is one of the key tasks when developing parsers, web scrapers, and data analysis tools. Despite the fact that C++ is not the most popular language for such tasks (yielding to Python or JavaScript), there are powerful and high-performance libraries that allow you to work with HTML efficiently. In this article, we will look at three of the most mature solutions: Gumbo-parser from Google, MyHTML, and htmlcxx. We will analyze their APIs, features, and provide practical code examples.
1. Gumbo-parser (Google)
Gumbo is an HTML5 parsing library developed by Google engineers. It fully complies with the WHATWG HTML5 specification and is highly resilient to "dirty" HTML code. Key advantages:
- Clean C API with no external dependencies.
- Support for all HTML5 elements, including SVG and MathML.
- Returns a complete DOM tree with correct nesting.
- High speed (native benchmarks show up to 50 MB/s).
Example of using Gumbo-parser
In this example, we will extract all links (<a>) from an HTML document:
#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 << "Found link: " << href->value << std::endl; } }
// Recursive traversal of child elements 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'>Example</a></body></html>"; GumboOutput* output = gumbo_parse(html.c_str()); extract_links(output->root); gumbo_destroy_output(&kGumboDefaultOptions, output); return 0;}As you can see, working with Gumbo requires manual memory management and recursive tree traversal. For large documents, it is recommended to use an iterative approach or a stack.
2. MyHTML — fast and lightweight parser
MyHTML is a library written in C with a focus on maximum performance. It does not build a complete DOM tree but uses a SAX-like approach (sequential token traversal). This makes it ideal for tasks where you need to quickly extract data without building a complex hierarchy.
Key features of MyHTML
- Modular architecture: parser + serializer + streaming API.
- Encoding support (UTF-8, Windows-1251, KOI8-R, etc.).
- Ability to work with HTML fragments (without mandatory <html>).
- Low memory consumption — does not store the entire tree.
Example: counting all <div> tags with class "content"
#include <iostream>#include "myhtml/api.h"
int main() { // Initialize the parser myhtml_t* myhtml = myhtml_create(); myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0);
// Parse HTML const char* html = "<div class='content'>Block 1</div><div>Block 2</div>"; myhtml_tree_t* tree = myhtml_tree_create(); myhtml_tree_init(tree, myhtml); myhtml_parse(tree, MyENCODING_UTF_8, html, strlen(html));
// Search for elements by CSS selector myhtml_collection_t* collection = myhtml_collection_create(1, 1); myhtml_css_match_selector(tree, tree->node, "div.con