# SerpApi Search in Rust [![CI](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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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(¶meter); // 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!