An open API service indexing awesome lists of open source software.

https://github.com/serpapi/serpapi-rust

Scrape any major search engine from our easy, fast, scalable and feature rich API powered by SerpApi
https://github.com/serpapi/serpapi-rust

Last synced: 4 months ago
JSON representation

Scrape any major search engine from our easy, fast, scalable and feature rich API powered by SerpApi

Awesome Lists containing this project

README

          

# SerpApi Search in Rust
[![serpapi-rust](https://github.com/serpapi/serpapi-rust/actions/workflows/ci.yml/badge.svg)](https://github.com/serpapi/serpapi-rust/actions/workflows/ci.yml) [![serpapi-rust](https://img.shields.io/crates/v/serpapi.svg)](https://crates.io/crates/serpapi)

This Rust package enables to scrape and parse search results from Google, Bing, Baidu, Yandex, Yahoo, Ebay, Apple, Youtube, Naver, Home depot and more. It's powered by [SerpApi](https://serpapi.com) which delivered a consistent JSON format accross search engines.
SerpApi.com enables to do localized search, leverage advanced search engine features and a lot more...
A completed documentation is available at [SerpApi](https://serpapi.com).

## Installation

To install in your rust application, update Cargo.toml
```sh
serpapi="1.0.0"
```

## Usage

Let's start by searching for Coffee on Google:

```rust
// search example for google
//
use serpapi::serpapi::Client;
use std::collections::HashMap;
use std::env;

#[tokio::main]
async fn main() -> Result<(), Box> {
// Read your private API Key from an environment variable.
// Copy/paste from [https://serpapi.com/dashboard] to your shell:
// ```bash
// export API_key="paste_your_private_api_key"
// ```
let api_key = match env::var_os("API_KEY") {
Some(v) => v.into_string().unwrap(),
None => panic!("$API_KEY environment variable is not set!"),
};

println!("let's initiliaze the client to search on google");
let mut default = HashMap::new();
default.insert("api_key".to_string(), api_key);
default.insert("engine".to_string(), "google".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("q".to_string(), "coffee".to_string());
parameter.insert("engine".to_string(), "google".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let organic_results = results["organic_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of organic_results: {}", organic_results.len());
println!(
" - organic_results first result description: {}",
results["organic_results"][0]
);

// search returns text
println!("--- HTML search ---");
let raw = client.html(html_parameter).await.expect("html content");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())
}
```

[Google search documentation](https://serpapi.com/search-api).
More hands on examples are available below.

#### Documentations

* [Full documentation on SerpApi.com](https://serpapi.com)
* [API health status](https://serpapi.com/status)

For more information how to build a paramaters HashMap see [serpapi.com documentation](https://serpapi.com/search-api)

### Location API

```rust
let default = HashMap::::new();
let client = Client::new(default);
let mut parameter = HashMap::::new();
parameter.insert("q".to_string(), "Austin".to_string());
let data = client.location(parameter).await.expect("request");
let locations = data.as_array().unwrap();
```

It returns the first 3 locations matching Austin (Texas, Texas, Rochester)

### Search Archive API

```rust
let mut default = HashMap::::new();
default.insert("engine".to_string(), "google".to_string());
default.insert("api_key".to_string(), "your_secret_key".to_string());
let client = Client::new(default);

// initialize the search engine
let mut parameter = HashMap::::new();
parameter.insert("q".to_string(), "coffee".to_string());
parameter.insert(
"location".to_string(),
"Austin, TX, Texas, United States".to_string(),
);
let initial_results = client.search(parameter).await.expect("request");
let mut id = initial_results["search_metadata"]["id"].to_string();
// remove extra quote " from string convertion
id = id.replace("\"", "");

println!("{}", initial_results["search_metadata"]);
assert_ne!(id, "");

// search in archive
let archived_results = client.search_archive(&id).await.expect("request");
let archive_id = archived_results["search_metadata"]["id"].as_str();
let search_id = initial_results["search_metadata"]["id"].as_str();
println!("{}", archived_results);
assert_eq!(archive_id, search_id);
```

### Account API
```rust
let client = Client::new(HashMap::::new());
let mut parameter = HashMap::::new();
parameter.insert("api_key".to_string(), "your_secret_key".to_string());
let account = client.account(parameter).await.expect("request");
```

It returns your account information.

### Technical features
- Dynamic JSON decoding using Serde JSON
- Asyncronous HTTP request handle method using tokio and reqwest
- Async tests using Tokio

### References
* https://www.lpalmieri.com/posts/how-to-write-a-rest-client-in-rust-with-reqwest-and-wiremock/
* Serdes JSON

## Examples in rust

To run an example:
```sh
cargo build --example google_search
```
file: (examples/google_search.rs)

The keyword google can be replaced by any supported search engine:
- google
- baidu
- bing
- duckduckgo
- yahoo
- yandex
- ebay
- youtube
- walmart
- home_depot
- apple_app_store
- naver

### Search bing
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "bing".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("q".to_string(), "coffee".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let organic_results = results["organic_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of organic_results: {}", organic_results.len());
println!(
" - organic_results first result description: {}",
results["organic_results"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/bing_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/bing_search.rs)
see: [https://serpapi.com/bing-search-api](https://serpapi.com/bing-search-api)

### Search baidu
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "baidu".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("q".to_string(), "coffee".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let organic_results = results["organic_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of organic_results: {}", organic_results.len());
println!(
" - organic_results first result description: {}",
results["organic_results"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/baidu_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/baidu_search.rs)
see: [https://serpapi.com/baidu-search-api](https://serpapi.com/baidu-search-api)

### Search yahoo
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "yahoo".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("p".to_string(), "coffee".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let organic_results = results["organic_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of organic_results: {}", organic_results.len());
println!(
" - organic_results first result description: {}",
results["organic_results"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/yahoo_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/yahoo_search.rs)
see: [https://serpapi.com/yahoo-search-api](https://serpapi.com/yahoo-search-api)

### Search youtube
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "youtube".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("search_query".to_string(), "coffee".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let video_results = results["video_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of video_results: {}", video_results.len());
println!(
" - video_results first result description: {}",
results["video_results"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/youtube_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/youtube_search.rs)
see: [https://serpapi.com/youtube-search-api](https://serpapi.com/youtube-search-api)

### Search walmart
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "walmart".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("query".to_string(), "coffee".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let organic_results = results["organic_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of organic_results: {}", organic_results.len());
println!(
" - organic_results first result description: {}",
results["organic_results"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/walmart_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/walmart_search.rs)
see: [https://serpapi.com/walmart-search-api](https://serpapi.com/walmart-search-api)

### Search ebay
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "ebay".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("_nkw".to_string(), "coffee".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let organic_results = results["organic_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of organic_results: {}", organic_results.len());
println!(
" - organic_results first result description: {}",
results["organic_results"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/ebay_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/ebay_search.rs)
see: [https://serpapi.com/ebay-search-api](https://serpapi.com/ebay-search-api)

### Search naver
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "naver".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("query".to_string(), "coffee".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let ads_results = results["ads_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of ads_results: {}", ads_results.len());
println!(
" - ads_results first result description: {}",
results["ads_results"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/naver_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/naver_search.rs)
see: [https://serpapi.com/naver-search-api](https://serpapi.com/naver-search-api)

### Search home depot
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "home_depot".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("q".to_string(), "table".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let products = results["products"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of products: {}", products.len());
println!(
" - products first result description: {}",
results["products"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/home_depot_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/home_depot_search.rs)
see: [https://serpapi.com/home-depot-search-api](https://serpapi.com/home-depot-search-api)

### Search apple app store
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "apple_app_store".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("term".to_string(), "coffee".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let organic_results = results["organic_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of organic_results: {}", organic_results.len());
println!(
" - organic_results first result description: {}",
results["organic_results"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/apple_app_store_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/apple_app_store_search.rs)
see: [https://serpapi.com/apple-app-store](https://serpapi.com/apple-app-store)

### Search duckduckgo
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "duckduckgo".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("q".to_string(), "coffee".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let organic_results = results["organic_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of organic_results: {}", organic_results.len());
println!(
" - organic_results first result description: {}",
results["organic_results"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/duckduckgo_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/duckduckgo_search.rs)
see: [https://serpapi.com/duckduckgo-search-api](https://serpapi.com/duckduckgo-search-api)

### Search google
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "google".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("q".to_string(), "coffee".to_string());
parameter.insert("engine".to_string(), "google".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let organic_results = results["organic_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of organic_results: {}", organic_results.len());
println!(
" - organic_results first result description: {}",
results["organic_results"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/google_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/google_search.rs)
see: [https://serpapi.com/search-api](https://serpapi.com/search-api)

### Search google scholar
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "google_scholar".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("q".to_string(), "coffee".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let organic_results = results["organic_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of organic_results: {}", organic_results.len());
println!(
" - organic_results first result description: {}",
results["organic_results"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/google_scholar_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/google_scholar_search.rs)
see: [https://serpapi.com/google-scholar-api](https://serpapi.com/google-scholar-api)

### Search google autocomplete
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "google_autocomplete".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("q".to_string(), "coffee".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let suggestions = results["suggestions"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of suggestions: {}", suggestions.len());
println!(
" - suggestions first result description: {}",
results["suggestions"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/google_autocomplete_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/google_autocomplete_search.rs)
see: [https://serpapi.com/google-autocomplete-api](https://serpapi.com/google-autocomplete-api)

### Search google product
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "google_product".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("q".to_string(), "coffee".to_string());
parameter.insert("product_id".to_string(), "4887235756540435899".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let product_results = results["product_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of product_results: {}", product_results.len());
println!(
" - product_results first result description: {}",
results["product_results"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/google_product_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/google_product_search.rs)
see: [https://serpapi.com/google-product-api](https://serpapi.com/google-product-api)

### Search google reverse image
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "google_reverse_image".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("image_url".to_string(), "https://i.imgur.com/5bGzZi7.jpg".to_string());
parameter.insert("max_results".to_string(), "1".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let image_sizes = results["image_sizes"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of image_sizes: {}", image_sizes.len());
println!(
" - image_sizes first result description: {}",
results["image_sizes"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/google_reverse_image_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/google_reverse_image_search.rs)
see: [https://serpapi.com/google-reverse-image](https://serpapi.com/google-reverse-image)

### Search google events
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "google_events".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("q".to_string(), "coffee".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let events_results = results["events_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of events_results: {}", events_results.len());
println!(
" - events_results first result description: {}",
results["events_results"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/google_events_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/google_events_search.rs)
see: [https://serpapi.com/google-events-api](https://serpapi.com/google-events-api)

### Search google local services
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "google_local_services".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("q".to_string(), "electrician".to_string());
parameter.insert("data_cid".to_string(), "6745062158417646970".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let local_ads = results["local_ads"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of local_ads: {}", local_ads.len());
println!(
" - local_ads first result description: {}",
results["local_ads"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/google_local_services_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/google_local_services_search.rs)
see: [https://serpapi.com/google-local-services-api](https://serpapi.com/google-local-services-api)

### Search google maps
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "google_maps".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("q".to_string(), "pizza".to_string());
parameter.insert("ll".to_string(), "@40.7455096,-74.0083012,15.1z".to_string());
parameter.insert("type".to_string(), "search".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let local_results = results["local_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of local_results: {}", local_results.len());
println!(
" - local_results first result description: {}",
results["local_results"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/google_maps_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/google_maps_search.rs)
see: [https://serpapi.com/google-maps-api](https://serpapi.com/google-maps-api)

### Search google jobs
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "google_jobs".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("q".to_string(), "coffee".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let jobs_results = results["jobs_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of jobs_results: {}", jobs_results.len());
println!(
" - jobs_results first result description: {}",
results["jobs_results"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/google_jobs_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/google_jobs_search.rs)
see: [https://serpapi.com/google-jobs-api](https://serpapi.com/google-jobs-api)

### Search google play
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "google_play".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("q".to_string(), "kite".to_string());
parameter.insert("store".to_string(), "apps".to_string());
parameter.insert("max_results".to_string(), "2".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let organic_results = results["organic_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of organic_results: {}", organic_results.len());
println!(
" - organic_results first result description: {}",
results["organic_results"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/google_play_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/google_play_search.rs)
see: [https://serpapi.com/google-play-api](https://serpapi.com/google-play-api)

### Search google images
```rust
let mut default = HashMap::new();
default.insert("api_key".to_string(), "your_secret_api_key".to_string());
default.insert("engine".to_string(), "google_images".to_string());
// initialize the search engine
let client = Client::new(default);

// let's search for coffee in Austin, TX
let mut parameter = HashMap::new();
parameter.insert("engine".to_string(), "google_images".to_string());
parameter.insert("tbm".to_string(), "isch".to_string());
parameter.insert("q".to_string(), "coffee".to_string());
// copy search parameter for the html search
let mut html_parameter = HashMap::new();
html_parameter.clone_from(&parameter);

// search returns a JSON as serde_json::Value which can be accessed like a HashMap.
println!("waiting...");
let results = client.search(parameter).await?;
let images_results = results["images_results"].as_array().unwrap();
println!("results received");
println!("--- JSON ---");
let status = &results["search_metadata"]["status"];
if status != "Success" {
println!("search failed with status: {}", status);
} else {
println!("search is successfull");

println!(" - number of images_results: {}", images_results.len());
println!(
" - images_results first result description: {}",
results["images_results"][0]
);

// search returns text
println!("--- HTML search ---");
println!(" - raw HTML size {} bytes\n", raw.len());
println!(
" - async search completed with {}\n",
results["search_parameters"]["engine"]
);
}

print!("ok");
Ok(())

```

* source code: [examples/google_images_search.rs](https://github.com/serpapi/serpapi-rust/blob/master/examples/google_images_search.rs)
see: [https://serpapi.com/images-results](https://serpapi.com/images-results)

## License

MIT License

## Continuous integration
We love "true open source" and "continuous integration", and Test Drive Development (TDD).
We are using RSpec to test [our infrastructure around the clock]) using Github Action to achieve the best QoS (Quality Of Service).

The directory spec/ includes specification which serves the dual purposes of examples and functional tests.

Set your secret API key in your shell before running a test.
```bash
export API_KEY="your_secret_key"
cargo test
```

Contributions are welcome. Feel to submit a pull request!