使用 Go-Rod 构建浏览器渲染池:一份全面的中文指南
简介
go-rod
是一个功能强大的 Go 语言库,用于通过 DevTools 协议驱动浏览器。它使得网页自动化、爬虫、端到端测试等任务变得简单高效。本文档在原有笔记的基础上,结合官方文档,提供一份更全面、更详细的 go-rod
使用指南。
核心概念
- 浏览器(Browser):
go-rod
可以启动和连接到一个浏览器实例,无论是本地安装的 Chrome,还是远程的 Docker 容器。
- 页面(Page): 在一个浏览器实例中,可以创建一个或多个页面。每个页面都是一个独立的浏览上下文,可以加载不同的 URL。
- 启动器(Launcher):
go-rod
提供了 launcher
模块,用于方便地管理浏览器的启动和连接,包括远程连接和 Docker 容器。
安装与设置
1. 运行 Docker 镜像
为了方便和隔离,推荐使用官方提供的 Docker 镜像。这可以避免在本地安装 Chrome,并确保环境的一致性。
1
| docker run -p 7317:7317 --rm ghcr.io/go-rod/rod
|
这条命令会启动一个 go-rod
容器,并将容器的 7317
端口映射到主机的 7317
端口。--rm
参数表示容器停止后自动删除。
2. 连接到正在运行的 Docker 容器
在你的 Go 代码中,你可以使用 launcher
来连接到这个正在运行的容器。
注意: 连接前请确保关闭了全局代理或隧道代理,否则可能会导致连接失败。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package main
import ( "fmt" "github.com/go-rod/rod" "github.com/go-rod/rod/lib/launcher" )
func main() { l := launcher.MustNewManaged("ws://127.0.0.1:7317")
l.Set("disable-gpu")
l.Headless(false)
browser := rod.New().Client(l.MustClient()).MustConnect()
page := browser.MustPage("https://www.baidu.com") title := page.MustEval("() => document.title") fmt.Println(title) }
|
常用功能
1. 截图
go-rod
可以轻松地对页面进行截图。
1 2 3 4 5 6 7 8 9 10 11 12 13
| package main
import ( "github.com/go-rod/rod" "time" )
func main() { page := rod.New().NoDefaultDevice().MustConnect().MustPage("https://www.wikipedia.org/") page.MustWindowFullscreen() page.MustWaitStable().MustScreenshot("wikipedia.png") time.Sleep(time.Hour) }
|
2. 启动监控窗口
go-rod
提供了一个非常实用的功能:启动一个 web 窗口来实时监控浏览器中发生的事情。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package main
import ( "fmt" "github.com/go-rod/rod" "github.com/go-rod/rod/lib/launcher" "time" )
func main() { l := launcher.MustNewManaged("ws://127.0.0.1:7317") browser := rod.New().Client(l.MustClient()).MustConnect()
launcher.Open(browser.ServeMonitor(""))
fmt.Println( browser.MustPage("https://www.baidu.com").MustEval("() => document.title"), ) time.Sleep(time.Hour) }
|
构建浏览器渲染池
对于需要处理大量渲染任务的场景,可以使用 go-rod
的页面池(Page Pool)来提高效率。页面池可以复用页面对象,避免了频繁创建和销毁页面的开销。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| package main
import ( "github.com/go-rod/rod" "github.com/go-rod/rod/lib/launcher" )
func main() { l := launcher.MustNewManaged("ws://127.0.0.1:7317") browser := rod.New().Client(l.MustClient()).MustConnect()
pool := rod.NewPagePool(10)
create := func() *rod.Page { return browser.MustIncognito().MustPage() }
urlList := []string{ "http://www.baidu.com", "http://www.bing.com", }
for _, url := range urlList { page := pool.Get(create)
page.MustNavigate(url).MustWaitLoad() println(page.MustInfo().Title)
pool.Put(page) } }
|
直接使用 Debug 端口
除了通过 7317
端口,go-rod
还可以直接连接到 Chrome 的远程调试端口(默认为 9222
)。
1. 启动 Docker 容器并暴露调试端口
1
| docker run -p 9222:9222 --rm ghcr.io/go-rod/rod:arm chrome --headless --no-sandbox --remote-debugging-port=9222 --remote-debugging-address=0.0.0.0
|
2. 在 Go 代码中连接到调试端口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package main
import ( "github.com/go-rod/rod" "github.com/go-rod/rod/lib/launcher" )
func main() { container := launcher.MustResolveURL("ws://127.0.0.1:9222") browser := rod.New().ControlURL(container).MustConnect()
pool := rod.NewPagePool(10) create := func() *rod.Page { return browser.MustIncognito().MustPage() }
urlList := []string{ "http://www.baidu.com", "http://www.bing.com", }
page := pool.Get(create)
for _, url := range urlList { page.MustNavigate(url).MustWaitLoad() println(page.MustInfo().Title) }
pool.Put(page) }
|