goquery:HTML 解析器
简介
什么是 goquery?
goquery 是由 Go 实现的基于 Go 的 net/html
包和 CSS 选择器库 cascadia
的 HTML 解析库。
由于 net/html
解析器需要 UTF-8 编码,goquery 也同样需要,所以需要确保提供的 html 是 UTF-8 编码。
为什么用 goquery?
由于 net/html
解析器返回的是节点,而不是功能齐全的 DOM 树,所以在使用的过程中 goquery 可以提供更便利的操作。
快速上手
我们先对微博热搜进行一个简单的解析,打印当日的热搜排名标题以及热度。
package main
import (
"fmt"
"github.com/PuerkitoBio/goquery"
"log"
"net/http"
)
type Data struct {
number string
title string
heat string
}
func main() {
// 爬取微博热搜网页
res, err := http.Get("https://s.weibo.com/top/summary")
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
if res.StatusCode != 200 {
log.Fatalf("status code error: %d %s", res.StatusCode, res.Status)
}
//将html生成goquery的Document
dom, err := goquery.NewDocumentFromReader(res.Body)
if err != nil {
log.Fatalln(err)
}
var data []Data
// 筛选class为td-01的元素
dom.Find(".td-01").Each(func(i int, selection *goquery.Selection) {
data = append(data, Data{number: selection.Text()})
})
// 筛选class为td-02的元素下的a元素
dom.Find(".td-02>a").Each(func(i int, selection *goquery.Selection) {
data[i].title = selection.Text()
})
// 筛选class为td-02的元素下的span元素
dom.Find(".td-02>span").Each(func(i int, selection *goquery.Selection) {
data[i].heat = selection.Text()
})
fmt.Println(data)
}
过滤器示例
基于 HTML Element 元素的选择器
使用 Element 名称作为选择器,如 dom.Find("div")
。
dom.Find("div").Each(func (i int, selection *goquery.Selection) {
fmt.Println(selection.Text())
})
ID 选择器
以 # 加 id 值作为选择器
dom.Find("#id").Each(func (i int, selection *goquery.Selection) {
fmt.Println(selection.Text())
})
Class 选择器
以 . 加 class 值为选择器
dom.Find(".class").Each(func (i int, selection *goquery.Selection) {
fmt.Println(selection.Text())
})
上面的示例可以看出,goquery 的选择器与 jQuery 的选择器用法无异,在这里就不继续赘述了,同学们可以自行探索。
常用节点属性值
Html()
获取该节点的 html
dom.Find("table").Each(func (i int, selection *goquery.Selection) {
fmt.Println(selection.Html())
})
Text()
获取该节点的文本值
dom.Find(".td-02>a").Each(func (i int, selection *goquery.Selection) {
fmt.Println(selection.Text())
})
Attr()
返回节点的属性值以及该属性是否存在的布尔值
dom.Find("#execution").Each(func (i int, selection *goquery.Selection) {
value[i], ok = selection.Attr("value")
})
Length()
返回该 Selection 的元素个数
dom.Find("td").Length()