Go语言使用Go-Rod库实现浏览器自动化操作的知识点汇总
1. 导入库
- 使用了
go-rod
库及其相关子库来实现浏览器自动化操作。 导入的标准库包括:
context
:用于创建带有超时的上下文。fmt
:用于格式化输出。os
:用于文件操作。time
:用于时间相关的操作。
导入的第三方库包括:
github.com/go-rod/rod
:核心库,用于浏览器自动化。github.com/go-rod/rod/lib/launcher
:用于启动浏览器实例。github.com/go-rod/rod/lib/proto
:定义了浏览器协议相关的结构体和方法。github.com/go-rod/stealth
:用于隐身模式,避免被检测为自动化工具。github.com/ysmood/gson
:用于处理JSON数据。
2. 浏览器启动与连接
- 使用
launcher.New().Headless(false).MustLaunch()
启动浏览器,禁用无头模式。 - 创建带有超时的上下文:
context.WithTimeout(context.Background(), 60*time.Second)
。 - 连接浏览器实例:
rod.New().ControlURL(url).Context(ctx).MustConnect()
。 - 在程序结束时关闭浏览器:
defer browser.MustClose()
。
3. 页面导航与加载
- 创建一个新的隐身页面并导航到指定网址:
stealth.MustPage(browser).MustNavigate("https://.com/")
。 - 等待页面加载完成:
MustWaitLoad()
。
4. 截图功能
调用
page.Screenshot
方法进行截图,支持以下参数:true
:等待页面稳定后再截图。- 配置对象:指定截图格式、质量、区域等。
示例配置:
&proto.PageCaptureScreenshot{ Format: proto.PageCaptureScreenshotFormatJpeg, Quality: gson.Int(90), Clip: &proto.PageViewport{ X: 0, Y: 0, Width: 300, Height: 200, Scale: 1, }, FromSurface: true, }
- 将截图保存到文件:
utils.OutputFile("my.jpg", img)
。
5. 整页滚动截图
- 使用
browser.MustPage("https://desktop.github.com/").MustWaitStable().ScrollScreenshot
方法对整个页面进行滚动截图。 - 支持指定截图格式和质量。
6. 文件下载
- 打开PDF样本下载页面:
browser.MustPage("https://file-examples.com/...")
。 - 创建下载等待通道:
browser.MustWaitDownload()
。 - 定位并点击下载按钮:
page3.MustElementR("a", "DOWNLOAD SAMPLE PDF FILE").MustClick()
。 - 保存下载内容到本地:
utils.OutputFile("t.pdf", wait())
。
7. 元素搜索与属性获取
Rod 库中的 Search 方法可以用于查找嵌套在 iframe 或 shadow DOM 中的元素。它能够穿透多层嵌套的 iframe 来查找元素。这意味着即使元素嵌套在多个 iframe 中, Search 方法也可以找到它。不过,具体的实现可能会受到页面结构和 Rod 库版本的影响,因此建议在实际使用中进行测试以确保其行为符合预期
- 搜索页面中的特定元素:
page.Search("a.layui-btn.layui-btn-primary.layui-border-green.layui-btn-sm.copy")
。 - 获取搜索结果中的所有元素:
SearchResult.All()
。 遍历元素并根据文本内容执行不同操作:
- 如果文本为“复制账号”,获取
title
属性值作为账号信息。 - 如果文本为“复制密码”,获取
title
属性值作为密码信息。
- 如果文本为“复制账号”,获取
示例代码:
if v.MustText() == "复制账号" { username, err := v.Attribute("title") fmt.Println(*username) } else if v.MustText() == "复制密码" { password, err := v.Attribute("title") fmt.Println(*password) }
8. 页面内容保存
- 截图保存:
page.MustScreenshot("screenshot.png")
。 - 保存网页HTML内容:
os.WriteFile("page.html", []byte(page.MustHTML()), 0644)
。 - 保存为PDF:
page.MustPDF("page.pdf")
。
9. 异常处理
- 使用
if err != nil
检查错误,并打印错误信息。 示例代码:
if err != nil { fmt.Println("没有找到复制账号这个元素", err) return }
10. 程序暂停
- 使用
time.Sleep(100 * time.Second)
暂停程序以便观察结果(可选)。
总结
本代码展示了如何使用go-rod
库实现浏览器自动化操作,包括启动浏览器、导航页面、截图、文件下载、元素搜索与属性获取、页面内容保存等功能。通过这些功能,可以高效地完成各种网页交互任务。
// 导入必要的包
package main
// 导入标准库和第三方库
import (
"context"
"fmt"
"os"
"time"
"github.com/go-rod/rod"
"github.com/go-rod/rod/lib/launcher"
"github.com/go-rod/rod/lib/proto"
"github.com/go-rod/rod/lib/utils"
"github.com/go-rod/stealth"
"github.com/ysmood/gson"
)
// 主函数入口
func main() {
// 禁用无头模式,启动浏览器
url := launcher.New().Headless(false).MustLaunch()
// 创建带有超时的上下文,设置为60秒
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
// 创建浏览器实例并连接
browser := rod.New().ControlURL(url).Context(ctx).MustConnect()
// 在程序结束时关闭浏览器
defer browser.MustClose()
// 创建一个新的隐身页面并导航到指定网址
page := stealth.MustPage(browser).MustNavigate("https:///").Context(ctx).MustWaitLoad()
// 调用截图API,参数说明:
// 第一个true参数表示等待页面稳定后再截图
// 第二个参数是截图配置对象
img, _ := page.Screenshot(true, &proto.PageCaptureScreenshot{
Format: proto.PageCaptureScreenshotFormatJpeg, // 指定截图格式为JPEG
Quality: gson.Int(90), // 设置图片质量为90(0-100)
Clip: &proto.PageViewport{ // 定义截图区域
X: 0, // 起始点X坐标
Y: 0, // 起始点Y坐标
Width: 300, // 截图宽度300像素
Height: 200, // 截图高度200像素
Scale: 1, // 缩放比例保持1:1
},
FromSurface: true, // 包含浏览器界面元素
})
// 将截图保存到文件
_ = utils.OutputFile("my.jpg", img)
// capture entire browser viewport, returning jpg with quality=90
img, err := browser.MustPage("https://desktop.github.com/").MustWaitStable().ScrollScreenshot(&rod.ScrollScreenshotOptions{
Format: proto.PageCaptureScreenshotFormatJpeg,
Quality: gson.Int(90),
})
if err != nil {
panic(err)
}
_ = utils.OutputFile("my.jpg", img)
// 打开PDF样本下载页面
page3 := browser.MustPage("https://file-examples.com/...")
// 创建下载等待通道
wait := browser.MustWaitDownload()
// 定位并点击下载按钮
page3.MustElementR("a", "DOWNLOAD SAMPLE PDF FILE").MustClick()
// 保存下载内容到本地
_ = utils.OutputFile("t.pdf", wait())
// 搜索页面中的特定元素
SearchResult, err := page.Search("a.layui-btn.layui-btn-primary.layui-border-green.layui-btn-sm.copy")
if err != nil {
// 如果没有找到元素,打印错误信息
fmt.Println("没有找到复制账号这个元素", err)
return
}
// 获取搜索结果中的所有元素
el, err := SearchResult.All()
if err != nil {
// 如果获取元素时出错,打印错误信息
fmt.Println("在SearchResult对象返回所有元素时出错:", err)
}
// 遍历所有元素
for _, v := range el {
// 如果元素文本为“复制账号”
if v.MustText() == "复制账号" {
// 获取账号信息
username, err := v.Attribute("title")
if err != nil {
// 如果获取账号时出错,打印错误信息
fmt.Println("获取账号时出错:", err)
}
// 打印账号
fmt.Println(*username)
// 如果元素文本为“复制密码”
} else if v.MustText() == "复制密码" {
// 获取密码信息
password, err := v.Attribute("title")
if err != nil {
// 如果获取密码时出错,打印错误信息
fmt.Println("获取密码时出错:", err)
}
// 打印密码
fmt.Println(*password)
}
}
// 截图
page.MustScreenshot("screenshot.png")
// 保存网页内容
os.WriteFile("page.html", []byte(page.MustHTML()), 0644)
// 保存为PDF
page.MustPDF("page.pdf")
// 暂停程序以便观察结果
// time.Sleep(100 * time.Second)
}