LLM4Free Search Module

June 18, 2026 · View on GitHub

Last updated: 2026-03-30 Source: llm4free/search/

LLM4Free's search module provides unified access to search engines through a consistent Python API and CLI. All engines return typed result dataclasses that support both attribute and dict-style access.

Quick Start

from llm4free import DuckDuckGoSearch

search = DuckDuckGoSearch()
results = search.text("python programming", max_results=5)
for r in results:
    print(f"{r['title']}: {r['href']}")

Engine Capabilities

CategoryEngines
textDuckDuckGo, Bing, Brave, Yahoo, Mojeek, Wikipedia
imagesDuckDuckGo, Bing, Brave, Yahoo
videosDuckDuckGo, Brave, Yahoo
newsDuckDuckGo, Bing, Brave, Yahoo
suggestionsDuckDuckGo, Bing, Brave, Yahoo
weatherDuckDuckGo, Yahoo
answersDuckDuckGo
translateDuckDuckGo
mapsDuckDuckGo

Imports

from llm4free.search import (
    DuckDuckGoSearch,  # Full-featured: text, images, videos, news, maps, translate, weather, answers, suggestions
    BingSearch,        # Text, images, news, suggestions
    BraveSearch,       # Text, images, videos, news, suggestions
    YahooSearch,       # Text, images, videos, news, suggestions, weather
    Mojeek,            # Text only
    Wikipedia,         # Text only (encyclopedia)
)

Result Types

All main interfaces (DuckDuckGoSearch, BingSearch, BraveSearch, YahooSearch) return typed dataclasses. Low-level engines (Mojeek, Wikipedia) return TextResult.

from llm4free.search.results import TextResult, ImagesResult, VideosResult, NewsResult

# Both access styles work:
result.title      # attribute
result['title']   # dict-style
result['href']    # URL
result['link']    # alias for href
result['url']     # alias for href

TextResult

FieldTypeAliases for dict access
titlestr
hrefstrlink, url
bodystrsnippet

ImagesResult

FieldType
titlestr
imagestr
thumbnailstr
urlstr
heightint
widthint
sourcestr

VideosResult

FieldType
titlestr
urlstr
thumbnailstr
contentstr
descriptionstr
durationstr
embed_htmlstr
embed_urlstr
publisherstr
uploaderstr

NewsResult

FieldType
titlestr
bodystr
urlstr
datestr
imagestr
sourcestr

DuckDuckGo

The most feature-complete engine. Privacy-focused, no tracking.

from llm4free import DuckDuckGoSearch

ddg = DuckDuckGoSearch()
results = ddg.text(
    keywords="artificial intelligence",
    region="wt-wt",          # Region code
    safesearch="moderate",   # "on", "moderate", "off"
    timelimit="y",           # "d"=day, "w"=week, "m"=month, "y"=year
    backend="api",           # "api" or "html"
    max_results=10,
)
results = ddg.images(
    keywords="nature photography",
    size="large",            # "small", "medium", "large", "wallpaper"
    color="green",           # Color filter
    type_image="photo",      # "photo", "clipart", "line", "animated", "face"
    layout="square",         # "square", "tall", "wide"
    license_image="commercial",
    max_results=50,
)
results = ddg.videos(
    keywords="python tutorials",
    resolution="hd",          # "sd", "hd"
    duration="medium",        # "short", "medium", "long"
    license_videos="creativeCommon",
    max_results=30,
)
results = ddg.news(
    keywords="technology trends",
    timelimit="w",  # Last week
    max_results=20,
)
for item in results:
    print(f"{item['title']} - {item['date']}")
results = ddg.maps(
    keywords="coffee shops",
    place="new york",
    city="New York",
    radius=5,
    max_results=30,
)

Translate

results = ddg.translate(
    keywords="Hola mundo",
    from_lang="es",
    to_lang="en",
)

Weather

weather = ddg.weather("New York")
print(f"Temperature: {weather['current']['temperature_c']}C")

Answers

results = ddg.answers("python programming language")

Suggestions

results = ddg.suggestions("python prog", region="wt-wt")

Bing

from llm4free import BingSearch

bing = BingSearch()

Text Search

results = bing.text(
    keywords="machine learning",
    region="us",
    safesearch="moderate",
    unique=True,              # Deduplicate results
    max_results=10,
)

Image Search

results = bing.images(
    keywords="landscape photography",
    region="us",
    max_results=20,
)

News Search

results = bing.news(
    keywords="AI breakthroughs",
    max_results=15,
)

Suggestions

results = bing.suggestions(
    query="how to learn python",
    region="en-US",
)

Brave

Privacy-focused modern search engine.

