Go(Golang)中的HTML解析:工具与实践示例
Go(Golang)是一种由Google开发的编译型、静态类型语言。凭借其高性能、内置并发支持以及丰富的标准库,Go已成为网页抓取和HTML解析的最佳语言之一。在本文中,我们将介绍Go中用于处理HTML文档的主要库,提供代码示例并比较它们的功能。
为什么要在Go中解析HTML?
解析HTML对于从网页中提取数据(如新闻、价格、联系信息、搜索结果)是必不可少的。Go非常适合此任务,原因如下:
- 执行速度快(编译为机器码)
- 网络操作简便(内置
net/http包) - 通过专用库轻松解析DOM树
- 出色的多线程支持(goroutine和channel)
Go中用于HTML解析的主要库
1. net/html — 标准库
golang.org/x/net/html 是Go标准库中的底层HTML分词器和解析器。它提供了对解析过程的完全控制,但需要编写更多代码。
示例:从HTML文档中提取所有链接(<a href>)。
package main
import ( "fmt" "golang.org/x/net/html" "net/http" "log")
func main() { resp, err := http.Get("https://example.com") if err != nil { log.Fatal(err) } defer resp.Body.Close()
doc, err := html.Parse(resp.Body) if err != nil { log.Fatal(err) }
var f func(*html.Node) f = func(n *html.Node) { if n.Type == html.ElementNode && n.Data == "a" { for _, attr := range n.Attr { if attr.Key == "href" { fmt.Println(attr.Val) } } } for c := n.FirstChild; c != nil; c = c.NextSibling { f(c) } } f(doc)}优点:无需安装第三方包,完全控制。缺点:样板代码多,复杂选择器使用不便。
2. goquery — 类似jQuery的语法
github.com/PuerkitoBio/goquery 是Go中最流行的HTML解析库。它提供了类似jQuery的API:Find()、Each()、Attr()、Text()。
示例:从网站解析新闻标题。
package main
import ( "fmt" "github.com/PuerkitoBio/goquery" "log" "net/http")
func main() { resp, err := http.Get("https://habr.com/ru/news/") if err != nil { log.Fatal(err) } defer resp.Body.Close()
doc, err := goquery.NewDocumentFromReader(resp.Body) if err != nil { log.Fatal(err) }
doc.Find("h2.tm-article-snippet__title").Each(func(i int, s *goquery.Selection) { title := s.Find("a").Text() link, _ := s.Find("a").Attr("href") fmt.Printf("%d. %s 链接: %s", i+1, title, link) })}优点:语法简单,支持CSS选择器,文档丰富。缺点:不适合非常大的文档(全部加载到内存中)。
3. colly — 网页抓取框架
github.com/gocolly/colly 是一个强大的数据采集框架。它包含HTML解析(基于goquery)、请求队列管理、cookie处理、速率限制等功能。
示例:从网站首页收集所有链接,并在请求之间添加延迟。
package main
import ( "fmt" "github.com/gocolly/colly/v2")
func main() { c := colly.NewC