๐ async-search-scraper
May 10, 2026 ยท View on GitHub
Query a dozen search engines from a single async Python call โ and get back a unified, deduplicated list of results.
- ๐ง One unified async API over 12 engines (Bing, Brave, Yahoo, Startpage, AOL, Ask, Tor's Torch, โฆ).
- โก Drop-in CLI for one-shot searches with
print/html/csv/jsonoutput. - ๐งฐ Built-in pagination, deduplication, result filtering, and HTTP/SOCKS proxy support.
๐ Quick start
pip install -r requirements.txt
import asyncio
from search_engines import Bing
async def main():
async with Bing() as engine:
results = await engine.search("my query")
print(results.links())
asyncio.run(main())
That's it โ results.links() gives you a flat list[str] of URLs; results itself iterates over {host, link, title, text} dicts.
๐งญ Supported engines
| Engine | Status | Notes |
|---|---|---|
| Bing | โ Working | |
| Brave | โ Working | Uses the official Brave Search API; set BRAVE_API_KEY or pass api_key=.... |
| Yahoo | โ Working | Handles the GDPR consent redirect automatically. |
| Startpage | โ Working | |
| AOL | โ Working | |
| Torch | ๐ง Tor only | Requires a running TOR proxy (socks5://127.0.0.1:9050). |
| Ask | โ Deprecated | |
| โ Deprecated | ||
| DuckDuckGo | โ Deprecated | |
| Dogpile | โ Deprecated | |
| Mojeek | โ Deprecated | |
| Qwant | โ Deprecated |
๐ Usage as a library
Single engine
import asyncio
from search_engines import Bing
async def main():
async with Bing() as engine:
results = await engine.search("my query", pages=2)
for item in results:
print(item["title"], "โ", item["link"])
asyncio.run(main())
Multiple engines, deduplicated
import asyncio
from search_engines import Bing, Yahoo, Startpage
async def main():
all_links = set()
for cls in (Bing, Yahoo, Startpage):
async with cls() as engine:
engine.ignore_duplicate_urls = True
results = await engine.search("python programming", pages=1)
all_links.update(results.links())
print(f"{len(all_links)} unique URLs")
asyncio.run(main())
Brave (API key)
Note
Brave uses the official Search API. Get a free key at api.search.brave.com and either export BRAVE_API_KEY or pass api_key=... to the constructor.
import asyncio, os
from search_engines import Brave
async def main():
async with Brave(api_key=os.environ["BRAVE_API_KEY"]) as engine:
results = await engine.search("my query")
print(results.links())
asyncio.run(main())
๐ฅ๏ธ Usage as a CLI
python search_engines_cli.py -e bing,yahoo -q "my query" -o json,print
| Flag | Purpose | Default |
|---|---|---|
-q | Search query (required) | โ |
-e | Engine(s), comma-separated, or all | google |
-p | Number of pages to fetch | 20 |
-o | Output: any combination of print, html, csv, json | print |
-n | Output filename (without extension) | search_results/output |
-f | Filter results by url / title / text / host | none |
-i | Drop duplicate URLs across engines | off |
-proxy | HTTP/SOCKS proxy URL (protocol://ip:port) | none |
Typical output:
Searching Bing
page: 1 links: 10
page: 2 links: 20
1 https://www.python.org/ Welcome to Python.org
2 https://en.wikipedia.org/wiki/Python_(...) Python (programming language) - Wikipedia
...
โ๏ธ Configuration
BRAVE_API_KEYโ environment variable read by theBraveengine whenapi_key=isn't passed explicitly.- Proxy โ any URL supported by
aiohttp_socks:http://,https://,socks4://,socks5://. Pass viaBing(proxy="socks5://127.0.0.1:9050")or-proxyon the CLI. - Tunables โ
TIMEOUT,USER_AGENT, default page count, and output directory live insearch_engines/config.py.
๐งฉ Extending โ adding a new engine
Drop a new class into search_engines/engines/, subclass SearchEngine, override _selectors, _first_page, _next_page, then register it in search_engines/engines/__init__.py's search_engines_dict. Mimic bing.py for a pure-HTML engine, or brave.py / ask.py for JSON-driven ones.
๐ฆ Requirements
Python 3.9โ3.13, plus the pinned dependencies in requirements.txt (aiohttp, aiohttp_socks, beautifulsoup4, curl_cffi, requests).
pip install -r requirements.txt
python setup.py install # optional, to install the package itself
๐ License
MIT โ see LICENSE.
Originally created by Tasos M. Adamopoulos โ see Search-Engines-Scraper for the upstream repo.