from llm4free import BraveSearch

brave = BraveSearch()

Text Search

results = brave.text(
    keywords="cybersecurity",
    region="us-en",
    safesearch="moderate",
    max_results=10,
)

Image Search

results = brave.images(
    keywords="cyberpunk art",
    max_results=15,
)

Video Search

results = brave.videos(
    keywords="python tutorial",
    max_results=10,
)

News Search

results = brave.news(
    keywords="space exploration",
    max_results=10,
)

Suggestions

results = brave.suggestions(
    query="artificial i",
    rich=True,
    country="US",
)

Yahoo

from llm4free import YahooSearch

yahoo = YahooSearch()

Text Search

results = yahoo.text(
    keywords="web development",
    region="us",
    max_results=10,
)

Image Search

results = yahoo.images(
    keywords="landscapes",
    region="us",
    max_results=20,
)

Video Search

results = yahoo.videos(
    keywords="python tutorials",
    max_results=10,
)

News Search

results = yahoo.news(
    keywords="AI news",
    max_results=15,
)

Weather

weather = yahoo.weather("London")

Suggestions

results = yahoo.suggestions("web dev", region="us")

Yep

Privacy-focused, fast search.

from llm4free import YepSearch

yep = YepSearch()

Text Search

results = yep.text(
    keywords="privacy online",
    region="all",
    safesearch="moderate",
    max_results=10,
)

Image Search

results = yep.images(
    keywords="nature photography",
    max_results=10,
)

Suggestions

results = yep.suggestions("privacy", region="all")

Low-Level Engines

These engines only support text search and are accessed via their run() method.

Mojeek

Independent European search engine, privacy-first.

from llm4free.search import Mojeek

mojeek = Mojeek()
results = mojeek.run("privacy tools", region="us-en", max_results=5)

Wikipedia

Encyclopedia search returning article summaries.

from llm4free.search import Wikipedia

wiki = Wikipedia()
results = wiki.run("Quantum Computing", region="us-en", max_results=3)
for r in results:
    print(f"{r['title']}: {r['body'][:200]}")

CLI

The CLI uses --engine (-e) to select the backend. DuckDuckGo is the default.

# Text search
llm4free text -k "python programming"
llm4free text -k "python programming" -e brave
llm4free text -k "quantum physics" -e wikipedia

# Image search
llm4free images -k "cyberpunk art" -e bing

# News
llm4free news -k "space exploration" -e yahoo

# Weather
llm4free weather -l "London"

# Suggestions
llm4free suggestions -q "artificial i"

# Translate
llm4free translate -k "Hola mundo" --to en

See cli.md for the full CLI reference.


Processing Results

Extract URLs

from llm4free import DuckDuckGoSearch

search = DuckDuckGoSearch()
results = search.text("api design", max_results=5)

urls = [r['href'] for r in results]
for url in urls:
    print(url)

Filter by Keyword

results = search.text("python", max_results=20)
official = [r for r in results if "python.org" in r['href']]

Group by Domain

from urllib.parse import urlparse

results = search.text("web development", max_results=15)
grouped = {}
for r in results:
    domain = urlparse(r['href']).netloc
    grouped.setdefault(domain, []).append(r)

for domain, items in sorted(grouped.items(), key=lambda x: len(x[1]), reverse=True):
    print(f"{domain} ({len(items)} results)")

Convert to Dict

results = search.text("python", max_results=5)
dicts = [r.to_dict() for r in results]

Save to JSON

import json

results = search.text("python programming", max_results=10)
with open("results.json", "w") as f:
    json.dump([r.to_dict() for r in results], f, indent=2)

from llm4free import DuckDuckGoSearch, BingSearch, BraveSearch

def search_all(query, max_results=5):
    engines = [DuckDuckGoSearch(), BingSearch(), BraveSearch()]
    seen = set()
    combined = []

    for engine in engines:
        results = engine.text(query, max_results=max_results)
        for r in results:
            url = r['href']
            if url not in seen:
                seen.add(url)
                combined.append(r)
    return combined

results = search_all("python programming", max_results=5)
for r in results:
    print(f"{r['title']}: {r['href']}")

Combining Search with AI

Summarize Results

from llm4free import DuckDuckGoSearch, Meta

search = DuckDuckGoSearch()
results = search.text("quantum computing", max_results=3)

context = "\n".join(f"{r['title']}: {r['body']}" for r in results)
ai = Meta()
summary = ai.chat(f"Summarize these search results:\n{context}")
print(summary)

Research Assistant

from llm4free import DuckDuckGoSearch, Meta

