90 lines
1.6 KiB
Go
90 lines
1.6 KiB
Go
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)
|
|
}
|