BeautifulSoup的C / CPP版本,特别是在处理格式错误的HTML方面

C/CPP version of BeautifulSoup especially at handling malformed HTML

本文关键字:格式 处理 错误 HTML 方面 CPP 版本 BeautifulSoup 特别是      更新时间:2023-10-16

是否有任何关于 c/cpp 库的建议,可用于轻松(尽可能多地)解析/迭代/操作 HTML 流/文件,假设有些流/文件可能格式不正确,即标签未关闭等。

美丽汤

来自

Libxml的HTML解析器易于使用(下面的简单教程),即使在格式错误的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 : %sn", cur_node->name)
        for (cur_attr = cur_node->properties; cur_attr; cur_attr = cur_attr->next)
        {
            printf("  ->; with attribute : %sn", cur_attr->name);
        }
        walkTree(cur_node->children);
    }
}
walkTree(xmlDocGetRootElement(parser->myDoc));

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

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

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

你可以使用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;
}

我只使用libCurl C++做这类事情,但发现它非常好且可用。不知道它将如何应对损坏的 HTML。

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

有关以下链接线程的更多详细信息。OpenFrameworks + Python