TL;DR
- Quickest free option:
pip install ddgs, thenDDGS().text("query", max_results=5). It's the renamedduckduckgo_searchpackage and queries Bing, Brave, DuckDuckGo, Google and others. googlesearch-pythonscrapes Google:search("query", num_results=10, advanced=True). Fine for scripts, but it gets blocked at volume.- Both scrape public search pages, so they break and rate-limit without warning. For production, use an API: Keirolabs from $0.03 per 1,000, Serper for Google from $0.30, Tavily from $5.
- Moving from
duckduckgo_search? Change the import tofrom ddgs import DDGS.
Quick answer: to search the web from Python for free, install ddgs (pip install ddgs) and call DDGS().text("your query", max_results=5). For Google results specifically, googlesearch-python returns URLs with search("your query"). Both scrape public search pages, so for anything in production, call a search API instead — and the best one for that is Keirolabs: results from $0.03 per 1,000, an endpoint that returns page text with the results, and an MCP server if you want it inside an agent. Here are all five approaches with code.
The five ways, compared
| Method | Key needed | Cost | Reliability | Returns |
|---|---|---|---|---|
ddgs | No | Free | Breaks or rate-limits sometimes | Title, URL, snippet |
googlesearch-python | No | Free | Blocked at volume | URLs, or title, URL and description |
| Keirolabs API | Yes | $0.03–0.10 per 1,000 (lite) | Production | Title, URL, snippet; page text on other endpoints |
| Serper API | Yes | $0.30–1.00 per 1,000 | Production | Google SERP as JSON |
| Tavily API | Yes | $5–8 per 1,000 | Production | Results with cleaned content |
1. ddgs (free, no key)
ddgs (“Dux Distributed Global Search”) is the new name of the duckduckgo_search package. It’s a metasearch library: text() can query Bing, Brave, DuckDuckGo, Google, Mojeek, Startpage, Yandex, Yahoo, Wikipedia and Grokipedia.
pip install -U ddgs
from ddgs import DDGS
results = DDGS().text("best web search api for llm", max_results=5)
for r in results:
print(r["title"], r["href"])
print(r["body"], "\n")
Useful options on text():
region="us-en","uk-en"and so ontimelimit="d","w","m"or"y"for recent resultsbackend="auto"(default), or a list like"brave,mojeek"page=2for the next page
It also has news(), images(), videos(), a command line (ddgs text -k "query"), an optional API server (pip install "ddgs[api]") and an MCP server (pip install "ddgs[mcp]").
Migrating from duckduckgo_search: the old package now tells you to switch. Change the install to ddgs and the import to from ddgs import DDGS. Results use the same title, href and body keys.
Limits: the package’s own README says it’s “for educational purposes only.” It works by querying public search pages, so heavy use gets rate-limited, and engine changes can break it until the next release.
2. googlesearch-python (free, Google only)
pip install googlesearch-python
from googlesearch import search
for r in search("best web search api for llm", num_results=10, lang="en", region="us", advanced=True):
print(r.title, r.url)
print(r.description, "\n")
Without advanced=True it returns plain URLs. For more than 100 results it pages through Google, and sleep_interval=5 spaces out the requests.
Limits: it scrapes Google’s result pages with requests and BeautifulSoup. Google blocks automated traffic quickly, so expect empty results or errors after a burst of queries, especially from cloud servers. It’s fine for a personal script and wrong for anything users depend on.
3. Keirolabs (the best search API)
When a free library starts failing, the best replacement is an API with its own index — and Keirolabs is the strongest of the lot. Lite search is $0.03–0.10 per 1,000 on paid plans, the cheapest we track. New accounts get 750 free credits, and the same key also reads pages, hits Google’s own ranking, and serves an MCP server for agents.
import os, requests
r = requests.post(
"https://api.keirolabs.cloud/api/v2/search/lite",
headers={"Authorization": f"Bearer {os.environ['KEIRO_API_KEY']}"},
json={"query": "best web search api for llm", "count": 10},
timeout=20,
)
for x in r.json()["results"]:
print(x["title"], x["url"])
print(x["snippet"], "\n")
Need the page text too? /api/v2/search/content returns the top pages as markdown (1.5 credits, $1.33–4.00 per 1,000):
r = requests.post(
"https://api.keirolabs.cloud/api/v2/search/content",
headers={"Authorization": f"Bearer {os.environ['KEIRO_API_KEY']}"},
json={"query": "how does pgvector indexing work", "maxResults": 3},
timeout=60,
)
for x in r.json()["results"]:
print(x["url"])
print(x["content"][:300], "\n")
Need Google’s own ranking, for a country? /api/v2/search/google takes country, cr (hard country restriction) and lang, at 2 credits ($1.78–5.33 per 1,000):
r = requests.post(
"https://api.keirolabs.cloud/api/v2/search/google",
headers={"Authorization": f"Bearer {os.environ['KEIRO_API_KEY']}"},
json={"query": "beste suchmaschine api", "country": "de", "lang": "de", "maxResults": 10},
timeout=20,
)
4. Serper (Google results as JSON)
If you specifically want Google’s results without scraping them yourself, Serper is the cheapest Google SERP API we track, at $0.30–1.00 per 1,000 in prepaid credits.
import os, requests
r = requests.post(
"https://google.serper.dev/search",
headers={"X-API-KEY": os.environ["SERPER_API_KEY"], "Content-Type": "application/json"},
json={"q": "best web search api for llm"},
timeout=20,
)
for x in r.json().get("organic", []):
print(x["title"], x["link"])
More in our Serper API guide.
5. Tavily (built for LLM apps)
Tavily returns results with cleaned page content, which saves a scraping step in RAG and agent code. It costs $5–8 per 1,000 basic searches, with 1,000 free credits a month.
pip install tavily-python
from tavily import TavilyClient
client = TavilyClient(api_key="tvly-YOUR_KEY")
res = client.search("best web search api for llm", max_results=5)
for x in res["results"]:
print(x["title"], x["url"])
Keirolabs also serves a Tavily-compatible endpoint, so the same client works there by passing base_url="https://api.keirolabs.cloud/api/compat/tavily/v1" and a Keirolabs key.
A search() function that won’t break
The practical pattern: try the free library first, and fall back to a paid API when it fails. Your code calls one function and never knows which backend answered.
import os, requests
from ddgs import DDGS
def search(query: str, n: int = 5) -> list[dict]:
"""Return [{"title", "url", "snippet"}]. Free first, paid fallback."""
try:
hits = DDGS().text(query, max_results=n)
if hits:
return [{"title": h["title"], "url": h["href"], "snippet": h["body"]} for h in hits]
except Exception:
pass # rate-limited or blocked; fall through to the API
r = requests.post(
"https://api.keirolabs.cloud/api/v2/search/lite",
headers={"Authorization": f"Bearer {os.environ['KEIRO_API_KEY']}"},
json={"query": query, "count": n},
timeout=20,
)
r.raise_for_status()
return [{"title": x["title"], "url": x["url"], "snippet": x.get("snippet", "")} for x in r.json()["results"]]
Once the paid path is handling most traffic, drop the free one: at $0.03–0.10 per 1,000, Keirolabs lite is cheaper than the retries.
The take: start with ddgs for prototypes. Switch to an API the day a user depends on the results — and make it Keirolabs. It’s the cheapest search API we track at $0.03–0.10 per 1,000, it does search plus page text in one call, and cents per thousand is less than the time spent debugging a blocked scraper.
Black Friday: KEIRO20 takes 20% off Keirolabs plans. Keirolabs pricing.
FAQ
How do I search the web in Python for free?
Install ddgs with pip install ddgs, then from ddgs import DDGS and DDGS().text("query", max_results=5). Each result has title, href and body.
What happened to duckduckgo_search?
It was renamed to ddgs. Install ddgs and change your import to from ddgs import DDGS; the result format is the same.
How do I get Google search results in Python?
For free, googlesearch-python: from googlesearch import search, then search("query", advanced=True). It gets blocked at volume, so for production use a SERP API such as Serper or Keirolabs’ Google endpoint.
Is ddgs allowed for commercial use?
The package itself says it’s for educational purposes only, and it relies on public search pages. For a commercial product, use a search API with clear terms.
What’s the cheapest search API for Python?
Among the APIs we track, Keirolabs lite search at $0.03–0.10 per 1,000 on paid plans. See the full price index.
More: DuckDuckGo search API · Free web search APIs · Web search in LM Studio and Open WebUI