feature: add stealth mode, launch args, and init scripts to BrowserOptions
All checks were successful
CI / vet (pull_request) Successful in 1m18s
CI / build (pull_request) Successful in 1m22s
CI / test (pull_request) Successful in 1m28s

Add anti-bot-detection evasion support to reduce blocking by sites like
archive.ph. Stealth mode is enabled by default for all browsers and applies
common evasions: navigator.webdriver override, plugin/mimeType spoofing,
window.chrome stub, and outerWidth/outerHeight fixes. For Chromium,
--disable-blink-features=AutomationControlled is also added.

New BrowserOptions fields:
- Stealth *bool: toggle stealth presets (default true)
- LaunchArgs []string: custom browser launch arguments
- InitScripts []string: JavaScript injected before page scripts

Closes #56

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-17 20:10:58 +00:00
parent e8f4d64eb9
commit e94665ff25
6 changed files with 183 additions and 2 deletions

View File

@@ -52,6 +52,21 @@ func initBrowser(opt BrowserOptions) (*browserInitResult, error) {
return nil, ErrInvalidBrowserSelection
}
// Collect launch args and init scripts, starting with any stealth-mode presets.
stealth := opt.Stealth == nil || *opt.Stealth
var launchArgs []string
var initScripts []string
if stealth {
if opt.Browser == BrowserChromium {
launchArgs = append(launchArgs, stealthChromiumArgs...)
}
initScripts = append(initScripts, stealthInitScripts...)
}
launchArgs = append(launchArgs, opt.LaunchArgs...)
initScripts = append(initScripts, opt.InitScripts...)
var browser playwright.Browser
launch := true
@@ -71,9 +86,13 @@ func initBrowser(opt BrowserOptions) (*browserInitResult, error) {
if launch {
headless := opt.ShowBrowser == nil || !*opt.ShowBrowser
browser, err = bt.Launch(playwright.BrowserTypeLaunchOptions{
launchOpts := playwright.BrowserTypeLaunchOptions{
Headless: playwright.Bool(headless),
})
}
if len(launchArgs) > 0 {
launchOpts.Args = launchArgs
}
browser, err = bt.Launch(launchOpts)
if err != nil {
return nil, fmt.Errorf("failed to launch browser: %w", err)
}
@@ -103,6 +122,12 @@ func initBrowser(opt BrowserOptions) (*browserInitResult, error) {
return nil, fmt.Errorf("failed to create browser context: %w", err)
}
for _, script := range initScripts {
if err := bctx.AddInitScript(playwright.Script{Content: &script}); err != nil {
return nil, fmt.Errorf("failed to add init script: %w", err)
}
}
if opt.CookieJar != nil {
cookies, err := opt.CookieJar.GetAll()
if err != nil {
@@ -158,6 +183,15 @@ func mergeOptions(base BrowserOptions, opts []BrowserOptions) BrowserOptions {
if o.ShowBrowser != nil {
base.ShowBrowser = o.ShowBrowser
}
if len(o.LaunchArgs) > 0 {
base.LaunchArgs = append(base.LaunchArgs, o.LaunchArgs...)
}
if len(o.InitScripts) > 0 {
base.InitScripts = append(base.InitScripts, o.InitScripts...)
}
if o.Stealth != nil {
base.Stealth = o.Stealth
}
}
return base
}