package libs import ( "log" "sync" "github.com/go-rod/rod" ) // Browser 浏览器实例管理器 type Browser struct{} // BrowserInfo 浏览器实例信息 type BrowserInfo struct { Id int Browser *rod.Browser Url string Page *rod.Page } // Fingerprint 浏览器指纹配置 type Fingerprint struct { Viewport []struct { Height int Width int } Proxy string Lang string } var ( browserPool = make(map[int]*BrowserInfo) poolMutex sync.RWMutex ) // GetBrowser 获取或创建浏览器实例(线程安全,双重检查锁定) func (*Browser) GetBrowser(id int, params *Fingerprint) *BrowserInfo { poolMutex.RLock() value, ok := browserPool[id] poolMutex.RUnlock() if ok { return value } poolMutex.Lock() defer poolMutex.Unlock() // 双重检查 if value, ok := browserPool[id]; ok { return value } var chrome Chrome browser, url, page := chrome.Create(id, params) browserInfo := &BrowserInfo{ Id: id, Browser: browser, Url: url, Page: page, } browserPool[id] = browserInfo log.Printf("[浏览器] 创建实例 #%d", id) return browserInfo } // CloseAll 关闭所有浏览器实例 func (*Browser) CloseAll() { poolMutex.Lock() defer poolMutex.Unlock() for id, v := range browserPool { v.Browser.MustClose() delete(browserPool, id) } log.Println("[浏览器] 已关闭所有实例") } // Close 关闭指定浏览器实例 func (*Browser) Close(id int) { poolMutex.Lock() defer poolMutex.Unlock() info, ok := browserPool[id] if !ok { return } info.Browser.MustClose() delete(browserPool, id) log.Printf("[浏览器] 已关闭实例 #%d", id) }