golang HTML节点树遍历与处理插件库htree的使用
Golang HTML节点树遍历与处理插件库htree的使用
Htree是一个用于遍历、导航、筛选和处理html.Node对象树的Go包。
基本用法
以下是一个使用htree包处理HTML节点的完整示例demo:
package main
import (
"fmt"
"golang.org/x/net/html"
"golang.org/x/net/html/atom"
"github.com/bobg/htree/v2"
"strings"
)
func main() {
// 示例HTML字符串
htmlStr := `
<!DOCTYPE html>
<html>
<head>
<title>Test Page</title>
</head>
<body>
<div class="content">
<h1>Hello World</h1>
<p>This is a paragraph</p>
<div id="footer" class="content-footer">
<span>Copyright 2023</span>
</div>
</div>
</body>
</html>
`
// 解析HTML
root, err := html.Parse(strings.NewReader(htmlStr))
if err != nil {
panic(err)
}
// 查找body元素
body := htree.FindEl(root, func(n *html.Node) bool {
return n.DataAtom == atom.Body
})
if body == nil {
panic("body element not found")
}
// 查找带有content类的div元素
contentDiv := htree.FindEl(body, func(n *html.Node) bool {
return n.DataAtom == atom.Div && htree.ElClassContains(n, "content")
})
if contentDiv != nil {
// 打印content div的内容
fmt.Println("Content Div found:")
for child := contentDiv.FirstChild; child != nil; child = child.NextSibling {
if child.Type == html.ElementNode {
fmt.Printf("- %s: %s\n", child.Data, htree.TextContent(child))
}
}
}
// 查找页脚元素
footer := htree.FindEl(contentDiv, func(n *html.Node) bool {
return n.DataAtom == atom.Div && htree.ElClassContains(n, "content-footer")
})
if footer != nil {
fmt.Println("\nFooter text:", htree.TextContent(footer))
}
}
主要功能
htree包提供了以下主要功能:
-
查找元素:使用
FindEl
函数在节点树中查找匹配条件的元素 -
类名检查:使用
ElClassContains
检查元素是否包含特定类名 -
文本内容提取:使用
TextContent
获取元素及其子元素的文本内容
示例输出
运行上述代码将输出:
Content Div found:
- h1: Hello World
- p: This is a paragraph
- div: Copyright 2023
Footer text: Copyright 2023
htree包简化了HTML节点树的遍历和处理,特别适合需要从HTML文档中提取特定内容的场景。
更多关于golang HTML节点树遍历与处理插件库htree的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang HTML节点树遍历与处理插件库htree的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang HTML节点树遍历与处理:htree库使用指南
htree是一个轻量级的Go语言HTML解析和操作库,它提供了一种简单高效的方式来遍历和处理HTML文档树。下面我将详细介绍htree的使用方法。
安装htree
首先安装htree库:
go get github.com/andybalholm/htree
基本用法
解析HTML文档
package main
import (
"fmt"
"github.com/andybalholm/htree"
"strings"
)
func main() {
html := `
<html>
<body>
<div id="content">
<p>Hello, World!</p>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
</body>
</html>
`
// 解析HTML
doc, err := htree.Parse(strings.NewReader(html))
if err != nil {
panic(err)
}
// 处理文档...
}
遍历节点树
htree提供了多种遍历节点树的方法:
// 深度优先遍历
func traverseDFS(n *htree.Node) {
fmt.Println("Node:", n.Data)
for c := n.FirstChild; c != nil; c = c.NextSibling {
traverseDFS(c)
}
}
// 查找特定元素
func findElements(doc *htree.Node, tagName string) []*htree.Node {
var result []*htree.Node
var traverse func(*htree.Node)
traverse = func(n *htree.Node) {
if n.Type == htree.ElementNode && n.Data == tagName {
result = append(result, n)
}
for c := n.FirstChild; c != nil; c = c.NextSibling {
traverse(c)
}
}
traverse(doc)
return result
}
// 使用示例
divs := findElements(doc, "div")
for _, div := range divs {
fmt.Println("Found div:", div)
}
操作节点
// 获取元素属性
func getAttribute(n *htree.Node, attrName string) string {
for _, attr := range n.Attr {
if attr.Key == attrName {
return attr.Val
}
}
return ""
}
// 修改元素内容
func setTextContent(n *htree.Node, text string) {
// 移除所有子节点
for n.FirstChild != nil {
n.RemoveChild(n.FirstChild)
}
// 添加文本节点
n.AppendChild(&htree.Node{
Type: htree.TextNode,
Data: text,
})
}
// 添加新元素
func addListItem(ul *htree.Node, text string) {
li := &htree.Node{
Type: htree.ElementNode,
Data: "li",
}
li.AppendChild(&htree.Node{
Type: htree.TextNode,
Data: text,
})
ul.AppendChild(li)
}
高级功能
CSS选择器查询
htree支持类似jQuery的CSS选择器查询:
import "github.com/andybalholm/htree/query"
func main() {
// ...解析文档代码...
// 使用CSS选择器查找元素
items := query.Find(doc, "ul li")
for _, item := range items {
fmt.Println("List item:", item.FirstChild.Data)
}
// 查找ID为content的div
contentDiv := query.FindOne(doc, "div#content")
if contentDiv != nil {
fmt.Println("Content div found")
}
}
修改和生成HTML
// 修改文档后生成HTML字符串
func modifyAndOutput(doc *htree.Node) string {
// 找到第一个p标签并修改内容
p := query.FindOne(doc, "p")
if p != nil {
setTextContent(p, "Modified content")
}
// 添加新的列表项
ul := query.FindOne(doc, "ul")
if ul != nil {
addListItem(ul, "Item 3")
}
// 生成HTML字符串
var buf bytes.Buffer
htree.Render(&buf, doc)
return buf.String()
}
实际应用示例
下面是一个完整的示例,演示如何解析HTML,修改内容并输出结果:
package main
import (
"bytes"
"fmt"
"github.com/andybalholm/htree"
"github.com/andybalholm/htree/query"
"strings"
)
func main() {
html := `
<html>
<head>
<title>Test Page</title>
</head>
<body>
<div id="content">
<h1>Welcome</h1>
<p>This is a test page.</p>
<ul class="items">
<li>First item</li>
<li>Second item</li>
</ul>
</div>
</body>
</html>
`
// 解析HTML
doc, err := htree.Parse(strings.NewReader(html))
if err != nil {
panic(err)
}
// 修改标题
title := query.FindOne(doc, "title")
if title != nil {
title.FirstChild.Data = "Modified Title"
}
// 在列表中添加新项目
ul := query.FindOne(doc, "ul.items")
if ul != nil {
newItem := &htree.Node{
Type: htree.ElementNode,
Data: "li",
}
newItem.AppendChild(&htree.Node{
Type: htree.TextNode,
Data: "Third item",
})
ul.AppendChild(newItem)
}
// 输出修改后的HTML
var buf bytes.Buffer
htree.Render(&buf, doc)
fmt.Println(buf.String())
}
htree是一个功能强大但轻量级的HTML处理库,非常适合需要解析和操作HTML文档的Go应用程序。它比标准库的html包提供了更多的便利方法,同时保持了高性能和低内存占用。