Files
go-extractor/cmd/browser/pkg/browser/flags.go
T
steve c3be14095a
CI / test (push) Successful in 2m16s
CI / build (push) Successful in 2m25s
CI / vet (push) Successful in 2m16s
feat: switch stealth Chromium default channel to consumer Chrome
Playwright's bundled Chromium has a distinct build fingerprint (build ID,
uniform WebGL/codec lists, HeadlessChrome residue) that anti-bot services
increasingly flag. Driving a system-installed Google Chrome via Playwright's
channel option sheds that signal and aligns sec-ch-ua with UA more cleanly.

Changes:
- Add BrowserOptions.Channel string field (chrome, chrome-beta, chromium,
  msedge; empty = default).
- When stealth+headless+Chromium and Channel is empty, default to "chrome"
  (was "chromium"). Explicit Channel values always win, so callers can opt
  back to "chromium" or pick another channel.
- Merge Channel in mergeOptions.
- Expose --channel/--ch flag on cmd/browser for A/B fingerprint testing.

Callers must have the chosen browser installed on the host
(e.g. `playwright install chrome`). Firefox and WebKit paths are untouched.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 17:26:50 +00:00

97 lines
2.2 KiB
Go

package browser
import (
"context"
"time"
"github.com/urfave/cli/v3"
"gitea.stevedudenhoeffer.com/steve/go-extractor"
)
type BrowserFlags []cli.Flag
var Flags = BrowserFlags{
&cli.StringFlag{
Name: "user-agent",
Aliases: []string{"ua"},
Usage: "User-Agent to use for requests",
DefaultText: extractor.DefaultUserAgent,
},
&cli.StringFlag{
Name: "timeout",
Aliases: []string{"t"},
Usage: "Timeout for requests",
DefaultText: "30s",
},
&cli.StringFlag{
Name: "browser",
Aliases: []string{"b"},
Usage: "Browser to use, one of: chromium, firefox, webkit",
DefaultText: "firefox",
},
&cli.StringFlag{
Name: "cookies-file",
Aliases: []string{"c"},
Usage: "cookies.txt file to load cookies from",
DefaultText: "",
},
&cli.BoolFlag{
Name: "visible",
Usage: "If set, the browser will be visible, if not set, the browser will be headless",
DefaultText: "false",
},
&cli.BoolFlag{
Name: "no-stealth",
Usage: "Disable stealth mode (anti-bot-detection evasions are enabled by default)",
DefaultText: "false",
},
&cli.StringFlag{
Name: "channel",
Usage: "Chromium channel to launch (chrome, chrome-beta, chromium, msedge). Only applies when --browser=chromium. Empty = stealth default (chrome).",
Aliases: []string{"ch"},
},
}
func FromCommand(ctx context.Context, cmd *cli.Command) (extractor.Browser, error) {
var opts extractor.BrowserOptions
if ua := cmd.String("user-agent"); ua != "" {
opts.UserAgent = ua
}
if to := cmd.String("timeout"); to != "" {
d, err := time.ParseDuration(to)
if err != nil {
return nil, err
}
opts.Timeout = &d
}
if b := cmd.String("browser"); b != "" {
opts.Browser = extractor.BrowserSelection(b)
}
if cf := cmd.String("cookies-file"); cf != "" {
cookies, err := extractor.LoadCookiesFile(cf)
if err != nil {
return nil, err
}
opts.CookieJar = cookies
}
if cmd.IsSet("visible") {
opts.ShowBrowser = extractor.Bool(cmd.Bool("visible"))
}
if cmd.IsSet("no-stealth") && cmd.Bool("no-stealth") {
opts.Stealth = extractor.Bool(false)
}
if ch := cmd.String("channel"); ch != "" {
opts.Channel = ch
}
return extractor.NewBrowser(ctx, opts)
}