C++ html解析库htmlcxx自封装的工具类(搜索标签) - Go语言中文社区

C++ html解析库htmlcxx自封装的工具类(搜索标签)


htmlcxxC++中解析html格式数据的第三方库,这个库的特点就是快捷、轻量级。最近在使用的时候在解析html的时候,总有搜索标签的需求,所以自己封装了一个工具。

1、HtmlCxxUtils.h头文件

/**
 * HtmlCxxUtils类定义
 * 
 * @author hestyle
 * @version 1.0.0
 */
#ifndef _HTMLCXX_UTILS_
#define _HTMLCXX_UTILS_

#include "htmlcxx/include/ParserDom.h"
//导入htmlcxx.lib,请修改为你自己的路径
#pragma comment(lib,"htmlcxx/lib/htmlcxx.lib")

using namespace std;
using namespace htmlcxx;

class HtmlCxxUtils{

public:
	HtmlCxxUtils();
	~HtmlCxxUtils();
	/*
	 * 在[beginIt,endIt)寻找第index个名为tagName的标签
	 * @param beginIt   搜索起始迭代器
	 * @param endIt     搜索尾端迭代器
	 * @param tagName   需要搜索标签名
	 * @param index     符合搜索条件的第index个(默认是第1个)
	 */
	static tree<HTML::Node>::iterator selectTag(tree<HTML::Node>::iterator& beginIt, tree<HTML::Node>::iterator& endIt,
		string tagName, int index = 1);

	/*
	 * 在[beginIt,endIt)寻找第index个名为tagName的标签,并且该标签中含有名为attrName的属性、属性值为attrValue
	 * @param beginIt   搜索起始迭代器
	 * @param endIt     搜索尾端迭代器
	 * @param tagName   需要搜索标签名
	 * @param attrName  标签含有的属性名
	 * @param attrValue 标签含有的attrName属性的值
	 * @param index     符合搜索条件的第index个(默认是第1个)
	 */
	static tree<HTML::Node>::iterator selectTag(tree<HTML::Node>::iterator& beginIt, tree<HTML::Node>::iterator& endIt,
		string tagName, string attrName, string attrValue, int index = 1);
};

#endif // !_HTMLCXX_UTILS_

2、HtmlCxxUtils.cpp类文件

/**
 * HtmlCxxUtils类方法实现
 * 
 * @author hestyle
 * @version 1.0.0
 */
#include <iostream>
#include <string>
#include <vector>
#include "HtmlCxxUtils.h"

using namespace std;
using namespace htmlcxx;

HtmlCxxUtils::HtmlCxxUtils() {

}
HtmlCxxUtils::~HtmlCxxUtils() {

}

/*
 * 在[beginIt,endIt)寻找第index个名为tagName的标签
 * @param beginIt   搜索起始迭代器
 * @param endIt     搜索尾端迭代器
 * @param tagName   需要搜索标签名
 * @param index     符合搜索条件的第index个(默认是第1个,可省略,注意声明设置了默认参数,实现方法不要写默认参数,否则会报错)
 */
tree<HTML::Node>::iterator HtmlCxxUtils::selectTag(tree<HTML::Node>::iterator& beginIt, tree<HTML::Node>::iterator& endIt,
	string tagName, int index) {
	tree<HTML::Node>::iterator it = beginIt;
	for (; it != endIt; ++it) {
		if (it->isTag()) {
			//扩展子标签
			it->parseAttributes();
			//第index个名为tagName的标签
			if (strcmp(it->tagName().c_str(), tagName.c_str()) == 0 && index-- == 1) {
				return it;
			}
		}
	}
	//否则返回空
	return NULL;
}

/*
 * 在[beginIt,endIt)寻找第index个名为tagName的标签,并且该标签中含有名为attrName的属性、属性值为attrValue
 * @param beginIt   搜索起始迭代器
 * @param endIt     搜索尾端迭代器
 * @param tagName   需要搜索标签名
 * @param attrName  标签含有的属性名
 * @param attrValue 标签含有的attrName属性的值
 * @param index     符合搜索条件的第index个(默认是第1个,可省略,注意声明设置了默认参数,实现方法不要写默认参数,否则会报错)
 */
