如何在 Go 中解析和生成 HTML

如何在 Go 中解析和生成 HTML

解析是分析和解釋文檔的結構。解析過程可能包括從文檔中提取特定元素、屬性或數據,並在遵循特定標准或規則的同時驗證文檔格式是否正確。解析主要用於從網頁中提取數據或在將網頁顯示給用戶之前操縱網頁的結構。

Go 提供了用於處理文檔的包,包括網頁中常用的 HTML 和 XML 格式。html包提供了標記化和解析 HTML的功能。

HTML 包

html包提供了一個符合 HTML5的分詞器和解析器,用於解析和操作 HTML 文檔、遍歷解析樹和操作樹結構。html包是Go標準庫的內置包。

html包的主要特性之一是Parse函數,它可以解析 HTML 文檔並返回解析樹的根節點,您可以從中使用FirstChildNextSibling等函數來導航樹並從文檔中提取信息。該包還提供了用於解析 HTML 文檔片段的ParseFragment函數。

EscapeString函數可以方便地轉義字符串中的特殊字符,以便更安全地包含在 HTML 中您可以使用此功能通過將特殊字符轉換為相應的 HTML 實體來防止跨站點腳本 (XSS) 攻擊。

要開始使用html包,您可以將該包導入到您的 Go 項目文件中。

import "golang.org/x/net/html"

html包不提供任何生成 HTML 的函數。相反,您可以使用 html/template 包,它提供了一組用於生成 HTML 模板的函數。html/template包提供了一個函數template.HTMLEscape用於將HTML 的轉義版本寫入響應編寫器。

html/template包也是標準庫的一部分,下面介紹如何導入該包。

import "html/template"

html包是 Go 生態中使用最廣泛的模板包,支持各種操作和數據類型。

在 Go 中解析 HTML

html包的Parse函數有助於解析 HTML 文本和文檔。Parse函數接受一個io.Reader實例,因為它是包含文件文檔的第一個參數和一個 * html.Node實例,它是 HTML 文檔的根節點

下面介紹如何使用Parse函數解析網頁並返回網頁上的所有 URL。

import (
    "fmt"
    "golang.org/x/net/html"
    "net/http"
)

func main() {
    // Send an HTTP GET request to the example.com web page
    resp, err: = http.Get("https://www.example.com")
    if err! = nil {
        fmt.Println("Error:", err)
        return
    }
    defer resp.Body.Close()

    // Use the html package to parse the response body from the request
    doc, err: = html.Parse(resp.Body)
    if err! = nil {
        fmt.Println("Error:", err)
        return
    }

    // Find and print all links on the web page
    var links []string
    var link func(*html.Node)
    link = func(n *html.Node) {
        if n.Type == html.ElementNode && n.Data == "a" {
            for _, a: = range n.Attr {
                if a.Key == "href" {
                    // adds a new link entry when the attribute matches
                    links = append(links, a.Val)
                }
            }
        }

        // traverses the HTML of the webpage from the first child node
        for c: = n.FirstChild; c! = nil; c = c.NextSibling {
            link(c)
        }
    }
    link(doc)

    // loops through the links slice
    for _, l: = range links {
        fmt.Println("Link:", l)
    }
}

main函數通過http包的Get函數向網站發送HTTP GET請求,獲取頁面響應體。html包的Parse函數解析響應體並返回 HTML 文檔。

links變量是保存網頁 URL 的字符串片段。link函數接收指向html包的Node方法的指針引用,節點的屬性實例的Key方法返回指定屬性(在本例中為href)中包含的數據。該函數使用NextSibling方法從FirstChild節點遍歷文檔以打印網頁上的每個 URL。最後,for 循環打印鏈接切片中的所有 URL。

這是操作的結果。

從網頁中檢索鏈接的結果

在 Go 中生成 HTML

html/template包提供了一組函數,用於安全高效地解析和執行 HTML 模板。該包旨在與html包結合使用,後者提供解析和操作 HTML 的功能。

您可以使用html/template包為服務器端呈現生成 HTML 。生成 HTML 對於發送電子郵件、服務器端前端渲染等許多用例都很方便。您可以使用內置的 Go 數據類型(如地圖和結構)來交互和操作網頁的 HTML。

您需要了解 Go HTML 模板語法才能使用html/template包成功生成 HTML。

import (
    "html/template"
    "os"
)

type webPage struct {
    Title string
    Heading string
    Text string
}

func main() {
    // Define the template
    tmpl: = `
<!DOCTYPE html>
<html>
<head>
    <title>{{.Title}}</title>
</head>
<body>
    <h1>{{.Heading}}</h1>
    <p>{{.Text}}</p>
</body>
</html>`

    // Define the data to be used in the template
    web: = webPage{
        Title: "An Example Page",
        Heading: "Welcome to my website!",
        Text: "This is the home page of my website.",
    }

    // Create a new template and parse the template string
    t, err: = template.New("webpage").Parse(tmpl)
    if err! = nil {
        panic(err)
    }

    // Execute the template and write the result to stdout
    err = t.Execute(os.Stdout, web)
    if err! = nil {
        panic(err)
    }
}

tmpl變量保存HTML 字符串。HTML 字符串使用 Go 模板語法來定義頁面標題、h1標題和一段文本。webPage結構使用TitleHeadingText字段定義網頁的數據字段。

模板包的New函數的Parse方法使用模板字符串創建並解析新模板。新模板實例的Execute函數使用結構實例中的數據執行模板,並將結果返回到標準輸出(在本例中,它將結果打印到控制台)。

html生成的結果

使用 Go 構建 Web 應用程序

學習使用 Go 解析和生成 HTML 是朝著使用 Go 構建更複雜的 Web 應用程序的正確方向邁出的一步。您可以使用 Gin 和 Echo 等框架以及 Gorilla Mux 和 Chi 路由器等路由器來構建 Web 應用程序的服務器端。

這些包建立在net/http包(Go 中用於與 HTTP 交互的內置包)之上,抽象了在 Go 中設置服務器和路由器的複雜性。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *