C++ 中的 HTML 解析:工具概览与实践示例
在 C++ 中解析 HTML 是开发者在创建网页解析器、内容分析器或自动化数据收集工具时经常遇到的任务。与 Python 或 JavaScript 不同,C++ 没有用于处理 HTML 文档的内置库,但存在几个成熟且高性能的解决方案。在本文中,我们将介绍 C++ 中用于 HTML 解析的主要库、它们的特点,并提供代码示例。
C++ 中用于 HTML 解析的主要库
库的选择取决于您的需求:是否需要支持 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-parservcpkg 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:使用 Gumbo-parser 解析 HTML(手动 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 属性。
图书馆中也有
推荐