A3S Search
Quick Start
Get up and running with A3S Search in any supported language
Quick Start
Installation
[dependencies]
a3s-search = "0.8"
tokio = { version = "1", features = ["full"] }Headless browser engines (Google, Baidu, Bing China) are enabled by default. HTTP-only:
a3s-search = { version = "0.7", default-features = false }pip install a3s-searchPython 3.9–3.13. Pre-built wheels for Linux (glibc/musl), macOS, and Windows.
npm install @a3s-lab/searchNode.js 16+. Native binary for Linux, macOS, and Windows (x64/arm64).
# Install
brew tap a3s-lab/tap https://github.com/A3S-Lab/homebrew-tap
brew install a3s-search
# Update
brew update && brew upgrade a3s-search
# Uninstall
brew uninstall a3s-search
brew untap a3s-lab/tap # optional: remove the tapmacOS and Linux. Installs the a3s-search CLI binary. See CLI for usage.
Basic Usage
1. Create and Configure
use a3s_search::{Search, SearchQuery};
use a3s_search::engines::{DuckDuckGo, Brave, Wikipedia};
let mut search = Search::new();
search.add_engine(DuckDuckGo::new());
search.add_engine(Brave::new());
search.add_engine(Wikipedia::new());2. Search
let query = SearchQuery::new("rust programming");
let results = search.search(query).await?;
for result in results.items().iter().take(10) {
println!("{}: {}", result.title, result.url);
println!(" Score: {:.2}, Engines: {:?}", result.score, result.engines);
}3. Error Handling
Each engine runs independently — one failure doesn't block others:
for (engine, error) in results.errors() {
eprintln!("Engine '{}' failed: {}", engine, error);
}from a3s_search import A3SSearch
search = A3SSearch()
# Default engines: DuckDuckGo + Wikipedia
response = await search.search("rust programming")
for r in response.results:
print(f"{r.title}: {r.url} (score: {r.score})")
print(f"{response.count} results in {response.duration_ms}ms")import { A3SSearch } from '@a3s-lab/search';
const search = new A3SSearch();
// Default engines: DuckDuckGo + Wikipedia
const response = await search.search('rust programming');
for (const r of response.results) {
console.log(`${r.title}: ${r.url} (score: ${r.score})`);
}
console.log(`${response.count} results in ${response.durationMs}ms`);Search with Options
use a3s_search::{SearchQuery, SafeSearch, TimeRange, EngineCategory};
let query = SearchQuery::new("rust async")
.with_language("en-US")
.with_safesearch(SafeSearch::Moderate)
.with_page(1)
.with_time_range(TimeRange::Month)
.with_categories(vec![EngineCategory::General])
.with_engines(vec!["ddg".into(), "brave".into(), "bing".into()]);response = await search.search("rust async",
engines=["ddg", "brave", "bing"],
limit=5,
timeout=15,
)const response = await search.search('rust async', {
engines: ['ddg', 'brave', 'bing'],
limit: 5,
timeout: 15,
});Chinese Search Engines
use a3s_search::engines::{Sogou, So360};
let mut search = Search::new();
search.add_engine(Sogou::new());
search.add_engine(So360::new());
let results = search.search(SearchQuery::new("Rust 编程语言")).await?;response = await search.search("Rust 编程语言", engines=["sogou", "360"])const response = await search.search('Rust 编程语言', {
engines: ['sogou', '360'],
});With Proxy Pool (Rust)
Rotate proxies per request for anti-crawler protection:
use std::sync::Arc;
use a3s_search::{Search, SearchQuery, PooledHttpFetcher, PageFetcher};
use a3s_search::engines::{DuckDuckGo, DuckDuckGoParser};
use a3s_search::proxy::{ProxyPool, ProxyConfig, ProxyProtocol, ProxyStrategy};
let pool = Arc::new(ProxyPool::with_proxies(vec![
ProxyConfig::new("proxy1.example.com", 8080),
ProxyConfig::new("proxy2.example.com", 8080)
.with_protocol(ProxyProtocol::Socks5),
]).with_strategy(ProxyStrategy::RoundRobin));
let fetcher: Arc<dyn PageFetcher> = Arc::new(PooledHttpFetcher::new(Arc::clone(&pool)));
let mut search = Search::new();
search.add_engine(DuckDuckGo::with_fetcher(DuckDuckGoParser, fetcher));
let results = search.search(SearchQuery::new("rust programming")).await?;
// Toggle at runtime (thread-safe via AtomicBool)
pool.set_enabled(false); // direct connection
pool.set_enabled(true); // re-enable rotationSee Proxy for dynamic providers and SDK usage.
With Health Monitor (Rust)
Automatically suspend engines after repeated failures:
use a3s_search::{Search, HealthConfig};
use std::time::Duration;
let mut search = Search::with_health_config(HealthConfig {
max_failures: 3,
suspend_duration: Duration::from_secs(120),
});
search.add_engine(DuckDuckGo::new());
search.add_engine(Brave::new());See Configuration for HCL config files.