def research(query: str):
    search = DuckDuckGoSearch()
    results = search.text(query, max_results=5)

    context = "Search Results:\n"
    for i, r in enumerate(results, 1):
        context += f"{i}. {r['title']}: {r['body'][:100]}...\n"

    ai = Meta()
    answer = ai.chat(f"{context}\nBased on these results, explain: {query}")

    print(f"Answer: {answer}\n")
    print("Sources:")
    for r in results:
        print(f"  {r['href']}")

research("how does photosynthesis work")

News Analysis

from llm4free import DuckDuckGoSearch, GROQ

search = DuckDuckGoSearch()
news = search.news("artificial intelligence", max_results=3)

news_text = "\n".join(f"{item['title']}: {item['body']}" for item in news)
client = GROQ(api_key="your-key")
analysis = client.chat(f"Key takeaways from this news:\n{news_text}")
print(analysis)

Error Handling

from llm4free import DuckDuckGoSearch

try:
    search = DuckDuckGoSearch()
    results = search.text("python programming", max_results=5)
    print(f"Found {len(results)} results")
except Exception as e:
    print(f"Search failed: {e}")

For rate-limited scenarios, add delays between requests:

import time

for query in ["python", "javascript", "rust"]:
    results = search.text(query, max_results=5)
    print(f"{query}: {len(results)} results")
    time.sleep(1)

Custom Search Engine

Extend BaseSearchEngine to add a new engine:

from llm4free.search.base import BaseSearchEngine
from llm4free.search.results import TextResult

class MyEngine(BaseSearchEngine[TextResult]):
    name = "myengine"
    category = "text"
    provider = "myengine"
    search_url = "https://example.com/search"
    search_method = "GET"
    items_xpath = "//div[@class='result']"
    elements_xpath = {
        "title": ".//h3/a/text()",
        "href": ".//h3/a/@href",
        "body": ".//p/text()",
    }

    def build_payload(self, query, region, safesearch, timelimit, page=1, **kwargs):
        return {"q": query, "p": page}

# Use it
engine = MyEngine()
results = engine.run("test query", max_results=5)

API Reference

DuckDuckGoSearch

MethodSignatureReturns
text(keywords, region="wt-wt", safesearch="moderate", timelimit=None, backend="api", max_results=None)List[TextResult]
images(keywords, region="wt-wt", safesearch="moderate", timelimit=None, size=None, color=None, type_image=None, layout=None, license_image=None, max_results=None)List[ImagesResult]
videos(keywords, region="wt-wt", safesearch="moderate", timelimit=None, resolution=None, duration=None, license_videos=None, max_results=None)List[VideosResult]
news(keywords, region="wt-wt", safesearch="moderate", timelimit=None, max_results=None)List[NewsResult]
answers(keywords)List[Dict]
suggestions(keywords, region="wt-wt")List[Dict]
maps(keywords, place=None, street=None, city=None, county=None, state=None, country=None, postalcode=None, latitude=None, longitude=None, radius=0, max_results=None)List[Dict]
translate(keywords, from_lang=None, to_lang="en")List[Dict]
weather(keywords)WeatherData

BingSearch

MethodSignatureReturns
text(keywords, region="us", safesearch="moderate", max_results=None, unique=True)List[TextResult]
images(keywords, region="us", safesearch="moderate", max_results=None)List[ImagesResult]
news(keywords, region="us", safesearch="moderate", max_results=None)List[NewsResult]
suggestions(query, region="en-US")List[Dict]

BraveSearch

MethodSignatureReturns
text(keywords, region="us-en", safesearch="moderate", max_results=None)List[TextResult]
images(keywords, region="us-en", safesearch="moderate", max_results=None)List[ImagesResult]
videos(keywords, region="us-en", safesearch="moderate", max_results=None)List[VideosResult]
news(keywords, region="us-en", safesearch="moderate", max_results=None)List[NewsResult]
suggestions(query, rich=True, country=None, max_results=None)List[Dict]

YahooSearch

MethodSignatureReturns
text(keywords, region="us", safesearch="moderate", max_results=None)List[TextResult]
images(keywords, region="us", safesearch="moderate", max_results=None)List[ImagesResult]
videos(keywords, region="us", safesearch="moderate", max_results=None)List[VideosResult]
news(keywords, region="us", safesearch="moderate", max_results=None)List[NewsResult]
suggestions(keywords, region="us")List[str]
weather(keywords)List[dict]

Low-Level Engines (Mojeek, Wikipedia)

All share the same run() pattern:

Enginerun() SignatureReturns
Mojeek(*args, **kwargs) — delegates to search()List[TextResult]
Wikipedia(*args, **kwargs) — delegates to search()List[TextResult]