BeautifulSoup的C / CPP版本,特别是在处理格式错误的HTML方面
C/CPP version of BeautifulSoup especially at handling malformed HTML
是否有任何关于 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
- 警告处理为错误这里有什么问题
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 生成库失败:无法识别文件格式;作为链接器脚本处理
- 在处理C 中的数字格式时,在SetPrecision中使用固定关键字
- 我可以在处理时保持编译器输出的格式
- 如何在自己的函数中最好地处理Mat中的不同数字格式
- 自然语言处理:word2vec的文本语料库格式
- BeautifulSoup的C / CPP版本,特别是在处理格式错误的HTML方面
- 如何设置错误处理语句的格式
- 如何将提取的光栅信息转换为可由opencv库处理的格式
- 如何在读取数据时处理不同版本的格式
- ARM的c++异常处理-通用异常处理表项的格式
- 无法识别文件格式;作为链接器脚本处理
- 根据标准,c++编译器需要如何处理格式不良的程序?
- 有没有一种方法可以让QXmlStreamReader处理格式错误的XML
- 如何处理带有%d格式说明符的字符
- 如何为自定义文件格式构建筛选器处理程序,以便可以通过windows搜索来搜索其内容
- 我如何处理输入/输出格式的竞争性编程网站,如SPOJ