C++ 中的 HTML 解析:库概述与代码示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C++ 中的 HTML 解析:库概述与实践示例



在 C++ 中进行 HTML 解析是开发人员在创建网络爬虫、内容分析器或数据提取工具时面临的任务。与 Python 中 BeautifulSoup 和 lxml 是标准不同,C++ 中没有单一的占主导地位的解决方案。然而,有几种成熟且高性能的库可以有效地处理 HTML 文档。



在本文中,我们将介绍三种最流行的用于在 C++ 中解析 HTML 的库:Gumbo-parser(来自 Google)、libxml2(带有 HTML 模块)和 MyHTML。我们将提供代码示例,比较它们的功能,并给出选择建议。



1. Gumbo-parser:来自 Google 的可靠性



Gumbo-parser 是 Google 的一个库,它根据 WHATWG 规范实现了 HTML5 解析。它用纯 C 语言编写,使其轻量且快速。主要优点:



  • 完全支持 HTML5(包括无效文档)
  • 最少的依赖项
  • 用于遍历 DOM 树的简单 API
  • 高性能


安装:

git clone https://github.com/google/gumbo-parsercd gumbo-parser./autogen.sh./configuremakesudo make install


解析 HTML 并提取所有链接的示例:

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

void extract_links(GumboNode* node, std::vector<std::string>& links) { if (node->type != GUMBO_NODE_ELEMENT) return;

GumboAttribute* href; if (node->v.element.tag == GUMBO_TAG_A && (href = gumbo_get_attribute(&node->v.element.attributes, "href"))) { links.push_back(href->value); }

const GumboVector* children = &node->v.element.children; for (unsigned int i = 0; i < children->length; ++i) { extract_links(static_cast<GumboNode*>(children->data[i]), links); }}

int main() { const std::string html = R"(<html><body> <a href="https://pythonlib.ru">PythonLib</a> <a href="/about">关于我们</a> </body></html>)";

GumboOutput* output = gumbo_parse(html.c_str()); std::vector<std::string> links; extract_links(output->root, links);

for (const auto& link : links) { std::cout << "找到链接: " << link << std::endl; }

gumbo_destroy_output(&kGumboDefaultOptions, output); return 0;}


输出:

找到链接: https://pythonlib.ru找到链接: /about


2. libxml2:带有 HTML 模块的通用解析器



libxml2 是一个用于处理 XML 和 HTML 的强大库。它的 HTML 解析器基于与 XML 解析器相同的原理,但针对非严格 HTML 语法进行了调整。优点:



  • 支持用于元素选择的 XPath
  • 内置编码支持
  • 稳定性和广泛使用
  • 能够处理 XSLT


安装 (Ubuntu/Debian):

sudo apt-get install libxml2-dev libxslt1-dev


使用 XPath 查找所有 h2 标题的示例:

#include <libxml/HTMLparser.h>#include <libxml/xpath.h>#include <iostream>

int main() { const char* html = "<html><body><h2>标题 1</h2><h2>标题 2</h2></body></html>"; htmlDocPtr doc = htmlReadDoc( reinterpret_cast<const xmlChar*>(html), nullptr, nullptr, HTML_PARSE_RECOVER | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING );

xmlXPathContextPtr xpathCtx = xmlXPathNewContext(doc); xmlXPathObjectPtr

推荐