Análisis de HTML en C++: Reseña de las mejores bibliotecas
El análisis (parseo) de documentos HTML es una de las tareas clave en el desarrollo de analizadores, raspadores web y herramientas de análisis de datos. A pesar de que C++ no es el lenguaje más popular para tales tareas (superado por Python o JavaScript), existen bibliotecas potentes y de alto rendimiento que permiten trabajar eficientemente con HTML. En este artículo, revisaremos tres de las soluciones más maduras: Gumbo-parser de Google, MyHTML y htmlcxx. Analizaremos sus API, características y proporcionaremos ejemplos prácticos de código.
1. Gumbo-parser (Google)
Gumbo es una biblioteca para analizar HTML5, desarrollada por ingenieros de Google. Cumple completamente con la especificación WHATWG HTML5 y se caracteriza por su alta tolerancia al código HTML "sucio". Principales ventajas:
- API C pura sin dependencias externas.
- Soporte para todos los elementos de HTML5, incluyendo SVG y MathML.
- Devuelve un árbol DOM completo con anidamiento correcto.
- Alta velocidad de trabajo (los benchmarks nativos muestran hasta 50 MB/s).
Ejemplo de uso de Gumbo-parser
En este ejemplo, extraeremos todos los enlaces (<a>) de un documento 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 << "Enlace encontrado: " << href->value << std::endl; } }
// Recorrido recursivo de elementos hijos 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'>Ejemplo</a></body></html>"; GumboOutput* output = gumbo_parse(html.c_str()); extract_links(output->root); gumbo_destroy_output(&kGumboDefaultOptions, output); return 0;}Como puede ver, trabajar con Gumbo requiere gestión manual de memoria y recorrido recursivo del árbol. Para documentos grandes, se recomienda usar un enfoque iterativo o una pila.
2. MyHTML — un analizador rápido y ligero
MyHTML es una biblioteca escrita en C con el objetivo de lograr el máximo rendimiento. No construye un árbol DOM completo, sino que utiliza un enfoque similar a SAX (recorrido secuencial de tokens). Esto la hace ideal para tareas donde se necesita extraer datos rápidamente sin construir una jerarquía compleja.
Características clave de MyHTML
- Arquitectura modular: analizador + serializador + API de flujo.
- Soporte de codificaciones (UTF-8, Windows-1251, KOI8-R, etc.).
- Posibilidad de trabajar con fragmentos de HTML (sin <html> obligatorio).
- Bajo consumo de memoria — no almacena todo el árbol.
Ejemplo: contar todas las etiquetas <div> con clase "content"
#include <iostream>#include "myhtml/api.h"
int main() { // Inicialización del analizador myhtml_t* myhtml = myhtml_create(); myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0);
// Análisis de HTML const char* html = "<div class='content'>Bloque 1</div><div>Bloque 2</div>"; myhtml_tree_t* tree = myhtml_tree_create(); myhtml_tree_init(tree, myhtml); myhtml_parse(tree, MyENCODING_UTF_8, html, strlen(html));
// Búsqueda de elementos por selector CSS myhtml_collection_t* collection = myhtml_collection_create(1, 1); myhtml_css_match_selector(tree, tree->node, "div.con