goquery

goquery

Go语言实现的jQuery风格HTML解析工具

goquery是Go语言生态中的一个HTML解析工具,其API设计借鉴了jQuery的语法风格。它构建在Go标准库的net/html包和第三方CSS选择器库cascadia之上,为开发者提供了简洁的链式调用方式和易于理解的方法名。goquery能够进行HTML文档的解析、元素查询、DOM遍历和修改等操作,广泛应用于网页内容抓取和数据分析场景。该库需要Go 1.18或更高版本,并保证与Go语言的最新两个版本保持兼容。

goqueryGo语言HTML解析CSS选择器jQueryGithub开源项目

goquery - 有点像那个j东西,只不过是用Go语言实现的

构建状态 Go参考 Sourcegraph徽章

goquery为Go语言带来了类似jQuery的语法和一系列功能。它基于Go的net/html包和CSS选择器库cascadia。由于net/html解析器返回的是节点而非完整的DOM树,jQuery的有状态操作函数(如height()、css()、detach())被省略了。

此外,由于net/html解析器要求UTF-8编码,goquery也是如此:确保源文档提供UTF-8编码的HTML是调用者的责任。有关各种实现方法,请参阅wiki

在语法上,它尽可能接近jQuery,尽可能使用相同的函数名,并保留了那种温暖而模糊的可链式接口。鉴于jQuery是如此流行的库,我觉得编写一个类似的HTML操作库最好遵循其API,而不是重新开始(与Go的fmt包精神相同),尽管它的一些方法不太直观(说的就是你,index()...)。

目录

安装

请注意,从goquery的v1.9.0版本开始,由于使用了泛型,需要Go 1.18+。对于之前的goquery版本,由于net/html依赖,需要Go 1.1+版本。正在进行的goquery开发在最新的两个Go版本上进行测试。

$ go get github.com/PuerkitoBio/goquery

(可选)运行单元测试:

$ cd $GOPATH/src/github.com/PuerkitoBio/goquery
$ go test

(可选)运行基准测试(警告:需要几分钟时间):

$ cd $GOPATH/src/github.com/PuerkitoBio/goquery
$ go test -bench=".*"

更新日志

