1. Home
  2. Docs
  3. golang
  4. 内置库(包-package)
  5. x-net-html

x-net-html

如何获取指定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 的解析树

Was this article helpful to you? Yes No

How can we help?