当前位置: 首页 > news >正文

上海建设安全生产协会网站脑叶公司

上海建设安全生产协会网站,脑叶公司,wordpress关闭多版本,百度竞价排名是什么方式目录 goquery 是什么 goquery 能用来干什么 goquery quick start 玩转goquery.Find() 查找多个标签 Id 选择器 Class 选择器 属性选择器 子节点选择器 内容过滤器 goquery 源码分析 图解源码 总结 goquery 简介 goquery是一款基于Go语言的HTML解析库#xff0c;…目录 goquery 是什么 goquery 能用来干什么 goquery quick start 玩转goquery.Find() 查找多个标签 Id 选择器 Class 选择器 属性选择器 子节点选择器 内容过滤器 goquery 源码分析 图解源码 总结 goquery 简介 goquery是一款基于Go语言的HTML解析库它使用了类似于jQuery的语法使得在Go语言中进行HTML解析变得更加方便。使用goquery开发者可以在HTML文档中轻松地查询、遍历和操作文档中的各种元素和属性。 具体而言goquery可以用来实现如下功能 在HTML文档中查找、筛选和遍历元素获取元素的属性、文本内容、HTML内容等信息对元素进行添加、修改、删除等操作在HTML文档中执行CSS选择器操作支持链式调用可以方便地进行多个操作组合 总的来说goquery是一款非常实用的HTML解析工具它可以大大简化开发者在Go语言中进行HTML解析的工作。 goquery quick start Document 是 goquery 包的核心类之一创建一个 Document 是使用 goquery 的第一步 type Document struct {*SelectionUrl *url.URLrootNode *html.Node }func NewDocumentFromNode(root *html.Node) *Document func NewDocument(url string) (*Document, error) func NewDocumentFromReader(r io.Reader) (*Document, error) func NewDocumentFromResponse(res *http.Response) (*Document, error) 通过源码可以知道 Document 继承了 Selection先不管 Selection 是什么除此之外最重要的是rootNode它是 HTML 的根节点Url这个字段作用不大在使用NewDocument和NewDocumentFromResponse时会对该字段赋值。 拥有Document类后我们就可以利用从Selection类继承的Find函数来获得自己想要的数据比如我们想拿到 func TestFind(t *testing.T) {html : bodydivDIV1/divdivDIV2/divspanSPAN/span/bodydom, err : goquery.NewDocumentFromReader(strings.NewReader(html))if err ! nil {log.Fatalln(err)}dom.Find(div).Each(func(i int, selection *goquery.Selection) {fmt.Println(selection.Text())}) } ------------运行结果--------------RUN TestFind DIV1 DIV2 玩转goquery.Find() goquery 提供了大量的函数个人认为最重要的是Find函数把它用好了才能快速从大量文本中筛选出我们想要的数据下面这一章主要展示使用Find函数的各种姿势 查找多个标签 使用,逗号找出多个标签 func TestMultiFind(t *testing.T) {html : bodydivDIV1/divdivDIV2/divspanSPAN/span/bodydom, err : goquery.NewDocumentFromReader(strings.NewReader(html))if err ! nil {log.Fatalln(err)}dom.Find(div,span).Each(func(i int, selection *goquery.Selection) {fmt.Println(selection.Text())}) } ------------运行结果--------------RUN TestMultiFind DIV1 DIV2 SPAN Id 选择器 使用#代表 Id 选择器。 func TestFind_IdSelector(t *testing.T) {html : bodydiv iddiv1DIV1/divdivDIV2/divspanSPAN/span/bodydom, err : goquery.NewDocumentFromReader(strings.NewReader(html))if err ! nil {log.Fatalln(err)}dom.Find(#div1).Each(func(i int, selection *goquery.Selection) {fmt.Println(selection.Text())}) } ------------运行结果--------------RUN TestFind_IdSelector DIV1 Class 选择器 使用.代表 Class 选择器。 func TestFind_ClassSelector(t *testing.T) {html : bodydivDIV1/divdiv classnameDIV2/divspanSPAN/span/bodydom, err : goquery.NewDocumentFromReader(strings.NewReader(html))if err ! nil {log.Fatalln(err)}dom.Find(.name).Each(func(i int, selection *goquery.Selection) {fmt.Println(selection.Text())}) } ------------运行结果--------------RUN TestFind_ClassSelector DIV2 属性选择器 使用[]代表属性选择器。 func TestFind_AttributeSelector(t *testing.T) {html : bodydivDIV1/divdiv langzhDIV2/divspanSPAN/span/bodydom, err : goquery.NewDocumentFromReader(strings.NewReader(html))if err ! nil {log.Fatalln(err)}dom.Find(div[lang]).Each(func(i int, selection *goquery.Selection) {fmt.Println(selection.Text())}) } ------------运行结果--------------RUN TestFind_AttributeSelector DIV2 属性选择器也支持表达式过滤比如 func TestFind_AttributeSelector_2(t *testing.T) {html : bodydivDIV1/divdiv langzhDIV2/divdiv langenDIV3/divspanSPAN/span/bodydom, err : goquery.NewDocumentFromReader(strings.NewReader(html))if err ! nil {log.Fatalln(err)}dom.Find(div[langzh]).Each(func(i int, selection *goquery.Selection) {fmt.Println(selection.Text())}) } ------------运行结果--------------RUN TestFind_AttributeSelector_2 DIV2 选择器说明Find(“div[lang]”)筛选含有lang属性的div元素Find(“div[langzh]”)筛选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(div[id][langzh]) 子节点选择器 使用代表子节点选择器。 func TestFind_ChildrenSelector(t *testing.T) {html : bodydivDIV1/divdivDIV2/divspanSPAN/span/bodydom, err : goquery.NewDocumentFromReader(strings.NewReader(html))if err ! nil {log.Fatalln(err)}dom.Find(bodyspan).Each(func(i int, selection *goquery.Selection) {fmt.Println(selection.Text())}) } ------------运行结果--------------RUN TestFind_ChildrenSelector SPAN 此外表示相邻表示共有(父节点相同即为true) 内容过滤器 过滤文本 使用:contains($text)来过滤字符串。 func TestFind_ContentFilter_Contains(t *testing.T) {html : bodydivDIV1/divdivDIV2/divspanSPAN/span/bodydom, err : goquery.NewDocumentFromReader(strings.NewReader(html))if err ! nil {log.Fatalln(err)}dom.Find(div:contains(V2)).Each(func(i int, selection *goquery.Selection) {fmt.Println(selection.Text())}) } ------------运行结果--------------RUN TestFind_ContentFilter_Contains DIV2 过滤节点 func TestFind_ContentFilter_Has(t *testing.T) {html : bodyspanSPAN1/spanspanSPAN2divDIV/div/span/bodydom, err : goquery.NewDocumentFromReader(strings.NewReader(html))if err ! nil {log.Fatalln(err)}dom.Find(span:has(div)).Each(func(i int, selection *goquery.Selection) {fmt.Println(selection.Text())}) } ------------运行结果--------------RUN TestFind_ContentFilter_Has SPAN2 DIV 此外还有:first-child、:first-of-type过滤器分别可以筛选出第一个子节点、第一个同类型的子节点。 相应的:last-child、:last-of-type、:nth-child(n)、:nth-of-type(n)用法类似不做过多解释。 goquery 源码分析 Find函数 是 goquery 最核心的函数 func (s *Selection) Find(selector string) *Selection {return pushStack(s, findWithMatcher(s.Nodes, compileMatcher(selector))) } Find函数 的功能由pushStack函数实现 func pushStack(fromSel *Selection, nodes []*html.Node) *Selection {result : Selection{nodes, fromSel.document, fromSel}return result } 该函数就是拿着nodes参数去创建一个新的 Selection 类构建一个 Selection 链表。 无论是函数命名pushStack还是 Selection 类的字段都可以证实上面的判断 type Selection struct {Nodes []*html.Nodedocument *DocumentprevSel *Selection // 上一个节点的地址 } 现在焦点来到了pushStack函数的nodes参数nodes参数是什么直接决定了我们构建了一个怎样的链表、决定了Find函数的最终返回值这就需要我们研究下findWithMatcher函数的实现 func findWithMatcher(nodes []*html.Node, m Matcher) []*html.Node {return mapNodes(nodes, func(i int, n *html.Node) (result []*html.Node) {for c : n.FirstChild; c ! nil; c c.NextSibling {if c.Type html.ElementNode {result append(result, m.MatchAll(c)...)}}return}) } findWithMatcher函数 的功能由mapNodes函数实现 func mapNodes(nodes []*html.Node, f func(int, *html.Node) []*html.Node) (result []*html.Node) {set : make(map[*html.Node]bool)for i, n : range nodes {if vals : f(i, n); len(vals) 0 {result appendWithoutDuplicates(result, vals, set)}}return result } mapNodes函数把参数f的返回值[]*html.Node做去重处理所以重点在于这个参数f func(int, *html.Node) []*html.Node的实现 func(i int, n *html.Node) (result []*html.Node) {for c : n.FirstChild; c ! nil; c c.NextSibling {if c.Type html.ElementNode {result append(result, m.MatchAll(c)...)}}return }![img.png](img.png) 函数遍历html.Node节点并利用MatchAll函数筛选出想要的数据 type Matcher interface {Match(*html.Node) boolMatchAll(*html.Node) []*html.NodeFilter([]*html.Node) []*html.Node }func compileMatcher(s string) Matcher {cs, err : cascadia.Compile(s)if err ! nil {return invalidMatcher{}}return cs } MatchAll函数由Matcher接口定义而compileMatcher(s string)恰好通过利用cascadia库返回一个Matcher实现类其参数s就是我们上文提到的匹配规则比如dom.Find(div) 图解源码 使用Find函数时goquery 做了什么 总结 本文主要介绍了 goquery 最核心的Find函数的用法及其源码实现其实除了Find函数goquery 还提供了大量的函数帮助我们过滤数据因为函数众多且没那么重要本人就没有继续研究以后有机会再深入研究下。
http://www.hkea.cn/news/14355573/

