gosearch.v0.2.0

v0.2.0 on the Go module proxy

Web search that answers to no one but you.

No API key. No SDK. No account. gosearch queries DuckDuckGo, Bing, Google and Yandex by parsing their public result pages directly — then reads the pages it finds and hands you the content as Markdown.

4 engines·1 tiny dependency·1 stars·MIT licensed·updated Aug 2026
main.go
go get github.com/BugraAkdemir/gosearch

page, err := gosearch.Fetch(ctx, url,
    gosearch.WithMarkdown())
# Kurulum
Paketi kurmak icin [Go 1.25+](https://go.dev) gerekir.

- Depoyu klonla
- Testleri çalıştır

01 · status, honestly

We tell you which engines actually work — before you find out the hard way.

Search engines run anti-bot systems and most wrappers hide that. This is the real picture from live probes of this library.

DuckDuckGoHIGHESTOfficial no-JS HTML endpoint; parser validated against a real captured page.
BingHIGHServed clean organic results even to a flagged datacenter IP in live testing.
GoogleMODERATENo official no-JS endpoint; DOM is regionally A/B tested and changes without notice.
YandexLOWESTAggressive geo/IP-based captcha gating, especially outside Russia.

last live probe: 2026-08-24 · reliability depends more on your network's IP reputation than on client behavior

02 · built for agents

From question to model context in two calls.

Search finds candidate sources across four engines. Fetch reads them and returns clean Markdown — structure intact, boilerplate gone. That is the entire retrieval layer.

STEP / 01

Search

Fallback chain crosses DuckDuckGo → Bing → Google → Yandex. Duplicates collapse; your domain policy applies.

STEP / 02

Fetch + Markdown

WithMarkdown() returns headings, lists, tables and code fences — not a flattened text soup.

STEP / 03

Context

Concatenate top pages and hand them to the model. Freshness stamps (WithDates()) let it prefer current sources.

retrieve.go
results, _ := gosearch.Search(ctx, question, gosearch.DuckDuckGo,
    gosearch.WithFallback(gosearch.Bing),
    gosearch.WithMaxResults(5),
    gosearch.WithDates(),
)

var ctx strings.Builder
for _, r := range results[:2] {
    page, err := gosearch.Fetch(ctx2, r.URL,
        gosearch.WithMarkdown(),   // headings, lists, links preserved
    )
    if err != nil { continue }
    fmt.Fprintf(&ctx, "# %s\n%s\n", page.Title, page.Content)
}
// ctx.String() -> model context

03 · the other way

What you stop dealing with

Hosted search APIs solve reliability by putting a paywall between you and the engine. gosearch solves it with an honest fallback chain instead.

Hosted search API
Sign up, generate, store an API key
Monthly quota, then a bill
Your queries pass through a third party
Down when their service is down
gosearch
go get, import, call Search()
No quota, no bill, ever
Direct HTTP to the engine, nothing in between
Blocked on one engine, falls back to the next

04 · what's in the box

Search finds pages. Fetch reads them. The rest is hardening.

Search()
Query four engines into structured Title/URL/Snippet results.
Fetch()
Readable main content of any URL — nav, ads and scripts stripped.
WithMarkdown()
GitHub-flavored Markdown output: headings, lists, fences, links.
WithFallback()
Name engines in order; blocks and challenges advance automatically.
WithRetries()
Transient failures retry with exponential backoff. Blocks never do.
Domain policy
WithAllowedDomains / WithBlockedDomains filter results your way.
Dedup
Encoding and parameter-order duplicates collapse to one result.
browser/ (opt-in)
Separate module driving a real headless browser for JS-only pages.
pkg.go.dev reference
$ go get github.com/BugraAkdemir/gosearch@latest