之前使用过PHP的Simple HTML DOM简单地解析HTML但PHP终非我所熟悉的语言,虽然我并不对语言抱有绝对的执着= =(什么你不相信,好吧,不管你信不信,反正我是信了= =)。虽然可以简单地使用正则表达式来解析HTML但我不是希望能够找到一个合适的HTML解析库,网上搜索了下关于c语言解析HTML的库,好像不是挻多的样子,我搜索到了google的gumbo,

gumbo是开源的,可以从这里得到它

https://github.com/google/gumbo-parser

我们需要下载回来手动编译安装,这里以linux debian为例

git clone https://github.com/google/gumbo-parser

cd gumbo-parser

./autogen.sh

./configure

这些一般都会非常顺利,没什么好说的,接下来就是

make

我要执行make后发现有一个错误导致无法编译通过,不知道各位是什么情况,给出的错误提示是benchmarks/benchmark.cc

文件中使用了未定义的函数clock_gettime

man了一下,该函数需要包含time.h头文件,打开benchmark.cc文件查看的确已经包含了time.h头文件,很苦恼,突然一下子就懵了,不过还好我反应还算快,看到manpages中写到

Link with-lrt (only for glibc versions before 2.17).

于是猜测没有链接库,使用vim打开Makefile文件,这个文件内容太多= =,要分析的话有些费劲,不过机智的我还是很快地通过benchmark关键字定位到了benchmark_LDADD这个变量,然后在后面加上-lrt

注意有空格

再次make,果然成功了。。。。。。。。。。。

编译完成之后就可以使用make install进行安装了,你可能需要使用root用户权限,因为默认的安装目录在/usr/local/下

gumbo的源码提供了几个示例程序,一个c语言写的获取标题的源码和另外三个使用c++编写的代码,我全都看了(你看,我说过我不是绝对的语言执着者吧,很不幸,这些程序我都看懂了= =)

简单地说gumbo的使用很简单,使用gumbo_parse或者gumbo_parse_with_options就可以得到一个GumboOutput数据结构,我们就可以从该结构中寻找我们想要的东西了。

我们先来看一个简单的例子,就拿获取title来说吧,我决定用自己写的解析代码而不是gumbo源码提供的好个示例,因为我发现该程序无法解析出我使用的示例HTML文本文件= =,所以我就自己写个吧。。。。。。

#include#include#include#include#include

/*包含头文件*/#include

void get_title(GumboNode *node)

{

GumboVector*children;inti;/*如果当前节点不是一个元素的话直接返回*/

if(node->type != GUMBO_NODE_ELEMENT) return;/*获取该节点的所有子元素节点*/children=&node->v.element.children;/*检查当前节点的标签是否为TITLE(title)

* 如果是则输出该节点下第一个节点的文本内容*/

if(node->v.element.tag ==GUMBO_TAG_TITLE)

printf("%s\n",((GumboNode *)children->data[0])->v.text.text);/*递归该节点下的所有子节点*/

for(i=0;i < children->length;++i)

get_title(children->data[i]);

}int main(int argc,char **argv)

{structstat buf;

GumboOutput*output;

FILE*fp;char *data;/*读取HTML文本文件*/

if(!(fp=fopen(argv[1],"rb"))) return -1;

stat(argv[1],&buf);

data=malloc(sizeof(char)*(buf.st_size+1));

fread(data,sizeof(char),buf.st_size,fp);

fclose(fp);

data[buf.st_size]=0;/*解析HTML文本文件*/output=gumbo_parse(data);/*获取TITLE*/get_title(output->root);/*销毁,释放内存*/gumbo_destroy_output(&kGumboDefaultOptions,output);free(data);return 0;

}

注释已经写的很清楚了,首先我们的节奏是这个样子的:

第一步加载HTML文本文件,我们把它读到一个buf中,

第二步我们进行解析出GumboOutput数据结构

第三步在GumboOptout这个数据结构中找出title标签

最后我们输出内容,gumbo的步骤基本上就是这个样子的了,使用gcc编译的时候需要加上-lgumbo

