HTML解析库Gumbo的使用(一)

60 篇文章 2 订阅
60 篇文章 0 订阅

Gumbo结构关系图如下:

测试htm文件内容如下(a.html):

<html>
<head>
<title> I'm a title</title>
</head>
<body link="#0000cc">
I'm a body text
<div>

</div>
</body>
</html>

代码如下(mian.cpp):

#include <QCoreApplication>
#include <QFile>
#include <QDebug>
#include <iostream>
#include "gumbo/gumbo.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QFile file("a.html");
    if (!file.open(QFile::ReadOnly)){
        qDebug()<<"open file failed!";
        return -1;
    }

    QByteArray html = file.readAll();
    std::cout<<html.toStdString();

    int input_length = html.length();
    GumboOutput* output = gumbo_parse_with_options(
          &kGumboDefaultOptions, html.toStdString().c_str(), input_length);

    // ===== start

    const GumboVector *root_children = &output->root->v.element.children;
    GumboNode* head = NULL;
    for (int i = 0; i < root_children->length; ++i) {
        GumboNode* child =(GumboNode*) root_children->data[i];
        if (child->type == GUMBO_NODE_ELEMENT/* && child->v.element.tag == GUMBO_TAG_HEAD*/) {
            std::cout<<"tag:"<<gumbo_normalized_tagname(child->v.element.tag)<<std::endl;

            // node children start =====
//            if (child->v.element.tag == GUMBO_TAG_HEAD){
                GumboVector *head_children = &child->v.element.children;
                for(int i=0; i<head_children->length; ++i){
                    GumboNode *child2 = (GumboNode*)head_children->data[i];
                    if (child2->type != GUMBO_NODE_ELEMENT && child2->type != GUMBO_NODE_DOCUMENT)
                    {
                        //节点结束时会换行,换行、空白符也算上是一个节点,类型是:GUMBO_NODE_WHITESPACE
                        std::cout<<"node is text:"<<child2->v.text.text<<std::endl;
                        continue;
                    }
                    std::cout<<"tag:"<<gumbo_normalized_tagname(child2->v.element.tag)<<std::endl;
                    if (child2->type == GUMBO_NODE_ELEMENT/* && child2->v.element.tag == GUMBO_TAG_TITLE*/)
                    {
                        // 元素里面的文本,例如<head>I'm a title</head>,里面的文本也是作为<head>元素里的子节点
                        GumboNode * title_node = (GumboNode*)child2->v.element.children.data[0];
                        if(title_node && title_node->type == GUMBO_NODE_TEXT){
                            std::cout<<"tag is text:"<<title_node->v.text.text<<std::endl;
                        }
                    }
                }
            //}
            //break;
          // node childre end =====
        }
    }

    // ===== end



    gumbo_destroy_output(&kGumboDefaultOptions, output);
      //free(input);

    return 0;
}

Gumbo说明:

1、整个html文档,就是Gumbo的文档节点,是<html></html>的全部,节点类型是:GUMBO_NODE_DOCUMENT

2、每个标签(例如:<head><body>)是一个节点,节点类型是:GUMBO_NODE_ELEMENT。标签里面的的属性定义是属性。

3、标签的子节点是标签括起来的部分,包括标签的换行"\n"(标签类型为:GUMBO_NODE_WHITESPACE),标签里面的文本(标签为元素标签,并且tag是文本)。

例如上面的html代码:

<html></html>是文档节点,换行"\n"、<head>和<body>是其子节点,节点类型分别是:GUMBO_NODE_WHITESPACEGUMBO_NODE_ELEMENTGUMBO_NODE_ELEMENT

<head>标签节点的子节点是:换行"\n",<title>、文本节点(” I'm a title“)。


运行结果:

其中:

tag:head

node is text:


这里有两次换行,一次是这个节点本身是换行,另外是代码程序的换行。


  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值