相关文章:

  • 建设科技信息 网站建设电子商务企业网站建设发展论文
  • 靖江网站建设公司dw制作网站网页模板
  • 芜湖镜湖区做网站公司东营远见网站建设公司
  • 建设个人网站多少钱河南省汝州市建设网站
  • 做二手房网站食堂网站建设方案
  • 技术支持 桂林网站建设优秀企业网站案例
  • 个人网站怎么盈利手机商城网站设计
  • 网站建设项目流程图广州网站建设高端
  • 口碑好网站建设多少钱深圳wap网站建设
  • 网站域名 空间中国施工企业协会官网
  • 公司网站建设怎么做账微网站预约网站开发
  • 企业网站制作哪家好王也天与葛优
  • jquery网站开发教程织梦网站提示保存目录数据时报
  • php网站开发实例教程简介北京网站建设外包公司
  • 郑州企业网站制作怎么做国内做网站的大公司有哪些
  • 专业管道疏通网站建设图片犀牛云做网站推广怎么样
  • 网站推广软件赚钱难吗?重庆可视化网站制作
  • 网站后台 请示网页设计学编程吗
  • 做网站代理拉别人网站品牌营销策略包括哪些内容
  • 山东专业的网站建设建设网站之前都需要准备什么东西
  • 网站管理员权限设置权限设置顺企网杭州网站建设
  • 如何做展示型网站四川省建设厅网站
  • 上海网站建设公司 红威新网站前期如何做seo
  • 大连网站推广价格王者荣耀是哪家公司开发的
  • 世界著名办公室设计太原网站搜索优化
  • cms网站后台管理系统官方网站作用
  • 高水平网站运营托管怎么在搜索引擎里做网站网页
  • 给网站做视频怎么赚钱室外绿化工程施工方案久久建筑网
  • 常州网站建设哪家好程序员一般找哪种女人
  • 网页设计与网站建设简答题做电容的网站