下面再说一个例子,该例子中的HTML文件内容是各国DNS的IP地址以及物理地址,大概的格式是

开始ip地址结束ip地址物理地址我们的解析步骤是获取所有dt标签再获取所有dd标签,然后分别输出dd标签中class属性为ipstart、ipend、address的内 容,下面放代码,由于原HTML文本文件内容放多,我不便放上来,这里就使用在线抓取的方式获取HTML文本,所以这里给出的是HTML文本的url地 址,至目前写代码这一刻该程序还是完全能够正常工作的,日后会该网页是否会因该网页做调整等原因解析出错就不得而知了。

#include#include#include#include

/*包含头文件*/#include

#define URL "http://ip.yqie.com/dns_usa.htm"

void print_dns(GumboNode *node,GumboAttribute *attr)

{/*获取子节点*/GumboNode*ip=(GumboNode *)(&node->v.element.children)->data[0];/*根据class属性的值打印结果*/

if(strcmp(attr->value,"ipstart") == 0)

{if(ip->type ==GUMBO_NODE_TEXT)

printf("开始IP:%s",ip->v.text.text);

}else if(strcmp(attr->value,"ipend") == 0)

{if(ip->type ==GUMBO_NODE_TEXT)

printf("结束IP:%s",ip->v.text.text);

}else if(strcmp(attr->value,"address") == 0)

{if(ip->type ==GUMBO_NODE_TEXT)

printf("物理地址:%s\n",ip->v.text.text);

}

}void get_dns(GumboNode *node,GumboTag tag)

{

GumboVector*children;

GumboAttribute*attr;inti;if(node->type != GUMBO_NODE_ELEMENT) return;/*获取当前节点class属性*/

if(attr=gumbo_get_attribute(&node->v.element.attributes,"class"))

print_dns(node,attr);/*当前节点子节点*/children=&node->v.element.children;/*如果当前节点标签为td我们就查找dd标签*/

if(node->v.element.tag ==GUMBO_TAG_DT)for(i=0;i < children->length;++i)

get_dns(children->data[i],GUMBO_TAG_DD);/*查找所有

标签*/

for(i=0;i < children->length;++i)

get_dns(children->data[i],GUMBO_TAG_DT);

}int main(void)

{

GumboOutput*output;char *buf;/*下载HTML文本文件*/buf=oauth_http_get(URL,NULL);if(!buf) return-1;/*解析*/output=gumbo_parse(buf);if(!output)

{free(buf);return -1;

}/*获取我们想要的内容

*/get_dns(output->root,GUMBO_TAG_DT);/*释放资源*/gumbo_destroy_output(&kGumboDefaultOptions,output);free(buf);return 0;

}

由于使用了oauth所以使用gcc编译时需要加上-loauth参数