请注意,goquery的API现已稳定,不会发生破坏性变更。

  • 2024-04-29 (v1.9.2) : 更新 go.mod 依赖。
  • 2024-02-29 (v1.9.1) : 改进 Map 函数和 Selection.Map 方法的内存分配和性能,更好地记录cascadia的差异(感谢 @jwilsson)。
  • 2024-02-22 (v1.9.0) : 添加通用 Map 函数,goquery现在需要Go 1.18+版本(感谢 @Fesaa)。
  • 2023-02-18 (v1.8.1) : 更新 go.mod 依赖,更新CI工作流程。
  • 2021-10-25 (v1.8.0) : 添加 Render 函数,将 Selection 渲染到 io.Writer(感谢 @anthonygedeon)。
  • 2021-07-11 (v1.7.1) : 更新go.mod依赖并添加dependabot配置(感谢 @jauderho)。
  • 2021-06-14 (v1.7.0) : 添加 SingleSingleMatcher 函数以优化首次匹配选择(感谢 @gdollardollar)。
  • 2021-01-11 (v1.6.1) : 修复在包含非元素节点的 Selection 上调用 {Prepend,Append,Set}Html 时的崩溃问题。
  • 2020-10-08 (v1.6.0) : 对所有处理html字符串的函数(AfterHtmlAppendHtml等)在容器节点的上下文中解析html。感谢 @thiemok@davidjwilkins 的贡献。
  • 2020-02-04 (v1.5.1) : 更新模块依赖。
  • 2018-11-15 (v1.5.0) : 支持Go模块(感谢 @Zaba505)。
  • 2018-06-07 (v1.4.1) : 添加 NewDocumentFromReader 示例。
  • 2018-03-24 (v1.4.0) : 废弃 NewDocument(url)NewDocumentFromResponse(response)
  • 2018-01-28 (v1.3.0) : 在 Slice 中添加 ToEnd 常量,用于选择到末尾(感谢 @davidjwilkins 提出问题)。
  • 2018-01-11 (v1.2.0) : 添加 AddBack* 并废弃 AndSelf(感谢 @davidjwilkins)。
  • 2017-02-12 (v1.1.0) : 添加 SetHtmlSetText(感谢 @glebtv)。
  • 2016-12-29 (v1.0.2) : 优化 Selection.Text 的内存分配(感谢 @radovskyb)。
  • 2016-08-28 (v1.0.1) : 优化大型文档的性能。
  • 2016-07-27 (v1.0.0) : 标记1.0.0版本。
  • 2016-06-15 : 无效的选择器字符串内部编译为永不匹配任何节点的 Matcher 实现(而不是引发panic)。例如,doc.Find("~") 返回一个空的 *Selection 对象。
  • 2016-02-02 : 添加 NodeName 实用函数,类似于DOM的 nodeName 属性。它返回选择中第一个元素的标签名,以及非元素节点的其他相关值(详见文档)。添加 OuterHtml 实用函数,类似于DOM的 outerHTML 属性(命名为 OuterHtml,小写以保持与现有 Selection 上的 Html 方法一致)。
  • 2015-04-20 : 添加 AttrOr 辅助方法,返回属性值或缺失时的默认值。感谢 piotrkowalczuk
  • 2015-02-04 : 添加更多操作函数 - Prepend* - 再次感谢 Andrew Stone
  • 2014-11-28 : 添加更多操作函数 - ReplaceWith*、Wrap* 和 Unwrap - 再次感谢 Andrew Stone
  • 2014-11-07 : 添加操作函数(感谢 Andrew Stone)和 *Matcher 函数,接收已编译的cascadia选择器而非选择器字符串,从而避免goquery通过 cascadia.MustCompile 调用可能引发的panic。这提高了性能(选择器可以编译一次并重复使用)并使错误处理更符合惯例(您可以处理cascadia的编译错误,而不是从panic中恢复,这一直困扰着我)。注意,实际期望的类型是 Matcher 接口,cascadia.Selector 实现了该接口。可以使用其他匹配器实现。
  • 2014-11-06 : 将net/html的导入路径更改为golang.org/x/net/html(参见 https://groups.google.com/forum/#!topic/golang-nuts/eD8dh3T9yyA)。当您使用 html.Node 调用goquery时,请确保更新代码以使用新的导入路径。
  • v0.3.2 : 添加 NewDocumentFromReader()(感谢jweir),允许从io.Reader创建goquery文档。
  • v0.3.1 : 添加 NewDocumentFromResponse()(感谢assassingj),允许从http响应创建goquery文档。
  • v0.3.0 : 添加 EachWithBreak(),允许通过返回false来跳出 Each() 循环。添加此函数而不是更改现有的 Each() 以避免破坏兼容性。
  • v0.2.1 : 使其可通过go get获取,现在go.net/html与Go1.0兼容(感谢@matrixik指出这一点)。
  • v0.2.0 :在Slice()中添加对负索引的支持。重大变更 移除了Document.RootDocument现在本身就是一个Selection(单一选择,即根元素,与之前的Document.Root相同)。添加了jQuery的Closest()方法。
  • v0.1.1 :添加基准测试作为重构的基线,重构Next...()和Prev...()方法以使用新的html包的链表特性(Next/PrevSibling, FirstChild)。性能显著提升(在某些情况下提升40%以上)。
  • v0.1.0 :初始发布。

API

与jQuery不同,goquery不是作为DOM文档的一部分加载,也不会作用于包含它的文档。因此,goquery需要被告知要操作哪个HTML文档。这就是Document类型的用途。它持有根文档节点作为初始的Selection值进行操作。

goquery暴露了两个结构体DocumentSelection,以及Matcher接口。jQuery通常对同一个函数有多个变体(无参数、选择器字符串参数、jQuery对象参数、DOM元素参数等)。goquery没有使用带有可变空接口参数的单一方法来提供相同的功能,而是使用静态类型的签名,遵循以下命名约定:

  • 当jQuery等效函数可以无参数调用时,无参数签名与jQuery使用相同的名称(如Prev()),而带选择器字符串参数的版本称为XxxFiltered()(如PrevFiltered()
  • 当jQuery等效函数必须有一个参数时,选择器字符串版本使用与jQuery相同的名称(如Is()
  • jQuery中接受jQuery对象作为参数的签名在goquery中定义为XxxSelection(),并接受*Selection对象作为参数(如FilterSelection()
  • jQuery中接受DOM元素作为参数的签名在goquery中定义为XxxNodes(),并接受*html.Node类型的可变参数(如FilterNodes()
  • jQuery中接受函数作为参数的签名在goquery中定义为XxxFunction(),并接受一个函数作为参数(如FilterFunction()
  • 可以用选择器字符串调用的goquery方法有对应的版本,接受Matcher接口,定义为XxxMatcher()(如IsMatcher()

在jQuery中不存在但在Go中有用的实用函数被实现为函数(接受*Selection作为参数),以避免与*Selection的方法(保留用于jQuery等效行为)可能发生的命名冲突。

完整的包参考文档可以在这里找到

请注意,Cascadia的选择器不一定匹配jQuery(Sizzle)支持的所有选择器。详情请参见cascadia项目。此外,选择器的工作方式更像DOM的querySelectorAll,而不是jQuery的匹配器 - 它们没有上下文匹配的概念(关于这意味着什么的一些具体例子,请参见此票据)。实践中,这通常不太重要,但值得一提。无效的选择器字符串会编译成一个无法匹配任何节点的Matcher。接受选择器字符串作为参数的各种函数的行为遵循这一事实,例如(其中~是一个无效的选择器字符串):

  • Find("~")返回一个空选择,因为选择器字符串不匹配任何内容。
  • Add("~")返回一个新的选择,持有与原始选择相同的节点,因为它没有添加任何节点(选择器字符串不匹配任何内容)。
  • ParentsFiltered("~")返回一个空选择,因为选择器字符串不匹配任何内容。
  • ParentsUntil("~")返回选择的所有父元素,因为选择器字符串没有匹配到任何元素来停止在顶层元素之前。

示例

wiki中查看一些技巧和窍门。

改编自example_test.go:

package main import ( "fmt" "log" "net/http" "github.com/PuerkitoBio/goquery" ) func ExampleScrape() { // 请求HTML页面 res, err := http.Get("http://metalsucks.net") if err != nil { log.Fatal(err) } defer res.Body.Close() if res.StatusCode != 200 { log.Fatalf("状态码错误: %d %s", res.StatusCode, res.Status) } // 加载HTML文档 doc, err := goquery.NewDocumentFromReader(res.Body) if err != nil { log.Fatal(err) } // 查找评论项目 doc.Find(".left-content article .post-title").Each(func(i int, s *goquery.Selection) { // 对于找到的每个项目,获取标题 title := s.Find("a").Text() fmt.Printf("评论 %d: %s\n", i, title) }) } func main() { ExampleScrape() }

相关项目

  • Goq,一个基于goquery和结构体标签的HTML反序列化和抓取库。
  • andybalholm/cascadia,goquery使用的CSS选择器库。
  • suntong/cascadia,cascadia CSS选择器库的命令行界面,用于测试选择器。
  • gocolly/colly,一个快速优雅的网络爬虫框架。
  • gnulnx/goperf,一个网站性能测试工具,也可以获取静态资源。
  • MontFerret/ferret,声明式网络爬虫。
  • tacusci/berrycms,一个现代简单易用的CMS,易于编写插件。
  • Dataflow kit,Go语言的Web爬虫框架。
  • Geziyor,一个快速的Go语言网络爬虫和抓取框架。支持JS渲染。
  • Pagser,一个简单、易用、可扩展、可配置的HTML解析器,基于goquery和结构体标签。
  • stitcherd,一个使用CSS选择器和DOM更新进行服务器端包含的服务器。
  • goskyr,一个易于配置的Go语言命令行爬虫。
  • goGetJS,一个用于提取、搜索和保存JavaScript文件的工具(可选无头浏览器)。
  • fitter,一个用于从JSON、XML、HTML和XPath格式页面中选择值的工具。
  • seltabl,一个类似ORM的包和支持语言服务器,用于从HTML中提取值。

支持

您可以通过以下几种方式支持本项目:

  • 使用它、为它加星、用它构建项目、传播它!
    • 如果您确实用它构建了开源或其他公开可见的项目,请告诉我,我可以将其添加到相关项目部分!
  • 提出问题以改进项目(注意:文档错别字和澄清也是问题!)
    • 在提出新问题之前请先搜索现有问题 - 可能已经有人提出过了。
  • 拉取请求:除非修复非常简单,否则请先在问题中讨论新代码。
    • 确保新代码经过测试。
    • 注意现有代码 - 破坏现有代码的PR很可能会被拒绝,除非它修复了一个严重问题。
  • 赞助开发者
    • 查看Github仓库顶部的赞助按钮
    • 或通过下方的BuyMeACoffee.com

<a href="https://www.buymeacoffee.com/mna" target="_blank"><img src="https://yellow-cdn.veclightyear.com/835a84d5/48cb6fbe-9bd6-482f-9c6d-aed4be48af82.png" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>

许可证

BSD 3-Clause许可证,与Go语言相同。Cascadia的许可证在这里

编辑推荐精选

TRAE编程

TRAE编程

AI辅助编程,代码自动修复

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
蛙蛙写作

蛙蛙写作

AI小说写作助手,一站式润色、改写、扩写

蛙蛙写作—国内先进的AI写作平台,涵盖小说、学术、社交媒体等多场景。提供续写、改写、润色等功能,助力创作者高效优化写作流程。界面简洁,功能全面,适合各类写作者提升内容品质和工作效率。

AI辅助写作AI工具蛙蛙写作AI写作工具学术助手办公助手营销助手AI助手
问小白

问小白

全能AI智能助手,随时解答生活与工作的多样问题

问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。

热门AI助手AI对话AI工具聊天机器人
Transly

Transly

实时语音翻译/同声传译工具

Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。

讯飞智文

讯飞智文

一键生成PPT和Word,让学习生活更轻松

讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。

AI办公办公工具AI工具讯飞智文AI在线生成PPTAI撰写助手多语种文档生成AI自动配图热门
讯飞星火

讯飞星火

深度推理能力全新升级,全面对标OpenAI o1

科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。

热门AI开发模型训练AI工具讯飞星火大模型智能问答内容创作多语种支持智慧生活
Spark-TTS

Spark-TTS

一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型

Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。

咔片PPT

咔片PPT

AI助力,做PPT更简单!

咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。

讯飞绘文

讯飞绘文

选题、配图、成文,一站式创作,让内容运营更高效

讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。

热门AI辅助写作AI工具讯飞绘文内容运营AI创作个性化文章多平台分发AI助手
材料星

材料星

专业的AI公文写作平台,公文写作神器

AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。

下拉加载更多