如何在chromedp.Run执行失败时截取浏览器截图?
解决方案
核心思路
利用context的取消通知机制,在触发context deadline exceeded超时或其他取消信号时,优先执行截图操作,再处理浏览器关闭逻辑。同时要保证chromedp的浏览器实例在截图完成前不被提前销毁。
具体实现步骤
- 拆分context层级:不直接将超时context传给chromedp.Run,而是创建父级可取消context,派生超时子context,以此控制浏览器实例的生命周期。
- 分离任务与错误处理:用goroutine执行主业务流程,主goroutine监听context的Done()信号,一旦触发立即执行截图。
- 保留浏览器上下文:提前保存chromedp的Context实例,确保错误发生时能直接调用截图命令。
示例代码
package main import ( "context" "fmt" "os" "time" "github.com/chromedp/chromedp" ) func main() { // 创建父级可取消context,用于全局控制 parentCtx, cancel := context.WithCancel(context.Background()) defer cancel() // 派生带超时的子context,模拟超时场景 timeoutCtx, timeoutCancel := context.WithTimeout(parentCtx, 3*time.Second) defer timeoutCancel() // 配置chromedp启动选项,支持无头/有头切换 opts := append(chromedp.DefaultExecAllocatorOptions[:], chromedp.Flag("headless", false), // 改为true启用无头模式 chromedp.Flag("disable-gpu", true), ) // 创建浏览器实例的上下文 allocCtx, allocCancel := chromedp.NewExecAllocator(parentCtx, opts...) defer allocCancel() ctx, cancelCtx := chromedp.NewContext(allocCtx) defer cancelCtx() var screenshot []byte // 启动goroutine执行主任务 go func() { err := chromedp.Run(ctx, chromedp.Navigate("https://example.com"), // 模拟耗时操作触发超时 chromedp.Sleep(5*time.Second), // 正常流程的截图(可选) chromedp.Screenshot(`body`, &screenshot), ) if err != nil { fmt.Printf("主任务报错: %v\n", err) } cancel() }() // 监听取消信号,处理截图逻辑 select { case <-timeoutCtx.Done(): fmt.Println("触发超时,开始捕获错误状态截图") // 执行错误场景截图 err := chromedp.Run(ctx, chromedp.Screenshot(`body`, &screenshot)) if err != nil { fmt.Printf("截图失败: %v\n", err) return } // 保存截图到本地 if err := os.WriteFile("error_screenshot.png", screenshot, 0644); err != nil { fmt.Printf("保存截图失败: %v\n", err) } fmt.Println("错误截图已保存为error_screenshot.png") case <-parentCtx.Done(): // 处理正常完成后的截图 if len(screenshot) > 0 { os.WriteFile("success_screenshot.png", screenshot, 0644) fmt.Println("正常流程截图已保存") } } }
关键细节说明
- context层级设计:通过父级context控制浏览器实例的销毁时机,避免超时触发时浏览器直接关闭,给截图操作留足执行时间。
- 跨模式兼容:仅需修改
headless参数即可切换有头/无头模式,截图逻辑不受影响。 - 场景覆盖:除了超时错误,该逻辑还能处理其他导致context取消的场景(如手动取消、浏览器异常等)。
内容的提问来源于stack exchange,提问作者Katya
相关产品推荐
相关产品推荐

