Documentation
¶
Overview ¶
Package browser 提供统一的浏览器池抽象层。
支持多种浏览器后端(Rod、Browserless、Surf 等), 上层调用方通过统一的 Browser 接口操作页面,无需关心底层实现。
架构参考 database/sql 的 Strategy Pattern:
- 父包定义接口(Browser、Provider)和通用能力(Pool、Fetcher)
- 子包(rod/、browserless/、surf/)提供具体实现
- 用户按需 import 子包,配置驱动注册
Index ¶
- Variables
- func CheckWAF(ctx context.Context, b Browser, detector BlockDetector) error
- func IsConnectionError(err error) bool
- func PlatformFromUA(ua string) string
- func PlatformOverrideScript(platform string) string
- func RandomLocale() string
- func RandomTimezone() string
- func RandomUserAgent() string
- func TruncateUA(ua string, maxLen int) string
- type AcquireOpts
- type BlockDetector
- type BlockResult
- type Browser
- type Cookie
- type DefaultBlockDetector
- type DetectResult
- type FetchAttempt
- type FetchOption
- type FetchResult
- type Fetcher
- type FetcherOption
- type Metrics
- type MetricsSnapshot
- type NavigateOption
- type NavigateOpts
- type NavigateResult
- type Pool
- func (p *Pool) Acquire(ctx context.Context, opts AcquireOpts) (Browser, error)
- func (p *Pool) Close() error
- func (p *Pool) FetchWithFallback(ctx context.Context, url string, chain []Type, detector BlockDetector) (*FetchResult, error)
- func (p *Pool) HasProvider(t Type) bool
- func (p *Pool) Metrics() *Metrics
- func (p *Pool) Register(provider Provider)
- func (p *Pool) Release(b Browser, lastErr error) error
- func (p *Pool) Stats() PoolStats
- type PoolConfig
- type PoolStats
- type Provider
- type Task
- type TaskResult
- type Type
- type Viewport
- type WAFBlockedError
- type Worker
- type WorkerConfig
Constants ¶
This section is empty.
Variables ¶
var ( // ErrPoolClosed 表示浏览器池已关闭 ErrPoolClosed = errors.New("browser: pool closed") // ErrAcquireTimeout 表示获取浏览器实例超时 ErrAcquireTimeout = errors.New("browser: acquire timeout") // ErrProviderNotFound 表示未注册对应类型的 Provider ErrProviderNotFound = errors.New("browser: provider not found") // ErrUnsupported 表示当前浏览器实现不支持该操作 ErrUnsupported = errors.New("browser: operation not supported") // ErrAllBlocked 表示所有浏览器类型都被风控拦截 ErrAllBlocked = errors.New("browser: all browser types blocked") // ErrNoHealthyEndpoint 表示没有可用的健康远程节点 ErrNoHealthyEndpoint = errors.New("browser: no healthy endpoint available") // ErrWAFBlocked 表示页面被 WAF/风控系统拦截 ErrWAFBlocked = errors.New("browser: waf blocked") )
var DefaultPoolConfig = PoolConfig{ MaxInstances: 8, IdleTimeout: 5 * time.Minute, AcquireTimeout: 30 * time.Second, HealthCheckFreq: 30 * time.Second, PingTimeout: 2 * time.Second, }
DefaultPoolConfig 默认池配置
var DefaultViewport = Viewport{ Width: 1920, Height: 1080, Scale: 1.0, Mobile: false, }
DefaultViewport 默认桌面视口
var DefaultWorkerConfig = WorkerConfig{
Concurrency: 4,
}
DefaultWorkerConfig 默认 Worker 配置
var Locales = []string{
"en-US", "en-GB", "en-CA", "en-AU",
"de-DE", "fr-FR", "ja-JP", "zh-CN",
}
Locales 预定义的语言区域列表
var Timezones = []string{
"America/New_York", "America/Chicago", "America/Denver",
"America/Los_Angeles", "America/Phoenix",
"Europe/London", "Europe/Paris", "Europe/Berlin",
"Asia/Tokyo", "Asia/Shanghai", "Asia/Singapore",
"Australia/Sydney",
}
Timezones 预定义的时区列表
var UserAgents = []string{
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
}
UserAgents 预定义的 User-Agent 列表
var Viewports = []Viewport{
{Width: 1920, Height: 1080, Scale: 1.0},
{Width: 1366, Height: 768, Scale: 1.0},
{Width: 1536, Height: 864, Scale: 1.25},
{Width: 1440, Height: 900, Scale: 1.0},
{Width: 1680, Height: 1050, Scale: 1.0},
{Width: 2560, Height: 1440, Scale: 1.0},
{Width: 1280, Height: 720, Scale: 1.0},
{Width: 1600, Height: 900, Scale: 1.0},
}
Viewports 预定义的桌面视口列表
Functions ¶
func CheckWAF ¶
func CheckWAF(ctx context.Context, b Browser, detector BlockDetector) error
CheckWAF 检测当前页面是否被 WAF 拦截
func PlatformOverrideScript ¶
PlatformOverrideScript 生成 navigator.platform 覆盖脚本
func RandomUserAgent ¶
func RandomUserAgent() string
Types ¶
type AcquireOpts ¶
AcquireOpts 获取浏览器实例的选项
type BlockDetector ¶
type BlockDetector interface {
Detect(html, title string, statusCode int) BlockResult
}
BlockDetector 风控检测接口
type BlockResult ¶
type BlockResult struct {
Blocked bool `json:"blocked"`
Reason string `json:"reason"`
Type string `json:"type"`
}
BlockResult 风控检测结果
type Browser ¶
type Browser interface {
WaitStable(ctx context.Context) error
HTML(ctx context.Context) (string, error)
Text(ctx context.Context) (string, error)
Title(ctx context.Context) (string, error)
URL(ctx context.Context) (string, error)
Screenshot(ctx context.Context) ([]byte, error)
Eval(ctx context.Context, js string) (string, error)
// EvalDirect 直接通过 CDP 执行 JS,不等待 navigation lifecycle。
// 使用场景: 页面目标元素已确认存在,只需操作 DOM (SPA 表单交互、DOM 读取)。
// 不确定目标元素是否存在时,请先用 WaitSelector 或自行轮询确认后再调用。
EvalDirect(ctx context.Context, js string) (string, error)
Click(ctx context.Context, selector string) error
Type(ctx context.Context, selector, text string) error
WaitSelector(ctx context.Context, selector string) error
Cookies(ctx context.Context) ([]Cookie, error)
SetCookies(ctx context.Context, cookies []Cookie) error
BrowserType() Type
Close() error
}
Browser 统一浏览器操作接口
所有浏览器后端(Rod、Browserless、Surf 等)都实现此接口。 不支持的操作应返回 ErrUnsupported。
type Cookie ¶
type Cookie struct {
Name string `json:"name"`
Value string `json:"value"`
Domain string `json:"domain"`
Path string `json:"path"`
Secure bool `json:"secure"`
HTTPOnly bool `json:"http_only"`
}
Cookie HTTP cookie
type DefaultBlockDetector ¶
type DefaultBlockDetector struct{}
DefaultBlockDetector 默认风控检测器
func NewBlockDetector ¶
func NewBlockDetector() *DefaultBlockDetector
func (*DefaultBlockDetector) Detect ¶
func (d *DefaultBlockDetector) Detect(html, title string, statusCode int) BlockResult
type DetectResult ¶
type DetectResult struct {
SuggestedType Type `json:"suggested_type"`
IsSSR bool `json:"is_ssr"`
Score int `json:"score"`
Signals []string `json:"signals"`
}
DetectResult 页面类型探测结果
type FetchAttempt ¶
type FetchAttempt struct {
Type Type `json:"type"`
Duration time.Duration `json:"duration"`
Blocked bool `json:"blocked"`
Reason string `json:"reason"`
Err error `json:"-"`
}
FetchAttempt 单次尝试记录
type FetchOption ¶
type FetchOption func(*fetchCall)
FetchOption 单次 Fetch 调用的选项
func FetchWithProvider ¶
func FetchWithProvider(t Type) FetchOption
FetchWithProvider 覆盖本次请求使用的浏览器类型
type FetchResult ¶
type FetchResult struct {
HTML string `json:"html"`
Title string `json:"title"`
FinalType Type `json:"final_type"`
Attempts []FetchAttempt `json:"attempts"`
TotalLatency time.Duration `json:"total_latency"`
}
FetchResult 抓取结果
type Fetcher ¶
type Fetcher struct {
// contains filtered or unexported fields
}
Fetcher 业务层单一入口,封装 Pool + BlockDetector
func NewFetcher ¶
func NewFetcher(pool *Pool, detector BlockDetector, opts ...FetcherOption) (*Fetcher, error)
func (*Fetcher) Fetch ¶
func (f *Fetcher) Fetch(ctx context.Context, url string, opts ...FetchOption) (*FetchResult, error)
func (*Fetcher) SetPrimary ¶
type FetcherOption ¶
type FetcherOption func(*Fetcher)
FetcherOption 配置 Fetcher 的函数式选项
func WithFallback ¶
func WithFallback(types ...Type) FetcherOption
func WithPrimary ¶
func WithPrimary(t Type) FetcherOption
type Metrics ¶
type Metrics struct {
AcquireTotal atomic.Int64
AcquireSuccess atomic.Int64
AcquireFail atomic.Int64
CreateTotal atomic.Int64
ReleaseTotal atomic.Int64
EvictTotal atomic.Int64
ReuseTotal atomic.Int64
FetchTotal atomic.Int64
FetchSuccess atomic.Int64
FetchBlocked atomic.Int64
FetchFallback atomic.Int64
FetchAllFail atomic.Int64
// contains filtered or unexported fields
}
Metrics 浏览器池运行指标
func NewMetrics ¶
func NewMetrics() *Metrics
func (*Metrics) LogSummary ¶
func (m *Metrics) LogSummary()
func (*Metrics) RecordBlockByType ¶
func (*Metrics) RecordFetchByType ¶
func (*Metrics) RecordLatency ¶
func (*Metrics) Snapshot ¶
func (m *Metrics) Snapshot() MetricsSnapshot
type MetricsSnapshot ¶
type MetricsSnapshot struct {
AcquireTotal int64 `json:"acquire_total"`
AcquireSuccess int64 `json:"acquire_success"`
AcquireFail int64 `json:"acquire_fail"`
CreateTotal int64 `json:"create_total"`
ReleaseTotal int64 `json:"release_total"`
EvictTotal int64 `json:"evict_total"`
ReuseTotal int64 `json:"reuse_total"`
FetchTotal int64 `json:"fetch_total"`
FetchSuccess int64 `json:"fetch_success"`
FetchBlocked int64 `json:"fetch_blocked"`
FetchFallback int64 `json:"fetch_fallback"`
FetchAllFail int64 `json:"fetch_all_fail"`
FetchByType map[Type]int64 `json:"fetch_by_type"`
BlockByType map[Type]int64 `json:"block_by_type"`
AvgLatency time.Duration `json:"avg_latency"`
P50Latency time.Duration `json:"p50_latency"`
P95Latency time.Duration `json:"p95_latency"`
P99Latency time.Duration `json:"p99_latency"`
SuccessRate float64 `json:"success_rate"`
FallbackRate float64 `json:"fallback_rate"`
}
MetricsSnapshot 指标快照
type NavigateOption ¶
type NavigateOption func(*NavigateOpts)
func WithEarlyWait ¶
func WithEarlyWait(d time.Duration) NavigateOption
func WithWaitStable ¶
func WithWaitStable() NavigateOption
type NavigateResult ¶
type NavigateResult struct {
}
NavigateResult 导航结果
func NavigateAndCheck ¶
func NavigateAndCheck(ctx context.Context, b Browser, url string, detector BlockDetector, options ...NavigateOption) (*NavigateResult, error)
NavigateAndCheck 导航到 URL 并检测 WAF 拦截
type Pool ¶
type Pool struct {
// contains filtered or unexported fields
}
Pool 浏览器实例池
func NewPool ¶
func NewPool(cfg PoolConfig) *Pool
func (*Pool) FetchWithFallback ¶
func (p *Pool) FetchWithFallback(ctx context.Context, url string, chain []Type, detector BlockDetector) (*FetchResult, error)
FetchWithFallback 智能降级抓取
func (*Pool) HasProvider ¶
type PoolConfig ¶
type PoolConfig struct {
MaxInstances int
IdleTimeout time.Duration
AcquireTimeout time.Duration
HealthCheckFreq time.Duration
PingTimeout time.Duration // 复用空闲实例前的存活探测超时,零值取 2s
}
PoolConfig 浏览器池配置
type Provider ¶
type Provider interface {
Type() Type
Create(ctx context.Context, opts AcquireOpts) (Browser, error)
HealthCheck(ctx context.Context) error
Close() error
}
Provider 浏览器实例工厂接口
每种浏览器类型实现一个 Provider,负责创建和管理该类型的实例。
type Task ¶
type Task struct {
// URL 目标地址
URL string
// Chain 降级链 (如 [TypeSurf, TypeRodHeadless])
Chain []Type
}
Task 抓取任务
type TaskResult ¶
type TaskResult struct {
// URL 目标地址
URL string `json:"url"`
// FetchResult 抓取结果 (nil if error)
FetchResult *FetchResult `json:"fetch_result"`
// Err 错误 (如果有)
Err error `json:"-"`
// Duration 执行耗时
Duration time.Duration `json:"duration"`
}
TaskResult 任务执行结果
type WAFBlockedError ¶
type WAFBlockedError struct {
Result BlockResult
URL string
}
WAFBlockedError 携带 WAF 拦截详情的结构化错误
func (*WAFBlockedError) Error ¶
func (e *WAFBlockedError) Error() string
func (*WAFBlockedError) Unwrap ¶
func (e *WAFBlockedError) Unwrap() error
type Worker ¶
type Worker struct {
// contains filtered or unexported fields
}
Worker 并发任务调度器
批量执行抓取任务,通过信号量控制并发数,支持速率限制和结果回调。 结果按原始任务顺序返回。
func NewWorker ¶
func NewWorker(pool *Pool, detector BlockDetector, cfg WorkerConfig) *Worker
NewWorker 创建 Worker
type WorkerConfig ¶
type WorkerConfig struct {
// Concurrency 并发 worker 数量
Concurrency int
// RateLimit 每秒最大请求数 (0 表示不限制)
RateLimit int
// OnResult 每完成一个任务的回调 (可选,在 goroutine 中调用)
// idx 为任务在原始列表中的索引
OnResult func(idx int, result TaskResult)
}
WorkerConfig Worker 配置
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package browserless 提供基于 Browserless v2 的远程浏览器集群 Provider 实现。
|
Package browserless 提供基于 Browserless v2 的远程浏览器集群 Provider 实现。 |
|
Package rod 提供基于 go-rod 的 Chrome 浏览器 Provider 实现。
|
Package rod 提供基于 go-rod 的 Chrome 浏览器 Provider 实现。 |
|
Package surf 提供基于 TLS 指纹伪装的纯 HTTP 客户端 Provider 实现。
|
Package surf 提供基于 TLS 指纹伪装的纯 HTTP 客户端 Provider 实现。 |