在做网页爬虫、HTML 数据抓取、自动化数据采集时,Go 语言中最常用的 HTML 解析库之一就是:
github.com/PuerkitoBio/goquery
它提供了类似 JavaScript 中 jQuery 的 DOM 操作方式,使得 HTML 解析变得非常直观和高效。
一、goquery 是什么
goquery 是一个 Go 语言的 HTML 文档解析和 DOM 操作库,由 Martin Angers 开发维护。
该库的设计理念是:
在 Go 中实现类似 jQuery 的 DOM 选择和操作方式。
核心特点:
- • 使用 CSS Selector 选择元素
- • API 风格类似 jQuery
- • 基于 Go 标准库 HTML 解析器
- • 操作简单且性能稳定
goquery 的底层解析器来自 Go 官方 HTML 解析库:
二、为什么使用 goquery
在 Go 中解析 HTML 有多种方式:
1 使用正则表达式
3 使用 goquery
其中 goquery 的优势非常明显。
使用正则解析 HTML:
- • 代码复杂
- • 容易出错
- • 不适合复杂结构
使用 html 原生解析:
- • API 偏底层
- • 操作较繁琐
goquery 提供了更高级的 DOM 查询接口,使 HTML 解析更接近前端开发体验。
三、安装 goquery
在 Go 项目中安装:
arduino
go get github.com/PuerkitoBio/goquery
导入库:
arduino
import "github.com/PuerkitoBio/goquery"
四、解析 HTML 文档
最基础的使用方式是解析 HTML 字符串或网页。
示例:
go
package main
import (
"fmt"
"strings"
"github.com/PuerkitoBio/goquery"
)
func main() {
html := `
<html>
<body>
<div class="title">Hello GoQuery</div>
</body>
</html>
`
doc, err := goquery.NewDocumentFromReader(strings.NewReader(html))
if err != nil {
panic(err)
}
text := doc.Find(".title").Text()
fmt.Println(text)
}
输出:
Hello GoQuery
五、从网页 URL 直接解析
goquery 提供了一个非常方便的函数,可以直接解析网页。
go
package main
import (
"fmt"
"github.com/PuerkitoBio/goquery"
)
func main() {
doc, err := goquery.NewDocument("https://example.com")
if err != nil {
panic(err)
}
fmt.Println(doc.Find("title").Text())
}
适用于:
- • 简单爬虫
- • 快速数据采集
不过在生产环境中通常建议使用自定义 HTTP 请求。
六、使用 CSS 选择器
goquery 支持常见的 CSS Selector。
例如:
选择 class
arduino
doc.Find(".product")
选择 id
arduino
doc.Find("#main")
选择标签
arduino
doc.Find("a")
组合选择
css
doc.Find("div.product a.title")
属性选择
css
doc.Find("img[data-src]")
这些写法与 jQuery 几乎一致。
七、遍历元素
在抓取数据时,经常需要遍历列表元素。
示例:
css
doc.Find(".item").Each(func(i int, s *goquery.Selection) {
title := s.Find(".title").Text()
link, _ := s.Find("a").Attr("href")
fmt.Println(title, link)
})
Each 会遍历所有匹配的元素。
八、读取元素属性
例如读取图片地址:
css
src, exists := doc.Find("img").Attr("src")
if exists {
fmt.Println(src)
}
常见属性:
- • href
- • src
- • data-*
九、修改 HTML 内容
goquery 不仅可以读取,还可以修改 DOM。
修改文本:
arduino
doc.Find(".title").SetText("New Title")
添加属性:
arduino
doc.Find("img").SetAttr("alt", "image")
删除元素:
scss
doc.Find(".ad").Remove()
十、获取完整 HTML
如果修改了 HTML,可以重新输出。
css
html, err := doc.Html()
也可以输出某个节点:
css
html, err := doc.Find(".content").Html()
十一、完整爬虫示例
下面是一个简单的网页抓取示例。
go
package main
import (
"fmt"
"net/http"
"github.com/PuerkitoBio/goquery"
)
func main() {
resp, err := http.Get("https://example.com")
if err != nil {
panic(err)
}
defer resp.Body.Close()
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
panic(err)
}
doc.Find("a").Each(func(i int, s *goquery.Selection) {
text := s.Text()
link, _ := s.Attr("href")
fmt.Println(text, link)
})
}
这个程序会抓取页面中所有链接。
十二、性能建议
在大规模爬虫项目中,可以做以下优化:
1 使用 HTTP 连接池
2 并发抓取多个页面
3 减少不必要的 DOM 查询
4 提前筛选 HTML 结构
goquery 本身性能不错,但 HTML 解析仍然属于 CPU 密集操作。
十三、典型应用场景
goquery 非常适合以下场景:
网页爬虫
SEO 数据采集
电商商品抓取
新闻内容采集
HTML 数据提取
自动化测试
例如抓取:
- • 商品标题
- • 商品价格
- • 图片链接
- • 文章正文
十四、常见问题
HTML 解析失败
原因通常是 HTML 不完整,可以先打印 HTML 内容确认。
网页需要 JavaScript
goquery 只能解析静态 HTML。
如果网页依赖 JavaScript 渲染,需要使用浏览器自动化工具,例如:
Chromium
或无头浏览器方案。
十五、总结
github.com/PuerkitoBio/goquery 是 Go 生态中最流行的 HTML 解析库之一。
主要优势:
- • jQuery 风格 API
- • 支持 CSS Selector
- • 使用简单
- • 适合爬虫开发
对于需要抓取网页结构化数据的 Go 项目来说,goquery 是一个非常高效且成熟的解决方案。