From 090f816c533eb4621e51b2813ebf24da54f1cc4b Mon Sep 17 00:00:00 2001 From: audrey-serpapi Date: Wed, 14 Oct 2026 16:08:33 -0400 Subject: [PATCH 1/4] edited: quickstart, added: features, response formats, configuration, search asynchronous, more examples, reordered: examples, headers like documentation, removed: 'Markdown output for AI agents' section (as it was already included in the response formats) --- README.md | 508 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 402 insertions(+), 106 deletions(-) diff --git a/README.md b/README.md index 2af6912..0d27090 100644 --- a/README.md +++ b/README.md @@ -1,51 +1,58 @@ # SerpApi Python Library & Package [![Package](https://img.shields.io/pypi/v/serpapi?color=green)](https://pypi.org/project/serpapi) [![serpapi-python](https://github.com/serpapi/serpapi-python/actions/workflows/ci.yml/badge.svg)](https://github.com/serpapi/serpapi-python/actions/workflows/ci.yml) -Integrate search data into your AI workflow, RAG / fine-tuning, or Python application using this official wrapper for [SerpApi](https://serpapi.com). +Integrate search data into your AI workflow, RAG / fine-tuning, or Python application using this official [SerpApi Python SDK](https://serpapi.com/integrations/python). SerpApi supports Google, Google Maps, Google Shopping, Baidu, Yandex, Yahoo, eBay, App Stores, and [more](https://serpapi.com). -Query a vast range of data at scale, including web search results, flight schedules, stock market data, news headlines, and [more](https://serpapi.com). - ## Installation -To install the `serpapi` package, simply run the following command: +Python 3.6 or later is required. + +To install the `serpapi` package, simply run the following command inside your Python virtual environment: ```bash $ pip install serpapi ``` -Please note that this package is separate from the legacy `serpapi` module, which is available on PyPi as `google-search-results`. This package is maintained by SerpApi, and is the recommended way to access the SerpApi service from Python. +> Please note that this package is separate from the legacy `serpapi` module, +> which is available on PyPi as `google-search-results`. +> This package is maintained by SerpApi, and is the recommended way to access the +> SerpApi service from Python. + +## Quickstart + +[Create a SerpApi account](https://serpapi.com/dashboard) to get your API key, then store it in an environment variable: -## Quick start +```bash +export SERPAPI_KEY="your_api_key" +``` + +Environment variables are a secure, safe, and easy way to manage secrets. +Python accesses these variables from `os.environ["SERPAPI_KEY"]`. -Let's start by searching for Coffee on Google: +Run a Google search and access the results as a Python `Dictionary`: ```python import os import serpapi +from pprint import pprint -client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) +client = serpapi.Client(api_key=os.environ["SERPAPI_KEY"]) results = client.search({ "engine": "google", "q": "coffee" }) -print(results) +pprint(results) ``` The `results` variable now contains a `SerpResults` object, which acts just like a standard dictionary, with some convenient functions added on top. -This example runs a search for "coffee" on Google. It then returns the results as a regular Python Hash. - See the [playground](https://serpapi.com/playground) to generate your own code. - -The SerpApi key can be obtained from [serpapi.com/signup](https://serpapi.com/users/sign_up?plan=free). +This example runs a search for "coffee" on Google. It then returns the results as a regular Python Hash. See the playground to generate your own code. -Environment variables are a secure, safe, and easy way to manage secrets. - Set `export SERPAPI_KEY=` in your shell. - Python accesses these variables from `os.environ["SERPAPI_KEY"]`. -### Error handling +### Error Handling Unsuccessful requests raise `serpapi.HTTPError` or `serpapi.TimeoutError` exceptions. The returned status code will reflect the sort of error that occurred, please refer to [Status and Error Codes Documentation](https://serpapi.com/api-status-and-error-codes) for more details. @@ -72,217 +79,534 @@ except serpapi.TimeoutError as e: # Handle timeout print(f"The request timed out: {e}") ``` +## Features -## Documentation +- **Asynchronous searches** for submitting non-blocking jobs and retrieving completed results from the Search Archive API. +- **Persistent connections and connection pooling** for reusing HTTP connections across searches. +- Search results as **Python dictionaries** with `search`, token-efficient **Markdown** with `md`, or raw **search-engine HTML** with `html`. +- SDK methods for the [Image API](https://serpapi.com/image-api), [Location API](https://serpapi.com/locations-api), [Search Archive API](https://serpapi.com/search-archive-api), and [Account API](https://serpapi.com/account-api). +- **Configurable HTTP timeouts** established by setting `timeout` in the client. -Documentation is [available on Read the Docs](https://serpapi-python.readthedocs.io/en/latest/). +## Response Formats -Change history is [available on GitHub](https://github.com/serpapi/serpapi-python/blob/master/HISTORY.md). +Use `search` and default output (none) for structured results decoded into a `Dictionary`: -### Markdown output for AI agents +```python +results = client.search({ + "engine": "google", + "q": "coffee" +}) +``` -For AI agents and LLM workflows, use `output="md"`. It returns search results with clean headings, links, and tables while using roughly half the tokens of JSON on average. +Use `md` output for a token-efficient Markdown String optimized for LLMs and AI agents: ```python markdown = client.search({ "engine": "google", "q": "coffee", - "output": "md", + "output": "md" +}) +``` + +Use `html` output when you need the raw search-engine response: +```python +raw_html = client.search({ + "engine": "google", + "q": "coffee", + "output": "html" +}) +``` + +Archived results are also available as Markdown with +`client.search_archive(search_id=search_id, output="md")`. + +Learn more about [SerpApi Markdown output](https://serpapi.com/markdown-output). + +## Configuration + +Set defaults when creating a client, then override search parameters in individual calls: + +```python +client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY"), timeout=120) +results = client.search({ + "engine": "google", + "q": "coffee", +}) +``` +|Option | Default | Description| +|-------|---------|------------| +| `api_key` | None | Your SerpApi API key. Use an environment variable rather than committing it to source control. | +| `engine` | None | The search engine used by default, such as `google` or `google_maps`. | +| `timeout` | `120` | Timeout in seconds for non-persistent HTTP requests. | +| `async` | false | Submits searches without waiting for them to complete. It can be set on the client or per search.| + + +Search-engine-specific parameters can also be supplied when creating the client or calling `search`. Parameters passed to search override client defaults. + +### Search Asynchronous + +Search API features non-blocking search using the option: `async=true`. + +- Non-blocking - `async=true` - a single parent process can handle unlimited concurrent searches. +- Blocking - `async=false` - many processes must be forked and synchronized to handle concurrent searches. This strategy is I/O usage because each client would hold a network connection. + +> **Note:** `async` is a reserved keyword in Python 3.7+, so pass it inside the parameters dictionary (`{"async": True}`) rather than as a keyword argument. + +Here is an example of asynchronous searches using Python: + +```python +import os +import re +import time +from queue import Queue + +import serpapi + +company_list = ["meta", "amazon", "apple", "netflix", "google"] +client = serpapi.Client(api_key=os.environ["SERPAPI_KEY"]) +schedule_search = Queue() +result = None + +for company in company_list: + result = client.search({"engine": "google", "q": company, "async": True}) + if re.search(r"Cached", result["search_metadata"]["status"]): + print(f"{company}: search results found in cache for: {company}") + + schedule_search.put(result["search_metadata"]["id"]) + +print(f"Last search submitted at: {result['search_metadata']['created_at']}") + +print("wait 10s for all requests to be completed") +time.sleep(10) + +print("wait until all searches are cached or success") +while not schedule_search.empty(): + search_id = schedule_search.get() + + search_archived = client.search_archive(search_id=search_id) + + company = search_archived["search_parameters"]["q"] + status = search_archived["search_metadata"]["status"] + + if re.search(r"Cached|Success", status): + print(f"{company}: search results found in archive for: {company}") + continue + + if status == "Error": + print(f"{company}: search failed: {search_archived.get('error')}") + continue + + schedule_search.put(search_id) + time.sleep(1) + +print("done") +``` + +This code batches searches into a [queue](https://en.wikipedia.org/wiki/Queue_(abstract_data_type)). +Each search can take a few seconds to complete, so by the time the first ID is popped, its results are usually already in the archive. Searches that are still processing are put back in the queue and checked again. + +## Basic Examples in Python + +Here are some examples for some of our most popular APIs. You can find the full list of supported engines and parameters in our [documentation](https://serpapi.com/search-engine-apis). + +### Google Shopping + +Scrape Google Shopping results with product names, prices, ratings, and merchant information. + +```python +import serpapi +import os +from pprint import pprint + +client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) +results = client.search({ + "engine": "google_shopping", + "q": "Macbook M4" +}) +shopping_results = results["shopping_results"] +pprint(shopping_results) +``` + +[See documentation](https://serpapi.com/google-shopping-api) + +#### Google Shopping Light + +A [light variant](https://serpapi.com/google-shopping-light-api) engine called `google_shopping_light` is also available for faster, lower-cost shopping searches. + +### Google Images + +Scrape Google Images search results, including image URLs, thumbnails, titles, and source pages. + +```python +import os +import serpapi +from pprint import pprint + +client = serpapi.Client(api_key=os.getenv("API_KEY")) +results = client.search({ + 'engine': 'google_images', + 'q': 'coffee', +}) +pprint(results) +``` + +[See documentation](https://serpapi.com/google-images-api) + +#### Google Images Light + +A [light variant](https://serpapi.com/google-images-light-api) engine called `google_images_light` is also available for faster, lower-cost image searches. + +### Google Lens with Image URL or Upload + +Google Lens accepts either a publicly accessible image URL or an uploaded +image. To search by URL, pass the URL directly: + +```python +import os +import serpapi +from pprint import pprint + +client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) +results = client.search({ + "engine": "google_lens", + "url": "https://i.imgur.com/HBrB8p0.png", +}) +pprint(results) +``` + +To search a local image, place a file named `image.png` in your working directory, upload it, and pass its temporary `image_id` to Google Lens: + +```python +upload = client.upload_image("image.png") +results = client.search({ + "engine": "google_lens", + "image_id": upload["image_id"], +}) +``` + +Uploaded images can be JPG/JPEG, PNG, or WebP files up to 500 KB. The returned +`image_id` expires after 10 minutes. + +[See Image API documentation](https://serpapi.com/image-api) · [See Google Lens image upload documentation](https://serpapi.com/google-lens-upload-an-image) + +### Google Trends + +Track search interest over time and compare the popularity of search terms. + +```python +import os +import serpapi +from pprint import pprint + +client = serpapi.Client(api_key=os.getenv("API_KEY")) +results = client.search({ + "engine": "google_trends", + "q": "coffee", + "data_type": "TIMESERIES" }) +interest_over_time = results["interest_over_time"] +pprint(interest_over_time) ``` -Markdown works across SerpApi APIs and is returned as a plain Python string. See [Markdown Output for AI Agents](https://serpapi.com/markdown-output.md) for details. +[See Documentation](https://serpapi.com/google-trends-api) -Raw HTML is also available with `output="html"` and is returned as a plain Python string. +### Google Flights -## Basic examples +Search flight routes, schedules, prices, and booking options. + +> Note: The google_flights engine does not use q. +> Specify route and date parameters such as departure_id, arrival_id, outbound_date, and return_date. -### Search Bing ```python +import serpapi import os +from datetime import date, timedelta +from pprint import pprint + +client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) +outbounding = date.today() +returning = outbounding + timedelta(weeks=2) + +results = client.search({ + "engine": "google_flights", + "departure_id": "LAX", + "arrival_id": "AUS", + "outbound_date": outbounding, + "return_date": returning +}) +best_flights = results["best_flights"] +pprint(best_flights) +``` + +[See documentation](https://serpapi.com/google-flights-api) + +### Google AI Mode API + +The Google AI Mode API returns AI-generated answers with structured text blocks, references, images, products, and more. + +```python import serpapi +import os +from pprint import pprint + +client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) +results = client.search({ + "engine": "google_ai_mode", + "q": "best coffee maker" +}) +text_blocks = results["text_blocks"] +pprint(text_blocks) +``` + +[See documentation](https://serpapi.com/google-ai-mode-api) + +### Bing Search + +Scrape Bing web search results, including organic results, ads, related searches, and more. + +```python +import os +import serpapi +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ 'engine': 'bing', 'q': 'coffee' }) +pprint(results) +``` +[See documentation](https://serpapi.com/bing-search-api) + +### DuckDuckGo Search + +Scrape DuckDuckGo search results, including organic results, ads, knowledge graphs, and related searches. + +```python +import os +import serpapi +from pprint import pprint + +client = serpapi.Client(api_key=os.getenv("API_KEY")) +results = client.search({ + 'engine': 'duckduckgo', + 'q': 'coffee', +}) +pprint(results) ``` -- API Documentation: [serpapi.com/bing-search-api](https://serpapi.com/bing-search-api) +[See Documentation](https://serpapi.com/duckduckgo-search-api) + +### Baidu Search + +Scrape Baidu search results, including organic results, answer boxes, and related searches. -### Search Baidu ```python import os import serpapi +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ 'engine': 'baidu', 'q': 'coffee', }) +pprint(results) ``` -- API Documentation: [serpapi.com/baidu-search-api](https://serpapi.com/baidu-search-api) +[See documentation](https://serpapi.com/baidu-search-api) + +### Amazon Search + +Scrape Amazon product search results, including product names, prices, ratings, reviews, and availability. + +> Note: The `amazon` engine uses the `k` parameter for a keyword search, not `q`. -### Search Yahoo +```python +import serpapi +import os +from pprint import pprint + +client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) +results = client.search({ + "engine": "amazon", + "k": "Coffee", + "amazon_domain": "amazon.com" +}) +organic_results = results["organic_results"] +pprint(organic_results) +``` + +[See documentation](https://serpapi.com/amazon-search-api) + +### Yahoo Search ```python import os import serpapi +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ 'engine': 'yahoo', 'p': 'coffee', }) +pprint(results) ``` -- API Documentation: [serpapi.com/yahoo-search-api](https://serpapi.com/yahoo-search-api) + [serpapi.com/yahoo-search-api](https://serpapi.com/yahoo-search-api) -### Search YouTube +### YouTube Search ```python import os import serpapi +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ 'engine': 'youtube', 'search_query': 'coffee', }) +pprint(results) ``` -- API Documentation: [serpapi.com/youtube-search-api](https://serpapi.com/youtube-search-api) + [serpapi.com/youtube-search-api](https://serpapi.com/youtube-search-api) ### Search Walmart ```python import os import serpapi +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ 'engine': 'walmart', 'query': 'coffee', }) +pprint(results) ``` -- API Documentation: [serpapi.com/walmart-search-api](https://serpapi.com/walmart-search-api) + [serpapi.com/walmart-search-api](https://serpapi.com/walmart-search-api) ### Search eBay ```python import os import serpapi +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ 'engine': 'ebay', '_nkw': 'coffee', }) +pprint(results) ``` -- API Documentation: [serpapi.com/ebay-search-api](https://serpapi.com/ebay-search-api) + [serpapi.com/ebay-search-api](https://serpapi.com/ebay-search-api) ### Search Naver ```python import os import serpapi +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ 'engine': 'naver', 'query': 'coffee', }) +pprint(results) ``` -- API Documentation: [serpapi.com/naver-search-api](https://serpapi.com/naver-search-api) + [serpapi.com/naver-search-api](https://serpapi.com/naver-search-api) ### Search Home Depot ```python import os import serpapi +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ 'engine': 'home_depot', 'q': 'chair', }) +pprint(results) ``` -- API Documentation: [serpapi.com/home-depot-search-api](https://serpapi.com/home-depot-search-api) + [serpapi.com/home-depot-search-api](https://serpapi.com/home-depot-search-api) ### Search Apple App Store ```python import os import serpapi +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ 'engine': 'apple_app_store', 'term': 'coffee', }) +pprint(results) ``` -- API Documentation: [serpapi.com/apple-app-store](https://serpapi.com/apple-app-store) - -### Search DuckDuckGo -```python -import os -import serpapi - -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'duckduckgo', - 'q': 'coffee', -}) -``` -- API Documentation: [serpapi.com/duckduckgo-search-api](https://serpapi.com/duckduckgo-search-api) +[See documentation](https://serpapi.com/apple-app-store) ### Search Google ```python import os import serpapi +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ 'engine': 'google', 'q': 'coffee' }) +pprint(results) ``` -- API Documentation: [serpapi.com/search-api](https://serpapi.com/search-api) + [See documentation](https://serpapi.com/search-api) ### Search Google Scholar ```python import os import serpapi +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ 'engine': 'google_scholar', 'q': 'coffee', }) +pprint(results) ``` -- API Documentation: [serpapi.com/google-scholar-api](https://serpapi.com/google-scholar-api) + [See documentation](https://serpapi.com/google-scholar-api) ### Search Google Autocomplete ```python import os import serpapi +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ 'engine': 'google_autocomplete', 'q': 'coffee', }) +pprint(results) ``` -- API Documentation: [serpapi.com/google-autocomplete-api](https://serpapi.com/google-autocomplete-api) + [See documentation](https://serpapi.com/google-autocomplete-api) ### Search Google Immersive Product ```python import os import serpapi +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ 'engine': 'google_immersive_product', 'page_token': 'eyJlaSI6Im5ZVmxaOXVVTDY2X3A4NFBqTnZELUFjIiwicHJvZHVjdGlkIjoiIiwiY2F0YWxvZ2lkIjoiNTE1NDU2NTc1NTc5MzcxMDY3NSIsImhlYWRsaW5lT2ZmZXJEb2NpZCI6IjI1MDkyMjcwMDUzMjk2NzQwODMiLCJpbWFnZURvY2lkIjoiMTYzOTg5MjU0MDcwMDU4MDA1NTQiLCJyZHMiOiJQQ18zNDg4MDE0MTg3ODgxNzc5NjU0fFBST0RfUENfMzQ4ODAxNDE4Nzg4MTc3OTY1NCIsInF1ZXJ5IjoibGcrdHYiLCJncGNpZCI6IjM0ODgwMTQxODc4ODE3Nzk2NTQiLCJtaWQiOiI1NzY0NjI3ODM3Nzc5MTUzMTMiLCJwdnQiOiJoZyIsInV1bGUiOm51bGx9=', }) +pprint(results) ``` -- API Documentation: [serpapi.com/google-immersive-product-api](https://serpapi.com/google-immersive-product-api) + [See documentation](https://serpapi.com/google-immersive-product-api) ### Search Google Reverse Image ```python import os import serpapi +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ @@ -290,44 +614,16 @@ results = client.search({ 'image_url': 'https://i.imgur.com/5bGzZi7.jpg', 'max_results': '1', }) +pprint(results) ``` -- API Documentation: [serpapi.com/google-reverse-image](https://serpapi.com/google-reverse-image) - -### Search Google Lens by image URL or upload - -Google Lens accepts either a publicly accessible image URL or an uploaded -image. To search by URL, pass the URL directly: - -```python -import os -import serpapi - -client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) -results = client.search({ - "engine": "google_lens", - "url": "https://i.imgur.com/HBrB8p0.png", -}) -``` + [See documentation](https://serpapi.com/google-reverse-image) -To search a local image, place a file named `image.png` in your working directory, upload it, and pass its temporary `image_id` to Google Lens: - -```python -upload = client.upload_image("image.png") -results = client.search({ - "engine": "google_lens", - "image_id": upload["image_id"], -}) -``` - -Uploaded images can be JPG/JPEG, PNG, or WebP files up to 500 KB. The returned -`image_id` expires after 10 minutes. - -- API Documentation: [Google Lens image uploads](https://serpapi.com/google-lens-upload-an-image), [Image API](https://serpapi.com/image-api) ### Search Google Local Services ```python import os import serpapi +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ @@ -335,14 +631,15 @@ results = client.search({ 'q': 'electrician', 'data_cid': '6745062158417646970', }) +pprint(results) ``` -- API Documentation: [serpapi.com/google-local-services-api](https://serpapi.com/google-local-services-api) + [See documentation](https://serpapi.com/google-local-services-api) ### Search Google Maps ```python import os import serpapi - +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ @@ -351,27 +648,30 @@ results = client.search({ 'll': '@40.7455096,-74.0083012,15.1z', 'type': 'search', }) +pprint(results) ``` -- API Documentation: [serpapi.com/google-maps-api](https://serpapi.com/google-maps-api) + [See documentation](https://serpapi.com/google-maps-api) ### Search Google Jobs ```python import os import serpapi - +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ 'engine': 'google_jobs', 'q': 'software engineer', }) +pprint(results) ``` -- API Documentation: [serpapi.com/google-jobs-api](https://serpapi.com/google-jobs-api) + [See documentation](https://serpapi.com/google-jobs-api) ### Search Google Play ```python import os import serpapi +from pprint import pprint client = serpapi.Client(api_key=os.getenv("API_KEY")) results = client.search({ @@ -379,22 +679,16 @@ results = client.search({ 'q': 'kite', 'store': 'apps', }) +pprint(results) ``` -- API Documentation: [serpapi.com/google-play-api](https://serpapi.com/google-play-api) + [See documentation](https://serpapi.com/google-play-api) -### Search Google Images -```python -import os -import serpapi -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'google_images', - 'tbm': 'isch', - 'q': 'coffee', -}) -``` -- API Documentation: [serpapi.com/google-images-api](https://serpapi.com/google-images-api) +## Documentation + +Documentation is [available on Read the Docs](https://serpapi-python.readthedocs.io/en/latest/). + +Change history is [available on GitHub](https://github.com/serpapi/serpapi-python/blob/master/HISTORY.md). ## License @@ -402,4 +696,6 @@ MIT License. ## Contributing -See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, testing, and publishing instructions. +Contributions are welcome. Make sure to read our [contributing guide](CONTRIBUTING.md). + +© 2026 [SerpApi](https://serpapi.com/) \ No newline at end of file From d5a2eda511598ea1660b3e246706d6c03710e4ea Mon Sep 17 00:00:00 2001 From: audrey-serpapi Date: Wed, 14 Oct 2026 16:54:09 -0400 Subject: [PATCH 2/4] remove persistent connection --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 0d27090..ad9e402 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,6 @@ except serpapi.TimeoutError as e: ## Features - **Asynchronous searches** for submitting non-blocking jobs and retrieving completed results from the Search Archive API. -- **Persistent connections and connection pooling** for reusing HTTP connections across searches. - Search results as **Python dictionaries** with `search`, token-efficient **Markdown** with `md`, or raw **search-engine HTML** with `html`. - SDK methods for the [Image API](https://serpapi.com/image-api), [Location API](https://serpapi.com/locations-api), [Search Archive API](https://serpapi.com/search-archive-api), and [Account API](https://serpapi.com/account-api). - **Configurable HTTP timeouts** established by setting `timeout` in the client. From 85cc63348d22eaeb4d1c33026e49b1a7eed071a0 Mon Sep 17 00:00:00 2001 From: audrey-serpapi Date: Thu, 15 Oct 2026 15:38:41 -0400 Subject: [PATCH 3/4] keep persistent and standardize examples --- README.md | 247 +----------------------------------------------------- 1 file changed, 1 insertion(+), 246 deletions(-) diff --git a/README.md b/README.md index ad9e402..0d7ff6d 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ except serpapi.TimeoutError as e: ## Features - **Asynchronous searches** for submitting non-blocking jobs and retrieving completed results from the Search Archive API. +- **Persistent connections and connection pooling** for reusing HTTP connections across searches. - Search results as **Python dictionaries** with `search`, token-efficient **Markdown** with `md`, or raw **search-engine HTML** with `html`. - SDK methods for the [Image API](https://serpapi.com/image-api), [Location API](https://serpapi.com/locations-api), [Search Archive API](https://serpapi.com/search-archive-api), and [Account API](https://serpapi.com/account-api). - **Configurable HTTP timeouts** established by setting `timeout` in the client. @@ -436,252 +437,6 @@ pprint(organic_results) [See documentation](https://serpapi.com/amazon-search-api) -### Yahoo Search -```python -import os -import serpapi -from pprint import pprint - -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'yahoo', - 'p': 'coffee', -}) -pprint(results) -``` - [serpapi.com/yahoo-search-api](https://serpapi.com/yahoo-search-api) - -### YouTube Search -```python -import os -import serpapi -from pprint import pprint - -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'youtube', - 'search_query': 'coffee', -}) -pprint(results) -``` - [serpapi.com/youtube-search-api](https://serpapi.com/youtube-search-api) - -### Search Walmart -```python -import os -import serpapi -from pprint import pprint - -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'walmart', - 'query': 'coffee', -}) -pprint(results) -``` - [serpapi.com/walmart-search-api](https://serpapi.com/walmart-search-api) - -### Search eBay -```python -import os -import serpapi -from pprint import pprint - -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'ebay', - '_nkw': 'coffee', -}) -pprint(results) -``` - [serpapi.com/ebay-search-api](https://serpapi.com/ebay-search-api) - -### Search Naver -```python -import os -import serpapi -from pprint import pprint - -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'naver', - 'query': 'coffee', -}) -pprint(results) -``` - [serpapi.com/naver-search-api](https://serpapi.com/naver-search-api) - -### Search Home Depot -```python -import os -import serpapi -from pprint import pprint - -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'home_depot', - 'q': 'chair', -}) -pprint(results) -``` - [serpapi.com/home-depot-search-api](https://serpapi.com/home-depot-search-api) - -### Search Apple App Store -```python -import os -import serpapi -from pprint import pprint - -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'apple_app_store', - 'term': 'coffee', -}) -pprint(results) -``` -[See documentation](https://serpapi.com/apple-app-store) - -### Search Google -```python -import os -import serpapi -from pprint import pprint - -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'google', - 'q': 'coffee' -}) -pprint(results) -``` - [See documentation](https://serpapi.com/search-api) - -### Search Google Scholar -```python -import os -import serpapi -from pprint import pprint - -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'google_scholar', - 'q': 'coffee', -}) -pprint(results) -``` - [See documentation](https://serpapi.com/google-scholar-api) - -### Search Google Autocomplete -```python -import os -import serpapi -from pprint import pprint - -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'google_autocomplete', - 'q': 'coffee', -}) -pprint(results) -``` - [See documentation](https://serpapi.com/google-autocomplete-api) - -### Search Google Immersive Product -```python -import os -import serpapi -from pprint import pprint - -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'google_immersive_product', - 'page_token': 'eyJlaSI6Im5ZVmxaOXVVTDY2X3A4NFBqTnZELUFjIiwicHJvZHVjdGlkIjoiIiwiY2F0YWxvZ2lkIjoiNTE1NDU2NTc1NTc5MzcxMDY3NSIsImhlYWRsaW5lT2ZmZXJEb2NpZCI6IjI1MDkyMjcwMDUzMjk2NzQwODMiLCJpbWFnZURvY2lkIjoiMTYzOTg5MjU0MDcwMDU4MDA1NTQiLCJyZHMiOiJQQ18zNDg4MDE0MTg3ODgxNzc5NjU0fFBST0RfUENfMzQ4ODAxNDE4Nzg4MTc3OTY1NCIsInF1ZXJ5IjoibGcrdHYiLCJncGNpZCI6IjM0ODgwMTQxODc4ODE3Nzk2NTQiLCJtaWQiOiI1NzY0NjI3ODM3Nzc5MTUzMTMiLCJwdnQiOiJoZyIsInV1bGUiOm51bGx9=', -}) -pprint(results) -``` - [See documentation](https://serpapi.com/google-immersive-product-api) - -### Search Google Reverse Image -```python -import os -import serpapi -from pprint import pprint - -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'google_reverse_image', - 'image_url': 'https://i.imgur.com/5bGzZi7.jpg', - 'max_results': '1', -}) -pprint(results) -``` - [See documentation](https://serpapi.com/google-reverse-image) - - -### Search Google Local Services -```python -import os -import serpapi -from pprint import pprint - -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'google_local_services', - 'q': 'electrician', - 'data_cid': '6745062158417646970', -}) -pprint(results) -``` - [See documentation](https://serpapi.com/google-local-services-api) - -### Search Google Maps -```python -import os -import serpapi -from pprint import pprint - -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'google_maps', - 'q': 'pizza', - 'll': '@40.7455096,-74.0083012,15.1z', - 'type': 'search', -}) -pprint(results) -``` - [See documentation](https://serpapi.com/google-maps-api) - -### Search Google Jobs -```python -import os -import serpapi -from pprint import pprint - -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'google_jobs', - 'q': 'software engineer', -}) -pprint(results) -``` - [See documentation](https://serpapi.com/google-jobs-api) - -### Search Google Play -```python -import os -import serpapi -from pprint import pprint - -client = serpapi.Client(api_key=os.getenv("API_KEY")) -results = client.search({ - 'engine': 'google_play', - 'q': 'kite', - 'store': 'apps', -}) -pprint(results) -``` - [See documentation](https://serpapi.com/google-play-api) - ## Documentation From e7e950ff1ec8aa40f7ed49c51592d9945095cf6b Mon Sep 17 00:00:00 2001 From: audrey-serpapi Date: Fri, 16 Oct 2026 15:59:06 -0400 Subject: [PATCH 4/4] enforced sentence case, light versions in bold, no $, same key, standard indentation, standard import order, correct links, technical corrections --- README.md | 210 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 116 insertions(+), 94 deletions(-) diff --git a/README.md b/README.md index 0d7ff6d..b1f6de6 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Python 3.6 or later is required. To install the `serpapi` package, simply run the following command inside your Python virtual environment: ```bash -$ pip install serpapi +pip install serpapi ``` > Please note that this package is separate from the legacy `serpapi` module, @@ -22,83 +22,85 @@ $ pip install serpapi ## Quickstart -[Create a SerpApi account](https://serpapi.com/dashboard) to get your API key, then store it in an environment variable: +[Create a SerpApi account](https://serpapi.com/users/sign_up?plan=free) to get your API key, then store it in an environment variable: ```bash export SERPAPI_KEY="your_api_key" ``` -Environment variables are a secure, safe, and easy way to manage secrets. -Python accesses these variables from `os.environ["SERPAPI_KEY"]`. +Environment variables keep secrets out of your source code. +Python accesses these variables from `os.getenv("SERPAPI_KEY")`. -Run a Google search and access the results as a Python `Dictionary`: +Run a Google search and access the results as a Python `dict`: ```python import os -import serpapi from pprint import pprint -client = serpapi.Client(api_key=os.environ["SERPAPI_KEY"]) +import serpapi + +client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) results = client.search({ - "engine": "google", - "q": "coffee" + "engine": "google", + "q": "coffee" }) pprint(results) ``` -The `results` variable now contains a `SerpResults` object, which acts just like a standard dictionary, with some convenient functions added on top. +The `results` variable now contains a `SerpResults` object, which acts just like a `dict`, with some convenient functions added on top. -This example runs a search for "coffee" on Google. It then returns the results as a regular Python Hash. See the playground to generate your own code. +This example runs a search for "coffee" on Google. See the [playground](https://serpapi.com/playground) to generate your own code. - -### Error Handling +### Error handling Unsuccessful requests raise `serpapi.HTTPError` or `serpapi.TimeoutError` exceptions. The returned status code will reflect the sort of error that occurred, please refer to [Status and Error Codes Documentation](https://serpapi.com/api-status-and-error-codes) for more details. ```python import os + import serpapi # A default timeout can be set here. -client = serpapi.Client(api_key=os.getenv("API_KEY"), timeout=10) +client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY"), timeout=10) try: results = client.search({ - 'engine': 'google', - 'q': 'coffee', + "engine": "google", + "q": "coffee", }) except serpapi.HTTPError as e: if e.status_code == 401: # Invalid API key print(e.error) # "Invalid API key. Your API key should be here: https://serpapi.com/manage-api-key" elif e.status_code == 400: # Missing required parameter pass - elif e.status_code == 429: # Exceeds the hourly throughput limit OR account run out of searches + elif e.status_code == 429: # Exceeds the hourly throughput limit OR the account has run out of searches pass except serpapi.TimeoutError as e: # Handle timeout print(f"The request timed out: {e}") ``` + ## Features - **Asynchronous searches** for submitting non-blocking jobs and retrieving completed results from the Search Archive API. - **Persistent connections and connection pooling** for reusing HTTP connections across searches. -- Search results as **Python dictionaries** with `search`, token-efficient **Markdown** with `md`, or raw **search-engine HTML** with `html`. +- Search results as **Python dict** with `search`, token-efficient **Markdown** with `md`, or raw **search-engine HTML** with `html`. - SDK methods for the [Image API](https://serpapi.com/image-api), [Location API](https://serpapi.com/locations-api), [Search Archive API](https://serpapi.com/search-archive-api), and [Account API](https://serpapi.com/account-api). - **Configurable HTTP timeouts** established by setting `timeout` in the client. -## Response Formats +## Response formats -Use `search` and default output (none) for structured results decoded into a `Dictionary`: +Use `search` and default output (none) for structured results decoded into a `dict`: -```python +```python results = client.search({ - "engine": "google", - "q": "coffee" + "engine": "google", + "q": "coffee" }) ``` -Use `md` output for a token-efficient Markdown String optimized for LLMs and AI agents: +Use `md` output for a token-efficient Markdown string optimized for LLMs and AI agents: ```python markdown = client.search({ @@ -109,6 +111,7 @@ markdown = client.search({ ``` Use `html` output when you need the raw search-engine response: + ```python raw_html = client.search({ "engine": "google", @@ -124,31 +127,38 @@ Learn more about [SerpApi Markdown output](https://serpapi.com/markdown-output). ## Configuration -Set defaults when creating a client, then override search parameters in individual calls: +The client is configured with your API key (and an optional timeout parameter) when you create it: ```python -client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY"), timeout=120) -results = client.search({ - "engine": "google", - "q": "coffee", -}) +import os + +import serpapi + +client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) ``` -|Option | Default | Description| -|-------|---------|------------| -| `api_key` | None | Your SerpApi API key. Use an environment variable rather than committing it to source control. | -| `engine` | None | The search engine used by default, such as `google` or `google_maps`. | -| `timeout` | `120` | Timeout in seconds for non-persistent HTTP requests. | -| `async` | false | Submits searches without waiting for them to complete. It can be set on the client or per search.| +| Option | Default | Description | +|--------|---------|-------------| +| `api_key` | `None` | Your SerpApi API key. Use an environment variable rather than committing it to source control. | +| `timeout` | `None` | Timeout in seconds for each HTTP request. By default no timeout is set, so a request can wait indefinitely. | + +Everything else is passed with each call: -Search-engine-specific parameters can also be supplied when creating the client or calling `search`. Parameters passed to search override client defaults. +| Parameter | Where it goes | Example | +|-----------|---------------|---------| +| `engine`, `q`, and other engine-specific parameters | The dictionary passed to `client.search()` | `{"engine": "google", "q": "coffee"}` | +| `async` | The dictionary passed to `client.search()` | `{"engine": "google", "q": "coffee", "async": True}` | +| `output` | The dictionary passed to `client.search()` | `{"engine": "google", "q": "coffee", "output": "md"}` | +| `search_id`, `output` | Keyword arguments to `client.search_archive()` | `client.search_archive(search_id=search_id, output="md")` | -### Search Asynchronous +The client has no default `engine` or `async` setting, so include them in every search. -Search API features non-blocking search using the option: `async=true`. +### Search asynchronously -- Non-blocking - `async=true` - a single parent process can handle unlimited concurrent searches. -- Blocking - `async=false` - many processes must be forked and synchronized to handle concurrent searches. This strategy is I/O usage because each client would hold a network connection. +Use `{"async": True}` to submit searches without waiting for them to complete. + +- **Non-blocking** (`{"async": True}`): a single process can submit many searches and collect the results later from the Search Archive API. The code is more complex because you have to track search IDs and check their status. +- **Blocking** (`{"async": False}`, the default): each call waits for its results before returning, which keeps the code simple. > **Note:** `async` is a reserved keyword in Python 3.7+, so pass it inside the parameters dictionary (`{"async": True}`) rather than as a keyword argument. @@ -163,7 +173,7 @@ from queue import Queue import serpapi company_list = ["meta", "amazon", "apple", "netflix", "google"] -client = serpapi.Client(api_key=os.environ["SERPAPI_KEY"]) +client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) schedule_search = Queue() result = None @@ -205,23 +215,24 @@ print("done") This code batches searches into a [queue](https://en.wikipedia.org/wiki/Queue_(abstract_data_type)). Each search can take a few seconds to complete, so by the time the first ID is popped, its results are usually already in the archive. Searches that are still processing are put back in the queue and checked again. -## Basic Examples in Python +## Basic examples in Python -Here are some examples for some of our most popular APIs. You can find the full list of supported engines and parameters in our [documentation](https://serpapi.com/search-engine-apis). +Here are some examples of our most popular APIs. You can find the full list of supported engines and parameters in our [documentation](https://serpapi.com/search-engine-apis). ### Google Shopping Scrape Google Shopping results with product names, prices, ratings, and merchant information. ```python -import serpapi import os from pprint import pprint +import serpapi + client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) results = client.search({ - "engine": "google_shopping", - "q": "Macbook M4" + "engine": "google_shopping", + "q": "Macbook M4" }) shopping_results = results["shopping_results"] pprint(shopping_results) @@ -229,7 +240,7 @@ pprint(shopping_results) [See documentation](https://serpapi.com/google-shopping-api) -#### Google Shopping Light +**Google Shopping Light** A [light variant](https://serpapi.com/google-shopping-light-api) engine called `google_shopping_light` is also available for faster, lower-cost shopping searches. @@ -239,33 +250,35 @@ Scrape Google Images search results, including image URLs, thumbnails, titles, a ```python import os -import serpapi from pprint import pprint -client = serpapi.Client(api_key=os.getenv("API_KEY")) +import serpapi + +client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) results = client.search({ - 'engine': 'google_images', - 'q': 'coffee', + "engine": "google_images", + "q": "coffee", }) pprint(results) ``` [See documentation](https://serpapi.com/google-images-api) -#### Google Images Light +**Google Images Light** A [light variant](https://serpapi.com/google-images-light-api) engine called `google_images_light` is also available for faster, lower-cost image searches. -### Google Lens with Image URL or Upload +### Google Lens with image URL or upload Google Lens accepts either a publicly accessible image URL or an uploaded image. To search by URL, pass the URL directly: ```python import os -import serpapi from pprint import pprint +import serpapi + client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) results = client.search({ "engine": "google_lens", @@ -295,44 +308,46 @@ Track search interest over time and compare the popularity of search terms. ```python import os -import serpapi from pprint import pprint -client = serpapi.Client(api_key=os.getenv("API_KEY")) +import serpapi + +client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) results = client.search({ - "engine": "google_trends", - "q": "coffee", - "data_type": "TIMESERIES" + "engine": "google_trends", + "q": "coffee", + "data_type": "TIMESERIES" }) interest_over_time = results["interest_over_time"] pprint(interest_over_time) ``` -[See Documentation](https://serpapi.com/google-trends-api) +[See documentation](https://serpapi.com/google-trends-api) ### Google Flights Search flight routes, schedules, prices, and booking options. -> Note: The google_flights engine does not use q. -> Specify route and date parameters such as departure_id, arrival_id, outbound_date, and return_date. +> Note: The `google_flights` engine does not use `q`. +> Specify route and date parameters such as `departure_id`, `arrival_id`, `outbound_date`, and `return_date`. ```python -import serpapi import os from datetime import date, timedelta from pprint import pprint +import serpapi + client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) outbounding = date.today() returning = outbounding + timedelta(weeks=2) results = client.search({ - "engine": "google_flights", - "departure_id": "LAX", - "arrival_id": "AUS", - "outbound_date": outbounding, - "return_date": returning + "engine": "google_flights", + "departure_id": "LAX", + "arrival_id": "AUS", + "outbound_date": outbounding, + "return_date": returning }) best_flights = results["best_flights"] pprint(best_flights) @@ -345,14 +360,15 @@ pprint(best_flights) The Google AI Mode API returns AI-generated answers with structured text blocks, references, images, products, and more. ```python -import serpapi import os from pprint import pprint +import serpapi + client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) -results = client.search({ - "engine": "google_ai_mode", - "q": "best coffee maker" +results = client.search({ + "engine": "google_ai_mode", + "q": "best coffee maker" }) text_blocks = results["text_blocks"] pprint(text_blocks) @@ -360,58 +376,64 @@ pprint(text_blocks) [See documentation](https://serpapi.com/google-ai-mode-api) -### Bing Search +### Search Bing Scrape Bing web search results, including organic results, ads, related searches, and more. ```python import os -import serpapi from pprint import pprint -client = serpapi.Client(api_key=os.getenv("API_KEY")) +import serpapi + +client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) results = client.search({ - 'engine': 'bing', - 'q': 'coffee' + "engine": "bing", + "q": "coffee" }) pprint(results) ``` + [See documentation](https://serpapi.com/bing-search-api) -### DuckDuckGo Search +### Search DuckDuckGo Scrape DuckDuckGo search results, including organic results, ads, knowledge graphs, and related searches. ```python import os -import serpapi from pprint import pprint -client = serpapi.Client(api_key=os.getenv("API_KEY")) +import serpapi + +client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) results = client.search({ - 'engine': 'duckduckgo', - 'q': 'coffee', + "engine": "duckduckgo", + "q": "coffee", }) pprint(results) ``` -[See Documentation](https://serpapi.com/duckduckgo-search-api) -### Baidu Search +[See documentation](https://serpapi.com/duckduckgo-search-api) + +### Search Baidu Scrape Baidu search results, including organic results, answer boxes, and related searches. ```python import os -import serpapi from pprint import pprint -client = serpapi.Client(api_key=os.getenv("API_KEY")) +import serpapi + +client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) results = client.search({ - 'engine': 'baidu', - 'q': 'coffee', + "engine": "baidu", + "q": "coffee", }) pprint(results) ``` + [See documentation](https://serpapi.com/baidu-search-api) ### Amazon Search @@ -421,15 +443,16 @@ Scrape Amazon product search results, including product names, prices, ratings, > Note: The `amazon` engine uses the `k` parameter for a keyword search, not `q`. ```python -import serpapi import os from pprint import pprint +import serpapi + client = serpapi.Client(api_key=os.getenv("SERPAPI_KEY")) results = client.search({ - "engine": "amazon", - "k": "Coffee", - "amazon_domain": "amazon.com" + "engine": "amazon", + "k": "Coffee", + "amazon_domain": "amazon.com" }) organic_results = results["organic_results"] pprint(organic_results) @@ -437,7 +460,6 @@ pprint(organic_results) [See documentation](https://serpapi.com/amazon-search-api) - ## Documentation Documentation is [available on Read the Docs](https://serpapi-python.readthedocs.io/en/latest/).