1. Go语言基础
- 包导入:使用了标准库中的
context
、errors
、fmt
和time
包,分别用于处理上下文、错误、格式化输入输出和时间操作。 - 延迟执行:通过
defer
关键字确保在函数返回前关闭浏览器实例。 - 错误处理:使用
errors.Is
检查特定类型的错误,并通过panic
抛出未预期的错误。
2. Rod库的使用
浏览器自动化:
- 使用
rod.New().MustConnect()
创建并连接到一个浏览器实例。 - 使用
browser.MustPage(url)
打开指定的网页。 - 使用
browser.MustClose()
关闭浏览器。
- 使用
元素查找:
- 使用
page.Element(selector)
查找页面上的元素,支持重试机制。 - 使用
page.Sleeper(sleeper).Element(selector)
自定义重试逻辑。 - 使用
rod.NotFoundSleeper
处理元素未找到的情况。
- 使用
属性获取:
- 使用
el.MustProperty(name)
获取动态属性值,简化代码逻辑。 - 对比
el.Attribute(name)
,后者更适合静态属性且需要额外处理返回值为nil
的情况。
- 使用
3. 自定义函数
休眠函数:
- 定义了一个匿名函数作为
utils.Sleeper
,每次调用时休眠 0.5 秒。 - 通过
page.Sleeper(sleeper).Element(selector)
实现带自定义重试逻辑的元素查找。
- 定义了一个匿名函数作为
4. 错误处理与逻辑分支
元素未找到的处理:
- 使用
rod.NotFoundSleeper
配合page.Element(selector)
查找元素。 - 如果元素未找到,返回
rod.ElementNotFoundError
错误。 - 使用
errors.Is(err, &rod.ElementNotFoundError{})
判断是否为元素未找到的错误。
- 使用
其他错误处理:
- 如果发生非预期错误,通过
panic(err)
中断程序运行。
- 如果发生非预期错误,通过
5. 代码逻辑
主流程:
- 启动浏览器并打开指定网页。
- 使用自定义休眠函数查找页面上的
input
元素。 - 打印找到的元素的
name
属性。 - 再次尝试查找
input
元素,模拟元素未找到的场景,并打印相应消息。 - 最后关闭浏览器。
6. 扩展知识点
Rod库的优势:
- 提供了强大的浏览器自动化功能,适合爬虫、测试等场景。
- 支持灵活的元素查找和属性获取方式。
实际应用场景:
- 可用于自动化测试、数据抓取或模拟用户行为。
以上是代码中涉及的主要知识点,涵盖了 Go 语言的基础语法、Rod 库的使用方法以及错误处理的最佳实践。
package main
import (
"context" // 导入context包,用于处理超时和取消操作
"errors" // 导入errors包,用于处理错误
"fmt" // 导入fmt包,用于格式化输入输出
"time" // 导入time包,用于处理时间相关的操作
"github.com/go-rod/rod" // 导入rod包,用于自动化浏览器操作
"github.com/go-rod/rod/lib/utils" // 导入rod的utils包,用于工具函数
)
func main() {
browser := rod.New().MustConnect() // 创建一个新的浏览器实例并连接到浏览器
defer browser.MustClose() // 程序结束时关闭浏览器
page := browser.MustPage("https://github.com") // 打开指定的URL页面
// sleep for 0.5 seconds before every retry
// 在每次重试前休眠0.5秒
sleeper := func() utils.Sleeper {
return func(context.Context) error {
time.Sleep(time.Second / 2) // 休眠0.5秒
return nil
}
}
el, _ := page.Sleeper(sleeper).Element("input") // 使用自定义的休眠函数查找元素
fmt.Println(el.MustProperty("name")) // 打印元素的"name"属性
// If sleeper is nil page.Element will query without retrying.
// 如果sleeper为nil,page.Element将不会重试查询
// If sleeper is nil page.ElementE will query without retrying.
// 如果sleeper为nil,page.ElementE将不会重试查询
// If nothing found it will return an error.
// 如果没有找到元素,将返回一个错误
el, err := page.Sleeper(rod.NotFoundSleeper).Element("input") // 使用NotFoundSleeper查找元素
if errors.Is(err, &rod.ElementNotFoundError{}) { // 检查错误是否为元素未找到的错误
fmt.Println("element not found") // 打印元素未找到的消息
} else if err != nil { // 如果有其他错误
panic(err) // 抛出错误
}
fmt.Println(el.MustProperty("name")) // 打印元素的"name"属性
}