8

是否有任何关于 ac/cpp lib 的建议可以用来轻松(尽可能多地)解析/迭代/操作 HTML 流/文件,假设某些可能格式错误,即标签未关闭等。

美丽汤

4

4 回答 4

8

来自Libxml的HTMLparser易于使用(下面的简单教程),即使在格式错误的 HTML 上也能很好地工作。

编辑:原始博客文章不再可访问,因此我已将内容复制粘贴到此处。

在 C 中解析 (X)HTML 通常被视为一项艰巨的任务。确实,C 并不是用于开发解析器的最简单的语言。幸运的是,libxml2 的HTMLParser模块提供了帮助。因此,正如所承诺的,这里有一个小教程,解释如何使用 libxml2 的 HTMLParser 来解析 (X)HTML。

首先,您需要创建一个解析器上下文。您有很多功能可以做到这一点,具体取决于您希望如何将数据提供给解析器。我将使用htmlCreatePushParserCtxt(),因为它适用于内存缓冲区。

htmlParserCtxtPtr parser = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL, 0);

然后,您可以在该解析器上下文中设置许多选项。

htmlCtxtUseOptions(parser, HTML_PARSE_NOBLANKS | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING | HTML_PARSE_NONET);

我们现在准备解析 (X)HTML 文档。

// char * data : buffer containing part of the web page
// int len : number of bytes in data
// Last argument is 0 if the web page isn't complete, and 1 for the final call.
htmlParseChunk(parser, data, len, 0);

一旦你推送了所有数据,你可以再次调用该函数并使用NULL缓冲区并1作为最后一个参数。这将确保解析器已处理所有内容。

最后,如何获取你解析的数据?这比看起来容易。您只需遍历创建的 XML 树。

void walkTree(xmlNode * a_node)
{ 
    xmlNode *cur_node = NULL;
    xmlAttr *cur_attr = NULL;
    for (cur_node = a_node; cur_node; cur_node = cur_node->next)
    {
        // do something with that node information, like... printing the tag's name and attributes
        printf("Got tag : %s\n", cur_node->name)
        for (cur_attr = cur_node->properties; cur_attr; cur_attr = cur_attr->next)
        {
            printf("  ->; with attribute : %s\n", cur_attr->name);
        }
        walkTree(cur_node->children);
    }
}
walkTree(xmlDocGetRootElement(parser->myDoc));

就是这样!这还不够简单吗?从那里,你可以做任何事情,比如查找所有引用的图像(通过查看img标签)并获取它们,或者你能想到的任何事情。

此外,您应该知道您可以随时遍历 XML 树,即使您尚未解析整个 (X)HTML 文档。

如果你必须在 C 中解析 (X)HTML,你应该使用 libxml2 的HTMLParser. 它将为您节省大量时间。

于 2012-05-24T16:00:28.977 回答
1

你可以使用 Google gumbo-parser

Gumbo 是 HTML5 解析算法的实现,它作为纯 C99 库实现,没有外部依赖项。它旨在用作其他工具和库的构建块,例如 linter、验证器、模板语言以及重构和分析工具。

#include "gumbo.h"

int main() {
  GumboOutput* output = gumbo_parse("<h1>Hello, World!</h1>");
  // Do stuff with output->root
  gumbo_destroy_output(&kGumboDefaultOptions, output);
}

这个库gumbo-query还有一个C++绑定

一个 C++ 库,为 Google 的 Gumbo-Parser 提供类似 jQuery 的选择器。

#include <iostream>
#include <string>
#include "Document.h"
#include "Node.h"

int main(int argc, char * argv[])
{
  std::string page("<h1><a>some link</a></h1>");
  CDocument doc;
  doc.parse(page.c_str());

  CSelection c = doc.find("h1 a");
  std::cout << c.nodeAt(0).text() << std::endl; // some link
  return 0;
}
于 2021-08-08T22:28:25.427 回答
-1

我只将libCurl C++用于这种类型的东西,但发现它非常好且可用。不知道它会如何处理损坏的 HTML。

于 2012-05-24T15:14:51.890 回答
-4

尝试使用 SIP 并在其上运行 BeautifulSoup 可能会有所帮助。

有关以下链接线程的更多详细信息。开放框架 + Python

于 2014-05-02T00:42:05.207 回答