如何获取指定html标签(node)中的信息?
示例文件 hello.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello-html</title>
</head>
<body>
<div class="container">
<h1 class="title">this is title</h1>
<div class="list">
<ul>
<li><a href="https://www.baidu.com/">baidu</a></li>
<li><a href="https://www.qq.com">qq</a></li>
<li><a href="https://news.163.com">163</a></li>
</ul>
</div>
</div>
</body>
</html>
main.go
package main
import (
"bytes"
"fmt"
"io/ioutil"
"golang.org/x/net/html"
)
func main() {
//读取文件并解析
htmlFile := bytes.NewReader(resp)
doc, _ := html.Parse(htmlFile)
// 获取第一个html
html1 := doc.FirstChild
// 获取第一个HTML下的html
html2 := html1.NextSibling
// 获取第一个html下的head
head := html2.FirstChild
// 获取head中下面的第一个meta
meta1 := head.FirstChild
fmt.Println(meta1.NextSibling.Data)
meta2 := meta1.NextSibling
// 获取head下的第3个meta
meta3 := meta2.NextSibling.NextSibling
fmt.Println(meta3.Data)
// 获取head相邻的body
body1 := head.NextSibling.NextSibling
fmt.Println(body1.Data)
}
利用递归遍历html标签(node)获取a链接中的地址字符
links.go
package links
import(
"fmt"
"net/http"
"golang.org/x/net/html"
)
func Extract(url string) ([]string, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
resp.Body.Close()
return nil, fmt.Errorf("getting %s: %s", url, resp.Status)
}
doc, err := html.Parse(resp.Body)
resp.Body.Close()
if err != nil {
return nil, fmt.Errorf("parsing %s as HTML: %v", url, err)
}
// 下面是重要代码
var links []string
visitNode := func(n *html.Node) {
if n.Type == html.ElementNode && n.Data == "a" {
for _, a := range n.Attr {
if a.Key != "href" {
continue
}
link, err := resp.Request.URL.Parse(a.Val)
if err != nil {
continue
}
links = append(links, link.String())
}
}
}
forEachNode(doc, visitNode, nil)
return links, nil
}
// 递归遍历标签
func forEachNode(n *html.Node, pre, post func(n *html.Node)) {
if pre != nil {
pre(n)
}
// 如果获取当前标签下的子标签是nil, 寻找下一个相邻标签 直到遍历完全部的标签
for c := n.FirstChild; c != nil; c = c.NextSibling {
forEachNode(c, pre, post)
}
if post != nil {
post(n)
}
}
下面是官方文档翻译文档-By DeepL
包 html 实现了符合 HTML5 的标记器和解析器。
分词是通过为 io.Reader r 创建分词器来完成的。调用者有责任确保 r 提供 UTF-8 编码的 HTML。
type NodeType
const (
ErrorNode NodeType = iota
TextNode
DocumentNode
ElementNode
CommentNode
DoctypeNode
// RawNode nodes are not returned by the parser, but can be part of the
// Node tree passed to func Render to insert raw HTML (without escaping).
// If so, this package makes no guarantee that the rendered HTML is secure
// (from e.g. Cross Site Scripting attacks) or well-formed.
RawNode
)
type Node
type Node struct {
Parent, FirstChild, LastChild, PrevSibling, NextSibling *Node
Type NodeType
DataAtom atom.Atom
Data string
Namespace string
Attr []Attribute
}
一个节点由一个NodeType和一些数据(元素节点的标签名称,文本的内容)组成,是节点树的一部分。元素节点也可以有一个命名空间,并包含一个属性片断。
html.Parse
Parse returns the parse tree for the HTML from the given Reader.
Parse 返回来自给定阅读器的 HTML 的解析树