在 goquery 中,选择器遵循标准 CSS 选择器规则。如果要精确匹配同时包含多个类名的元素,正确的做法是将多个类选择器连续写在一起,中间不使用空格或逗号。这样浏览器或 goquery 才会理解为“且”的关系,而不是“或”。

多类名精确匹配的基本写法
假设我们有如下 HTML 片段,其中某些 div 同时带有 user 和 active 两个类,有些只带其中一个:
<div class="user active">张三</div> <div class="user">李四</div> <div class="active">公告</div> <div class="user active admin">管理员</div>
如果我们只想选出同时拥有 user 和 active 类的元素,应使用 .user.active 这种连写形式。下面是用 goquery 实现的完整示例:
package main
import (
"fmt"
"strings"
"github.com/PuerkitoBio/goquery"
)
func main() {
html := `<div class="user active">张三</div>
<div class="user">李四</div>
<div class="active">公告</div>
<div class="user active admin">管理员</div>`
doc, err := goquery.NewDocumentFromReader(strings.NewReader(html))
if err != nil {
panic(err)
}
// 精确匹配同时包含 user 和 active 类的元素
doc.Find(".user.active").Each(func(i int, s *goquery.Selection) {
fmt.Println(s.Text())
})
}
运行以上代码,输出结果为:
- 张三
- 管理员
可以看到,只带 user 或只带 active 的节点都被排除了。
常见错误写法
下面是新手常犯的几种错误:
| 错误写法 | 实际含义 |
|---|---|
.user, .active | 匹配 class 含 user 或 active 的任意元素 |
.user .active | 匹配 user 类元素内部的 active 类后代元素 |
.useractive | 匹配 class 名为 useractive 的元素 |
使用属性选择器作为替代方案
如果类名顺序不固定或动态生成,也可以用属性选择器达到类似效果:
// 匹配 class 属性中同时包含 user 和 active 词的元素
doc.Find("div[class~='user'][class~='active']").Each(func(i int, s *goquery.Selection) {
fmt.Println(s.Text())
})
其中 [class~='user'] 表示 class 属性中以空格分隔的列表中包含 user 这个词。
小结
在 goquery 里精确匹配多类名元素,记住把类选择器连写即可,如 .a.b.c。避免用逗号或空格分隔,也不要拼成单个长类名。掌握这一点,网页解析时的元素定位会更加准确。