golang实现高效网页自动化与数据抓取的插件库rod的使用
Golang实现高效网页自动化与数据抓取的插件库Rod的使用
概述
Rod是一个基于DevTools Protocol的高级驱动库,专为网页自动化和数据抓取设计。它既支持高级用法也支持底层操作,资深开发者可以使用底层包和函数轻松定制或构建自己的Rod版本。
特性
- 链式上下文设计,直观地设置超时或取消长时间运行的任务
- 自动等待元素准备就绪
- 调试友好,自动输入追踪,远程监控无头浏览器
- 所有操作都是线程安全的
- 自动查找或下载浏览器
- 高级辅助函数如WaitStable、WaitRequestIdle、HijackRequests、WaitDownload等
- 两步WaitEvent设计,不会错过任何事件
- 正确处理嵌套iframe或shadow DOM
- 崩溃后不会留下僵尸浏览器进程
- CI强制100%测试覆盖率
示例代码
基本使用示例
package main
import (
"fmt"
"time"
"github.com/go-rod/rod"
)
func main() {
// 启动浏览器
browser := rod.New().MustConnect()
defer browser.MustClose()
// 创建新页面
page := browser.MustPage("https://example.com")
// 等待页面加载完成
page.MustWaitLoad()
// 获取页面标题
title := page.MustInfo().Title
fmt.Println("页面标题:", title)
// 截图
page.MustScreenshot("screenshot.png")
// 获取页面HTML
html := page.MustHTML()
fmt.Println("页面HTML长度:", len(html))
}
表单填写与提交示例
package main
import (
"fmt"
"time"
"github.com/go-rod/rod"
)
func main() {
browser := rod.New().MustConnect()
defer browser.MustClose()
page := browser.MustPage("https://github.com/login")
// 等待元素出现
page.MustElement("#login_field").MustInput("your_username")
page.MustElement("#password").MustInput("your_password")
// 点击登录按钮
page.MustElement(".btn-primary").MustClick()
// 等待登录完成
page.MustWaitNavigation()
fmt.Println("登录成功!")
}
数据抓取示例
package main
import (
"fmt"
"strings"
"github.com/go-rod/rod"
)
func main() {
browser := rod.New().MustConnect()
defer browser.MustClose()
page := browser.MustPage("https://news.ycombinator.com/")
// 获取所有新闻标题
items := page.MustElements(".athing")
for _, item := range items {
title := item.MustElement(".titleline").MustText()
link := item.MustElement(".titleline a").MustProperty("href")
fmt.Printf("标题: %s\n链接: %s\n\n", strings.TrimSpace(title), link)
}
}
高级功能示例 - 拦截请求
package main
import (
"fmt"
"regexp"
"github.com/go-rod/rod"
)
func main() {
browser := rod.New().MustConnect()
defer browser.MustClose()
router := browser.HijackRequests()
defer router.MustStop()
// 拦截所有图片请求
router.MustAdd(regexp.MustCompile(`\.(jpg|png|svg)$`), func(ctx *rod.Hijack) {
// 阻止图片加载
ctx.Response.Fail(rod.ErrorTypeAborted)
})
go router.Run()
page := browser.MustPage("https://example.com")
page.MustWaitLoad()
fmt.Println("页面加载完成,所有图片请求已被拦截")
}
最佳实践
- 总是使用
defer browser.MustClose()
确保浏览器进程被正确关闭 - 对于关键操作使用
MustWaitNavigation()
确保页面导航完成 - 使用
MustElement()
而不是Element()
可以自动等待元素出现 - 对于复杂页面,考虑使用
MustWaitStable()
等待页面完全稳定 - 处理大量数据时,使用
MustEval()
执行JavaScript可能更高效
Rod提供了丰富的功能和灵活的API,可以满足各种网页自动化和数据抓取需求。通过上述示例,您可以快速上手并开始构建自己的自动化工具。
更多关于golang实现高效网页自动化与数据抓取的插件库rod的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang实现高效网页自动化与数据抓取的插件库rod的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用Rod实现高效网页自动化与数据抓取
Rod是一个基于Golang的高效网页自动化和数据抓取库,它提供了简洁的API来控制浏览器并提取网页数据。下面我将介绍Rod的核心功能和使用方法。
Rod的主要特点
- 无头浏览器控制(支持Chrome/Chromium)
- 自动等待元素加载
- 模拟用户操作(点击、输入、滚动等)
- 支持页面截图和PDF生成
- 网络请求拦截和修改
- 轻量级且性能优异
安装Rod
go get github.com/go-rod/rod
基本使用示例
1. 启动浏览器并打开页面
package main
import (
"fmt"
"time"
"github.com/go-rod/rod"
)
func main() {
// 启动浏览器
page := rod.New().MustConnect().MustPage("https://example.com")
// 等待页面加载完成
page.MustWaitLoad()
// 获取页面标题
title := page.MustInfo().Title
fmt.Println("页面标题:", title)
// 延迟关闭浏览器
defer page.MustClose()
}
2. 模拟用户输入和点击
func searchOnGoogle() {
browser := rod.New().MustConnect()
page := browser.MustPage("https://www.google.com").MustWaitLoad()
// 接受cookie提示(如果有)
if el, err := page.Element("#L2AGLb"); err == nil {
el.MustClick()
}
// 在搜索框中输入内容
page.MustElement("textarea[name=q]").MustInput("Rod golang")
// 点击搜索按钮
page.MustElement("input[name=btnK]").MustClick()
// 等待结果加载
page.MustWaitLoad()
// 获取第一个结果
firstResult := page.MustElement("#search .g").MustText()
fmt.Println("第一个搜索结果:", firstResult)
browser.MustClose()
}
3. 数据抓取示例
func scrapeQuotes() {
browser := rod.New().MustConnect()
page := browser.MustPage("http://quotes.toscrape.com/").MustWaitLoad()
// 获取所有引用文本
quotes := page.MustElements(".quote")
for _, quote := range quotes {
text := quote.MustElement(".text").MustText()
author := quote.MustElement(".author").MustText()
fmt.Printf("作者: %s\n引用: %s\n\n", author, text)
}
browser.MustClose()
}
高级功能
1. 处理动态加载内容
func handleInfiniteScroll() {
browser := rod.New().MustConnect()
page := browser.MustPage("https://www.example.com/infinite-scroll").MustWaitLoad()
// 滚动到底部多次以加载更多内容
for i := 0; i < 5; i++ {
page.MustEval("window.scrollTo(0, document.body.scrollHeight)")
time.Sleep(1 * time.Second) // 等待内容加载
}
// 现在可以获取所有加载的内容
items := page.MustElements(".item")
fmt.Println("加载的项目数量:", len(items))
browser.MustClose()
}
2. 拦截网络请求
func interceptRequests() {
browser := rod.New().MustConnect()
// 启用网络拦截
router := browser.HijackRequests()
defer router.MustStop()
// 只允许特定类型的请求
router.MustAdd("*.jpg|*.png|*.gif", func(ctx *rod.Hijack) {
ctx.Response.Fail(rod.ErrorReasonBlockedByClient)
})
go router.Run()
page := browser.MustPage("https://example.com").MustWaitLoad()
// 页面操作...
browser.MustClose()
}
3. 处理iframe和多个页面
func handleIframes() {
browser := rod.New().MustConnect()
page := browser.MustPage("https://example.com/with-iframe").MustWaitLoad()
// 获取iframe
iframe := page.MustElement("iframe").MustFrame()
// 在iframe中操作
iframe.MustElement("button").MustClick()
browser.MustClose()
}
性能优化技巧
- 重用浏览器实例:避免频繁启动和关闭浏览器
- 并行处理:使用goroutines处理多个页面
- 禁用不必要的功能:如图片加载、CSS等
- 合理使用等待:避免硬编码的sleep,使用MustWaitLoad等
func optimizedCrawler() {
browser := rod.New().
ControlURL("ws://localhost:9222"). // 连接已存在的浏览器实例
MustConnect().
MustIgnoreCertErrors(true).
NoDefaultDevice() // 禁用默认设备模拟提高性能
// 禁用图片加载
_ = browser.SetBlockedURLs("*.jpg", "*.png", "*.gif")
// 并行处理多个页面
var wg sync.WaitGroup
urls := []string{"url1", "url2", "url3"}
for _, url := range urls {
wg.Add(1)
go func(u string) {
defer wg.Done()
page := browser.MustPage(u).MustWaitLoad()
// 处理页面...
page.MustClose()
}(url)
}
wg.Wait()
browser.MustClose()
}
错误处理
Rod提供了良好的错误处理机制:
func withErrorHandling() {
browser := rod.New().Timeout(30 * time.Second).MustConnect()
defer browser.MustClose()
page, err := browser.Page(rod.NewPageOptions("https://example.com"))
if err != nil {
log.Fatal("无法创建页面:", err)
}
if err := rod.Try(func() {
page.MustWaitLoad().MustElement("#non-existent-element")
}); err != nil {
log.Println("元素未找到:", err)
// 可以在这里添加备用逻辑
}
}
Rod是一个功能强大且灵活的库,非常适合需要高效网页自动化和数据抓取的场景。通过合理使用其API,你可以构建出稳定高效的爬虫和自动化工具。