C语言解析动态html,【c语言】使用gumbo解析HTML相关推荐

  1. c语言实现动态字符串,C语言怎么实现可变长度字符串

    C语言怎么实现可变长度字符串 关注:149  答案:3  手机版 解决时间 2021-02-09 17:22 提问者北墓南笙 2021-02-09 04:15 比如C# 写了个配置文件 不管多长都声明 ...

  2. 什么是python语言的动态类型机制_python的内存管理机制

    一.python是一个什么样类型的语言 1.python是一种动态解释性强类型定义的高级.通用性编程语言. 解释型:执行的时候,才一条一条的解释成机器语言给计算机来执行.如:python.js.rub ...

  3. python程序设计语言是什么类型的语言-Python 是弱类型的语言 强类型和弱类型的语言区别...

    Python 是弱类型的语言 在强类型的编程语言中,定义变量时要指明变量的类型,而且赋值的数据也必须是相同类型的,C语言.C++.Java 是强类型语言的代表. 下面我们以 C++ 为例来演示强类型语 ...

  4. python是高级动态语言_Python动态语言之魅力揭秘

    之前的文章跟大家讲解了鸭子类型,其实鸭子类型是编程语言中动态类型语言中的一种设计风格.今天跟大家一起谈谈动态语言的魅力. 根据维基百科,动态编程语言是这样子定义的:动态编程语言是高级编程语言的一个类别 ...

  5. 下面的语言中哪些语言是动态语言( )

    下面的语言中哪些语言是动态语言(B    ) A.C B.JavaScript C.C++ D.CSS E.Java F.Objective-C 解析 静态语言(强类型语言) 静态语言是在编译时变量的 ...

  6. 静态类型和动态类型的语言有什么区别?

    我听到很多新的编程语言是动态类型的,但是当我们说一种语言是动态类型还是静态类型时,这实际上意味着什么? #1楼 http://en.wikipedia.org/wiki/Type_system 静态打 ...

  7. [转载] 【Python进阶】4-2 多态 | 什么是多态 / 静态语言vs动态语言 / python中多态

    参考链接: Python中的多态 文章目录 1.什么是多态"开闭"原则 2.静态语言 vs 动态语言小结 3.python中多态 1.什么是多态 要理解什么是多态,我们首先要对数据 ...

  8. go编译库给c语言map参数,在 Go 中使用 C 语言的动态库

    我和我的儿子在上周末干了一件非常有意思的事情,我们开发了一个用 Go 编写的命令行游戏,最近我正在重写一款曾经在年轻时开发的游戏,当时用的还是 Kaypro II. ![](https://raw.g ...

  9. 01 C语言实现动态气泡碰撞和移动的效果,小球碰撞,Win7气泡壁纸,碰撞算法

    C语言实现动态气泡碰撞和移动的效果 作者 将狼才鲸 创建日期 2023-01-29 Git源码仓库地址:C语言实现动态气泡碰撞和移动的效果 CSDN文章地址:01 C语言实现动态气泡碰撞和移动的效果 ...

  10. 【编程语言】静态语言与动态语言的本质区别以及其应用场景

    从宏观的语言层面来说,编程语言类型共分为两大类:静态语言(又叫强类型语言)与动态语言(又叫弱类型语言).静态语言通常是低级(底层)语言,动态语言一般为高级(应用)语言,静态语言运用通常是通过编译器,而 ...

最新文章

  1. 使用 Servlet 读取表单数据
  2. java 文件路径表达式_Java基础(二十二) Lambda表达式和File类
  3. 有趣c语言编程经典例子,C语言简单有趣例子总结ZWF.pdf
  4. YBTOJ:运动积分(trie树)
  5. POJ 1276 Cash Machine
  6. MD5,MD2,SHA加密的实现方式
  7. webservice调用天气服务
  8. spring框架 c p标签的区别_Spring学习初体验
  9. 春日 [宋] 王安石
  10. 机器人水下赌场争霸战!中国团队创造历史,在美国登顶世界第一
  11. 查看eclipse使用的jre版本
  12. java 到异常_java编程中遇到的异常以及异常的一些处理
  13. 使用root登陆到mysql后执行_如何让mysql以root用户远程登陆mysql数据库
  14. 佳能ir2002g无法扫描到计算机,佳能ir2002g扫描驱动
  15. 三阶实对称矩阵的秩一分解(快速计算三阶矩阵特征值特征向量的方法)
  16. 基于HFSS的圆极化阵列天线设计
  17. junit5 入门系列教程-05-junit5 断言(assert)
  18. python平均分及格率优秀率_跪求:请问怎样统计均分、优秀率、及格率、低分率的问题...
  19. 如何用计算机求一个正数的算术平方根,用计算器求一个正数的算术平方根
  20. 十进制转换为三进制实例

热门文章

  1. php变量显示,php – 显示会话变量
  2. VMWare 虚拟机中安装 CentOS 7
  3. Bytecoin节点搭建
  4. ctf 抓捕赵德汉_2017年网络空间安全技术大赛部分writeup
  5. python发送文件到邮箱_python 发送附件至邮箱
  6. android 图片拍照,Android获取图片拍照时间
  7. ios开发读取剪切板的内容_ios开发读取剪切板的内容_苹果隐私问题堪忧!多个iOS应用未经许可读取剪贴板......
  8. 求出m~n的整数中1出现的次数
  9. select自定义下拉选择图标
  10. 经理和下属谁更需要去了解业务