Go言語(golang) net/htmlを使ったHTMLのパース
net/htmlのドキュメントは以下
https://pkg.go.dev/golang.org/x/net/html?tab=doc
goquery(goでjQueryライクにHTMLを扱えるパッケージ)
https://github.com/PuerkitoBio/goquery
https://pkg.go.dev/github.com/PuerkitoBio/goquery?tab=doc
内部的には net/html と cascadia が使われている
goqueryを使えば簡単だけど、例えばアンカータグのhref属性のみ取得する
というような場合であれば net/htmlでもそんなに面倒じゃない。
package main import ( "bytes" "fmt" "log" "strings" "golang.org/x/net/html" "golang.org/x/net/html/atom" ) type Anchor struct { Text string Href string } func newAnchor(node *html.Node) *Anchor { var buff bytes.Buffer // A要素のテキストを取得 for c := node.FirstChild; c != nil; c = c.NextSibling { if c.Type == html.TextNode { buff.WriteString(c.Data) } } // href属性の値を取得 href := "" for _, v := range node.Attr { if v.Key == "href" { href = v.Val break } } return &Anchor{Text: buff.String(), Href: href} } func findAnchors(node *html.Node, collection *[]*Anchor) { for c := node.FirstChild; c != nil; c = c.NextSibling { if c.Type == html.ElementNode { if c.DataAtom == atom.A { *collection = append(*collection, newAnchor(c)) } findAnchors(c, collection) } } } func main() { r := strings.NewReader(` <html> <head></head> <body> <ul> <li><a href="https://example.com/foo">foo</a></li> <li><a href="https://example.com/bar">bar</a></li> <li><a href="https://example.com/baz">baz</a></li> </ul> </body> </html> `) node, err := html.Parse(r) if err != nil { log.Fatal(err) } var collection []*Anchor findAnchors(node, &collection) for _, a := range collection { fmt.Println(a.Text, ":", a.Href) } }