goquery的初步使用

前言

在解析、抓取html中部分数据时,为了快速定位数据,难免要使用jQuery相关。

在Go中有个实现类似jQuery功能的库,那就是goquery

本文主要介绍下goquery初步使用,尤其是对jQuery不熟的情况下,先对goquery有个初步的了解。

更多内容分享,欢迎关注公众号:Go开发笔记

goquery

goquery是基于Go标准库net/html及css选择器cascadia的基础实现的。

由于 net/html 解析器返回Node,而不是功能齐全的DOM树,jQuery的有状态操作函数(如height(), css(), detach())不支持。另外,net/html仅支持UTF-8编码,goquery也需要UTF-8编码,也就是说在使用goquery前,如果html的编码不是UTF-8,需要先对数据进行编码转换。在语法方面,goquery也尽可能地与jQuery使用相同的函数名。

goquery对外暴露两个struct:DocumentSelection,一个interface:Matcher。与 jQuery 不同,jQuery 作为 DOM 文档的一部分加载,因此对包含的文档进行行为,goquery 不知道要对哪个 HTML 文档进行操作。因此,它需要被告知Document。它持有根文档节点作为要操作的初始Selection值。

jQuery 通常具有同一函数的许多变体(无参数、selector字符串参数、jQuery 对象参数、DOM 元素参数等)。为了在goquery中公开具有可变空接口参数的同样特性的单个方法,按照以下命名约定使用静态类型标识:

  • 当 jQuery 等效项没有参数可以被调用时,它具有与无参数标识的 jQuery 相同的名称(例如:Prev()),并且具有一个selector字符串参数的版本称为XxxFiltered()(例如:PrevFiltered())

  • 当 jQuery 等效项需要一个参数时,selector字符串版本使用与 jQuery 相同的名称(例如:Is())

  • 接受 jQuery 对象作为参数的标,在 goquery 中定义为XxxSelection(),并且将*Selection对象作为参数(例如:FilterSelection())

  • 在 jQuery 中接受 DOM 元素作为参数的标识,在 goquery 中定义为XxxNodes(),并具有类型的可变参数*html.Node(例如:FilterNodes())

  • 在 jQuery 中接受函数作为参数的标识,在 goquery 中定义为XxxFunction(),并且将函数作为参数(例如:FilterFunction())

  • 可以用selector字符串调用的goquery方法有一个对应的版本,该版本采用Matcher接口,定义为XxxMatcher()

  • 不在 jQuery 中但在 Go 中有用的实用程序函数作为函数实现(以*Selection 为参数),以避免*Selection方法上的潜在命名冲突(为 jQuery 等效行为保留)。

安装

go get github.com/PuerkitoBio/goquery

使用go mod

require github.com/PuerkitoBio/goquery latest

使用

为了更简单的说明goquery的使用,我们以查找html中指定ul中的img为例,核心html内容如下:

<ul id="Ul_NAME" class="tt-thumb tt-clear">
	<li class="">
		<a href="#"><img src="xx0.jpg" /></a>
	</li>
	<li class="tb-selected">
		<a href="#"><img src="xx1.jpg" /></a>
	</li>
	<li class="">
		<a href="#"><img src="xx2.jpg" /></a>
	</li>
	...
</ul>

1.加载HTML document——NewDocumentFromReader

func NewDocumentFromReader(r io.Reader) (*Document, error)

通过io.Reader接口,可以加载本地/网络的html文档。

从网络加载示例如下:

// Request the HTML page.
  res, err := http.Get("http://metalsucks.net")
  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)
  }

  // Load the HTML document
  doc, err := goquery.NewDocumentFromReader(res.Body)
  if err != nil {
    log.Fatal(err)
  }

2.查找——Find

func (s *Selection) Find(selector string) *Selection

selector可以参考jQuery的使用

如果通过class查找,可以使用:

selector := “.tt-thumb.tt-clear li a img”

注意:如果class中存在空格,以.代替。

如果通过id查找则可以使用:

selector := “ul#Ul_NAME li a img”

使用id需要标明类型,并以#隔开。

使用示例:

doc.Find(selector)

3.匹配结果——Selection

func (s *Selection) Each(f func(int, *Selection)) *Selection

查找匹配后可能会有多个数据,使用Each可以迭代处理每个数据。

4.获取具体的属性——Attr

func (s *Selection) Attr(attrName string) (val string, exists bool)

要获取src,使用如下:

img, ok := selection.Attr("src")

5.完整示例:

// Request the HTML page.
  res, err := http.Get("http://xx.com")
  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)
  }

  // Load the HTML document
  doc, err := goquery.NewDocumentFromReader(res.Body)
  if err != nil {
    log.Fatal(err)
  }
  // Find 
  var imgs []string
  doc.Find("ul#Ul_NAME li a img").Each(func(i int, selection *goquery.Selection) {
    img, _ := selection.Attr("src")
    if img!="" {
        imgs = append(imgs,img)
    }
  }
  // Handle imgs
  ...

总结

本文主要介绍了goquery与jQuery的对照规则,以及从一个例子简单的说明goquery的使用。更深入的使用可以先从jQuery入手,熟悉jQuery后可以更熟练地使用goquery。

公众号

鄙人刚刚开通了公众号,专注于分享Go开发相关内容,望大家感兴趣的支持一下,在此特别感谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值