goquery使用
时间:2022-8-5 作者:smarteng 分类: Go语言
简介
goquery为Go语言带来了类似于jQuery的语法和一组特性。它基于Go的net / html包和CSS Selector库cascadia。由于net / html解析器返回节点,而不是功能齐全的DOM树,因此jQuery的有状态操作函数(如height(),css(),detach())已经停止。
此外,因为net / html解析器需要UTF-8编码,所以goquery也是如此:调用者有责任确保源文档提供UTF-8编码的HTML。有关执行此操作的各种选项
安装
go get github.com/PuerkitoBio/goquery
选择器
基于HTML Element 元素的选择器
就是基于a,p等这些HTML的基本元素进行选择。
使用方法 :使用语法为 dom.Find(“p”),匹配文档中所有的p标签。
ID 选择器
ID选择器是我们使用最频繁的,假如我们有2个p元素,其实我们只需要其中的一个,那么我们只需要给这个标记一个唯一的id即可,这样我们就可以使用id选择器,精确定位了。
使用方法 :id选择器以#开头,紧跟着元素id的值,使用语法为
dom.Find("#title") ,匹配文档中所有的 id=title的内容
如果多个标签的ID都是title,我们可以指定某一个标签,如dom.Find(“p#title”)
Class选择器
类选择跟ID选择器一样都是使用很频繁的,我们可以通过类选择器快速筛选到需要的内容。
使用方法 : id选择器以.开头,紧跟着元素class的值,使用语法为dom.Find(".content1"),匹配文档中所有的 id=title的元素。
类选择权器跟ID选择器一样,也可以指定某一个标签dom.Find(“div.content1”)
属性选择器
一个HTML元素都有自己的属性以及属性值,所以我们也可以通过属性和值筛选元素。
使用方法 :我们可以通过元素的属性和属性值来筛选数据,使用语法为dom.Find("p[class=content1],匹配文档中所有的 p标 签的class属性是content1的元素。
当然我们这里以class属性为例,还可以用其他属性,比如href等很多,自定义属性也是可以的。
更多选择器请参考:飞雪无痕 的 《golang goquery selector(选择器) 示例大全》
原文链接:https://www.flysnow.org/2018/01/20/golang-goquery-examples-selector.html
内置函数
1)类似函数的位置操作
Eq(index int) *Selection //根据索引获取某个节点集
First() *Selection //获取第一个子节点集
Last() *Selection //获取最后一个子节点集
Next() *Selection //获取下一个兄弟节点集
NextAll() *Selection //获取后面所有兄弟节点集
Prev() *Selection //前一个兄弟节点集
Get(index int) *html.Node //根据索引获取一个节点
Index() int //返回选择对象中第一个元素的位置
Slice(start, end int) *Selection //根据起始位置获取子节点集
2)循环遍历选择的节点
Each(f func(int, Selection)) Selection //遍历
EachWithBreak(f func(int, Selection) bool) Selection //可中断遍历
Map(f func(int, *Selection) string) (result []string) //返回字符串数组
3)检测或获取节点属性值
Attr(), RemoveAttr(), SetAttr() //获取,移除,设置属性的值
AddClass(), HasClass(), RemoveClass(), ToggleClass()
Html() //获取该节点的html
Length() //返回该Selection的元素个数
Text() //获取该节点的文本值
4)在文档树之间来回跳转(常用的查找节点方法
Children() //返回selection中各个节点下的孩子节点
Contents() //获取当前节点下的所有节点
Find() //查找获取当前匹配的元素
Next() //下一个元素
Prev() //上一个元素
使用示例:
这里示例是爬取一个电影网站中电影的信息:
网页地址为:http://www.haokongbu.com/dongzuopian/144016.html
c := colly.NewCollector()
c.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299"
///On every a element which has href attribute call callback
c.OnHTML("body", func(e *colly.HTMLElement) {
dom := e.DOM
//电影海报
poster, _ := dom.Find(".poster").Find("img").Attr("src")
intro := dom.Find(".intro")
//电影名称
movieName := intro.Find("h2").Text()
lis := intro.Find("ul").Find("li")
//电影豆瓣评分
score := lis.Eq(0).Find("font").Text()
//时长
length := lis.Eq(1).Find("span").Text()
//导演
doctor := lis.Eq(2).Find("span").Text()
//年代
time := lis.Eq(3).Find("span").Text()
//地区
country := lis.Eq(4).Find("span").Text()
//类型
category := lis.Eq(5).Find("span").Text()
//语言
language := lis.Eq(6).Find("span").Text()
//编剧
scriptwriter := lis.Eq(7).Find("span").Text()
//影片别名
alias := lis.Eq(8).Find("span").Text()
//上映时间
releaseDate := lis.Eq(10).Find("span").Text()
//主演
actors := lis.Eq(11).Find("span").Text()
//关键字
keyword := lis.Eq(12).Find("span").Text()
baiduyunaddres := dom.Find(".baiduyunaddres").Eq(0)
//下载地址
downloadInfos := make([]DownLoadInfo, 0)
//在线播放地址
onlinePlayUrls := make([]OnlinePlayUrl, 0)
baiduyunaddres.Find("ul").Find("li").Each(func(i int, selection *goquery.Selection) {
way := selection.Find("span").Text()
href, _ := selection.Find("a").Attr("href")
title := selection.Find("a").Text()
if way == "在线" {
if href != "" {
playUrl := "https://www.haokongbu.com" + href
movieUrl := GetPlayUrl(playUrl)
onlinePlayUrls = append(onlinePlayUrls, OnlinePlayUrl{Title: title, MovieUrl: movieUrl})
}
//fmt.Println(playUrl)
} else {
downloadInfos = append(downloadInfos, DownLoadInfo{Way: way, Title: title, Href: href})
}
})
//电影简介
introduction, _ := dom.Find(".movietext").Find(".introduction").Html()
})
c.Visit("http://www.haokongbu.com/dongzuopian/144016.html")
goquery简介
goquery
实现了与 jQuery
类似的功能,包括使用可链接语法操纵和查询HTML文档。
它为Go语言带来了一种类似于 jQuery
的语法和函数。它基于Go的 net/html
包和CSS Selector库cascadia
。由于 net/html
解析器返回的是节点,而不是功能完整的 DOM
树,因此 jQuery
的有状态操作函数(例如 height()
, css()
, detach()
)已被省去。
net/html
解析器读取UTF-8
编码的文件(Go默认处理的就是UTF-8编码的文件),所以要确保被操作的源文档是UTF-8
编码的HTML
文件。有关如何执行此操作的各种选项,可查看Github仓库的Wiki。
在语法上,它尽可能接近 jQuery
,并在可能的情况下使用相同的方法名称,并且具有熟悉而类似的可链接接口。
jQuery
是一个广受欢迎的库,因此,参照和遵循它的API来编写类似的HTML
操作库会更好,这也是Go语言的精神(如fmt
包的实现),即使jQuery
有些方法看起来不那么直观(如index()
等)。
注意: goquery
以来 net/html
库,因此需要 Go1.1+
以上版本。
根据方法的不同类型分类到不同的文件中,三个点( ...
)表示该方法可以重载(overloads)。
array.go
(数组类位置选择操作):Eq()
,First()
,Get()
,Index...()
,Last()
,Slice()
expend.go
(扩充选择的集合):Add...()
,AndSelf()
,Union()
是AddSelection()
的别名filter.go
(过滤选择的集合):End()
,Filter...()
,Has...()
,Intersection()
是FilterSelection()
的别名,Not...()
iteration.go
(遍历节点):Each()
,EachWithBreak()
,Map()
manipulation.go
(修改HTML):After...()
,Append...()
,Before...()
,Clone()
,Empty()
,Prepend...()
,Remove...()
,ReplaceWith...()
,Unwrap()
,Wrap...()
,WrapAll...()
,WrapInner...()
property.go
(检查并获取节点属性值):Attr*()
,RemoveAttr()
,SetAttr()
,AddClass(), HasClass(), RemoveClass(), ToggleClass()
,Html()
,Length()
,Size()
是Length()
的别名,Text()
query.go
(判断节点身份):Contains()
,Is...()
traversal.go
(遍历HTML
文档树):,Children...()
,Contents()
,Find...()
,Next...()
,Parent[s]...()
,Prev...()
,Siblings...()
type.go
(goquery
公开的类型):Document
,Selection
,Matcher
utilities.go
(辅助函数,而不是* Selection
的方法,这不是jQuery
的一部分):NodeName
,OuterHtml
了解了具体的功能和提供的函数,具体就是在调用上面函数的时候提供CSS选择器作为参数。
CSS选择器
goquery使用样例
大部分都和上面的一样,比较特殊的列在下面。
选择器 | 说明 |
---|---|
Find(“div[lang]") | 筛选含有lang属性的div元素 |
Find(“div[lang=zh]") | 筛选lang属性为zh的div元素 |
Find(“div[lang!=zh]") | 筛选lang属性不等于zh的div元素 |
Find(“div[lang¦=zh]") | 筛选lang属性为zh或者zh-开头的div元素 |
Find(“div[lang*=zh]") | 筛选lang属性包含zh这个字符串的div元素 |
Find(“div[lang~=zh]") | 筛选lang属性包含zh这个单词的div元素,单词以空格分开的 |
Find(“div[lang$=zh]") | 筛选lang属性以zh结尾的div元素,区分大小写 |
Find(“div[lang^=zh]") | 筛选lang属性以zh开头的div元素,区分大小写 |
下面的操作在选择器选出的内容中再进行过滤。
类别 | 描述 | 语法 | 例子 |
---|---|---|---|
内容过滤器 | 筛选出的元素要包含指定的文本 | Find(":contains(text)") |
- Find("div:contains(DIV2)") ,选择出的 div 元素要包含 DIV2 文本- Find(":empty) ,选出的元素都不能有子元素- Find("span:has(div)") ,选出包含 div 的 span 元素,与 has 类似的 contains |
:first-child / :last-child |
选出其父元素的第一个子元素 | Find(":first-child") |
Find("div:first-child") |
:first-of-type / :last-of-type |
选出其父元素的第一个该类型子元素 | Find(":first-of-type") |
Find("div:first-of-type") |
:nth-child(n) / :nth-last-child(n) |
选出其父元素的第n个子元素 | Find(":nth-child(n)") |
Find("div:nth-child(3)") |
:nth-of-type(n) / :nth-last-of-type(n) |
选出其父元素的第n个该类型子元素 | Find(":nth-of-type(n)") |
Find("div:nth-of-type(3)") |
:only-child |
选出其父元素中只有该元素(数量唯一)的子元素 | Find(":only-child") |
Find("div:only-child") |
:only-of-type |
选出其父元素中只有该类型元素(类型唯一)的子元素 | Find(":only-of-type") |
Find("div:only-of-type") |