golang自动化浏览器测试与驱动插件库chromedp的使用
golang自动化浏览器测试与驱动插件库chromedp的使用
关于chromedp
chromedp
包是一个更快、更简单的方式,用于在Go中驱动支持Chrome DevTools协议的浏览器,无需外部依赖。
安装
使用常规的Go安装方式:
$ go get -u github.com/chromedp/chromedp
示例
以下是一个完整的chromedp使用示例,演示如何打开网页并获取页面标题:
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/chromedp/chromedp"
)
func main() {
// 创建上下文
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
// 设置超时时间
ctx, cancel = context.WithTimeout(ctx, 15*time.Second)
defer cancel()
// 定义变量来存储页面标题
var title string
// 执行浏览器操作
err := chromedp.Run(ctx,
// 导航到网页
chromedp.Navigate("https://www.example.com"),
// 等待页面加载
chromedp.Sleep(2*time.Second),
// 获取页面标题
chromedp.Title(&title),
)
if err != nil {
log.Fatal(err)
}
// 打印页面标题
fmt.Printf("Page title: %s\n", title)
}
常见问题解答
问题:我看不到任何Chrome浏览器窗口
默认情况下,Chrome以无头模式运行。可以通过覆盖默认选项来显示浏览器窗口:
opts := append(chromedp.DefaultExecAllocatorOptions[:],
chromedp.Flag("headless", false),
)
allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
defer cancel()
ctx, cancel := chromedp.NewContext(allocCtx)
defer cancel()
问题:我看到"context canceled"错误
当与浏览器的连接丢失时,chromedp
会取消上下文,可能导致此错误。例如,如果手动关闭浏览器或浏览器进程被终止。
问题:Chrome在我的Go程序结束时立即退出
在Linux上,chromedp
配置为避免资源泄漏,会强制终止任何启动的Chrome子进程。如果需要启动长时间运行的Chrome实例,可以手动启动Chrome并使用RemoteAllocator
连接。
问题:不使用Run
执行操作会导致"invalid context"
默认情况下,chromedp
上下文没有执行器,可以手动指定:
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
chromedp.Run(ctx, chromedp.ActionFunc(func(ctx context.Context) error {
_, err := domain.SomeAction().Do(ctx)
return err
}))
问题:我想在无头环境中使用chromedp
最简单的方法是使用chromedp/headless-shell
镜像运行Go程序,该镜像包含headless-shell
,一个更小的Chrome无头构建。
更多关于golang自动化浏览器测试与驱动插件库chromedp的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang自动化浏览器测试与驱动插件库chromedp的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang自动化浏览器测试与chromedp使用指南
chromedp是一个强大的Golang库,用于通过Chrome DevTools协议(CDP)控制Chrome或Chromium浏览器,非常适合自动化测试和网页抓取场景。
安装chromedp
首先安装chromedp及其依赖:
go get -u github.com/chromedp/chromedp
基本用法示例
package main
import (
"context"
"log"
"time"
"github.com/chromedp/chromedp"
)
func main() {
// 创建上下文
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
// 设置超时
ctx, cancel = context.WithTimeout(ctx, 15*time.Second)
defer cancel()
// 定义变量存储结果
var title, content string
// 运行任务
err := chromedp.Run(ctx,
// 导航到页面
chromedp.Navigate("https://example.com"),
// 等待元素可见
chromedp.WaitVisible("body"),
// 获取页面标题
chromedp.Title(&title),
// 获取h1元素内容
chromedp.Text("h1", &content, chromedp.NodeVisible),
)
if err != nil {
log.Fatal(err)
}
log.Printf("Title: %s", title)
log.Printf("Content: %s", content)
}
核心功能
1. 元素选择与操作
// 点击元素
chromedp.Click("#submit-button", chromedp.NodeVisible),
// 输入文本
chromedp.SendKeys("#username", "myusername", chromedp.NodeVisible),
// 获取属性值
var href string
chromedp.AttributeValue("a.link", "href", &href, nil),
2. 等待策略
// 等待元素出现
chromedp.WaitVisible("#loading", chromedp.ByID),
// 等待元素消失
chromedp.WaitNotPresent("#spinner"),
// 自定义等待
chromedp.WaitFunc(func(ctx context.Context) error {
// 自定义等待逻辑
return nil
}),
3. 截图与PDF
// 截取整个页面
var buf []byte
chromedp.FullScreenshot(&buf, 90),
// 截取特定元素
chromedp.Screenshot("#banner", &buf, chromedp.NodeVisible),
// 生成PDF
chromedp.PrintToPDF(&buf, chromedp.WithLandscape(true)),
高级配置
自定义浏览器选项
opts := append(chromedp.DefaultExecAllocatorOptions[:],
chromedp.Flag("headless", false), // 显示浏览器窗口
chromedp.Flag("disable-gpu", true), // 禁用GPU加速
chromedp.Flag("no-sandbox", true), // 禁用沙箱
chromedp.Flag("ignore-certificate-errors", true), // 忽略证书错误
)
allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
defer cancel()
ctx, cancel := chromedp.NewContext(allocCtx)
defer cancel()
处理弹窗和对话框
chromedp.ListenTarget(ctx, func(ev interface{}) {
if _, ok := ev.(*page.EventJavascriptDialogOpening); ok {
go func() {
// 自动接受弹窗
_ = chromedp.Run(ctx, page.HandleJavaScriptDialog(true))
}()
}
}),
实际测试示例
func TestLogin(t *testing.T) {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
err := chromedp.Run(ctx,
chromedp.Navigate("https://example.com/login"),
chromedp.WaitVisible("#login-form"),
chromedp.SendKeys("#username", "testuser"),
chromedp.SendKeys("#password", "password123"),
chromedp.Click("#submit"),
chromedp.WaitVisible("#dashboard"),
)
if err != nil {
t.Fatalf("测试失败: %v", err)
}
}
性能优化建议
- 复用浏览器实例而不是为每个测试创建新实例
- 使用
chromedp.NewRemoteAllocator
连接已运行的浏览器实例 - 合理设置超时时间
- 避免不必要的截图和等待
chromedp提供了丰富的API可以满足大多数自动化测试需求,结合Golang的测试框架可以构建强大的浏览器自动化测试套件。