tree<HTML::Node>::iterator HtmlCxxUtils::selectTag(tree<HTML::Node>::iterator& beginIt, tree<HTML::Node>::iterator& endIt,
	string tagName, string attrName, string attrValue, int index) {
	tree<HTML::Node>::iterator it = beginIt;
	for (; it != endIt; ++it) {
		it = selectTag(it, endIt, tagName);
		if (it == NULL) {
			break;
		}
		//检查该标签是否含有attrName属性,并且属性值为attrValue
		if (it->attribute(attrName).first && strcmp(it->attribute(attrName).second.c_str(), attrValue.c_str()) == 0 && index-- == 1) {
			return it;
		}
	}
	return NULL;
}

3、测试用例

在这里插入图片描述

#include <iostream>
#include <string>
#include "htmlcxx/include/ParserDom.h"
#include "HtmlCxxUtils.h"

using namespace std;
using namespace htmlcxx;

int main() {
	//需要解析的html文本
	string htmlStr = "<div class="parent"><div class="children_1"><span>I am the first span!</span></div><div class="children_2"><span>I am the second span!</span></div></div><div class="parent">123456789<div>";
	//解析html前设置,方式解析中文报错
	setlocale(LC_ALL, ".OCP");
	HTML::ParserDom parser;
	tree<HTML::Node> dom = parser.parseTree(htmlStr);
	//输出树中所有的文本节点
	tree<HTML::Node>::iterator it = dom.begin();
	tree<HTML::Node>::iterator end = dom.end();

	//测试static tree<HTML::Node>::iterator selectTag(tree<HTML::Node>::iterator& beginIt, tree<HTML::Node>::iterator& endIt,string tagName, int index = 1);

	//查找html中的第一个span(不写index参数,默认是第一个)
	tree<HTML::Node>::iterator firstSpanIt = HtmlCxxUtils::selectTag(it, end, "span");
	if (firstSpanIt != NULL) {
		//注意,上面的额搜索只搜索到了span标签,需要后一个位置进入span标签的内部
		firstSpanIt++;
		cout << "第一个span标签内部的text:" + firstSpanIt->text() << endl;
	}

	//查找html中的第2个span(不写index参数,默认是第一个)
	tree<HTML::Node>::iterator secondSpanIt = HtmlCxxUtils::selectTag(it, end, "span", 2);
	if (firstSpanIt != NULL) {
		//注意,上面的额搜索只搜索到了span标签,需要后一个位置进入span标签的内部
		secondSpanIt++;
		cout << "第二个span标签内部的text:" + secondSpanIt->text() << endl;
	}

	//测试static tree<HTML::Node>::iterator selectTag(tree<HTML::Node>::iterator& beginIt, tree<HTML::Node>::iterator& endIt, string tagName, string attrName, string attrValue, int index = 1);

	//查找html中的第一个div(不写index参数,默认是第一个),并且含有class属性,属性值为“children_1”
	tree<HTML::Node>::iterator firstDivIt = HtmlCxxUtils::selectTag(it, end, "div", "class", "children_1");
	if (firstDivIt != NULL) {
		cout << "第一个含有属性class="children_1"的div:" + firstDivIt->text() << endl;
	}

	//查找html中的第二个div(不写index参数,默认是第一个),并且含有class属性,属性值为“parent”
	tree<HTML::Node>::iterator secondDivIt = HtmlCxxUtils::selectTag(it, end, "div", "class", "parent", 2);
	if (firstDivIt != NULL) {
		secondDivIt++;
		cout << "第二个含有属性class="parent"的div:" + secondDivIt->text() << endl;
	}
}

控制台输出:
在这里插入图片描述
以上就是我自己封装的htmlcxx工具类以及使用方法,希望可以帮助到给为道友。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_41855420/article/details/104566210
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