How to Get Google Search Results in JSON Using Python
Learn how to get Google search results in JSON using Python, parse organic results, extract titles, URLs, snippets, positions, and save search data for SEO, AI agents, RAG, and competitor monitoring.
If you need Google search results for an app, SEO dashboard, AI agent, competitor monitor, or research workflow, copying results from a browser is not enough.
You need structured data.
That means turning a search result page into JSON fields like:
|
Field |
Example |
|
title |
Best SERP APIs for SEO Monitoring |
|
url |
https://example.com/serp-api-guide |
|
snippet |
Compare tools for rank tracking and search monitoring |
|
position |
1 |
|
domain |
example.com |
Once the data is in JSON, you can store it, analyze it, compare it over time, feed it into an AI workflow, or build reports on top of it.
This tutorial shows how to get Google search results in JSON using Python.
Why not scrape Google HTML directly?
You can technically open a Google search URL and try to parse the HTML. But in practice, that path gets messy fast.
Google search pages can change by:
|
Factor |
Why it matters |
|
Location |
Results differ by country, city, and region |
|
Language |
Snippets and result pages change |
|
Device |
Mobile and desktop layouts differ |
|
SERP features |
Ads, maps, images, videos, and AI-style results can appear |
|
Personalization |
Results may vary by user context |
|
HTML structure |
Page markup can change without warning |
If you are building a real product, you usually do not want to maintain brittle HTML parsers, proxy logic, CAPTCHA handling, and location controls yourself. That little scraping goblin eats weekends.
A better approach is to use a Search Results API or SERP API. The API handles the search collection layer and returns structured JSON.
Basic workflow
The workflow is simple:
-
Choose a search query
-
Send it to a Google Search API
-
Receive JSON results
-
Extract titles, URLs, snippets, and positions
-
Store or use the data in your application
In Python, this usually means using the requests library.
Install dependencies
You only need one package for the basic example:
pip install requests
You should also store your API key as an environment variable instead of hardcoding it in your script.
export SERP_API_KEY="your_api_key_here"
On Windows PowerShell:
setx SERP_API_KEY "your_api_key_here"
Example: request Google search results in JSON
The exact endpoint and parameter names depend on your SERP API provider. The structure below is a clean pattern you can adapt.
import os
import requests
from typing import Any, Dict
API_KEY = os.getenv("SERP_API_KEY")
# Replace this with your SERP API provider endpoint.
# For example, use the endpoint provided in your Talordata dashboard or API docs.
API_URL = "https://YOUR_SERP_API_ENDPOINT"
def get_google_results(query: str, country: str = "us", language: str = "en") -> Dict[str, Any]:
if not API_KEY:
raise RuntimeError("Missing SERP_API_KEY environment variable.")
params = {
"api_key": API_KEY,
"engine": "google",
"q": query,
"country": country,
"language": language,
"device": "desktop",
"format": "json"
}
response = requests.get(API_URL, params=params, timeout=30)
response.raise_for_status()
return response.json()
if __name__ == "__main__":
data = get_google_results("best SERP API for SEO monitoring")
print(data)
This gives you the raw JSON response from the API.
For production use, you should not print the whole object forever. The next step is to parse only the fields you need.
Parse organic results
Most SEO and search data workflows start with organic results.
A typical organic result contains:
|
Field |
Meaning |
|
position |
Ranking position |
|
title |
Search result headline |
|
url |
Destination page |
|
displayed_url |
Visible URL or breadcrumb |
|
snippet |
Description shown in search |
|
domain |
Website domain |
The JSON structure may vary by provider, but many APIs return organic results under a field like organic_results.
Here is a defensive parser:
from urllib.parse import urlparse
from typing import Any, Dict, List
def parse_organic_results(data: Dict[str, Any]) -> List[Dict[str, Any]]:
results = data.get("organic_results", [])
parsed = []
for index, item in enumerate(results, start=1):
url = item.get("url") or item.get("link") or ""
domain = urlparse(url).netloc.replace("www.", "")
parsed.append({
"position": item.get("position", index),
"title": item.get("title", "").strip(),
"url": url,
"domain": domain,
"snippet": item.get("snippet", "").strip()
})
return parsed
Then use it like this:
if __name__ == "__main__":
data = get_google_results("best SERP API for SEO monitoring")
organic_results = parse_organic_results(data)
for result in organic_results:
print(result["position"], result["title"])
print(result["url"])
print(result["snippet"])
print()
Save results to a JSON file
For rank tracking, competitor monitoring, or research, you should store snapshots over time.
import json
from datetime import datetime, timezone
def save_results_to_file(query: str, results: List[Dict[str, Any]]) -> str:
timestamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
filename = f"google_results_{timestamp}.json"
payload = {
"query": query,
"collected_at": timestamp,
"results": results
}
with open(filename, "w", encoding="utf-8") as file:
json.dump(payload, file, ensure_ascii=False, indent=2)
return filename
Full usage:
if __name__ == "__main__":
query = "best SERP API for SEO monitoring"
data = get_google_results(query)
organic_results = parse_organic_results(data)
filename = save_results_to_file(query, organic_results)
print(f"Saved {len(organic_results)} results to {filename}")
Save results to CSV
If you want to open the results in Excel, Google Sheets, or a BI tool, CSV is convenient.
import csv
def save_results_to_csv(filename: str, results: List[Dict[str, Any]]) -> None:
fieldnames = ["position", "title", "url", "domain", "snippet"]
with open(filename, "w", newline="", encoding="utf-8") as file:
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(results)
Usage:
if __name__ == "__main__":
query = "best SERP API for SEO monitoring"
data = get_google_results(query)
organic_results = parse_organic_results(data)
save_results_to_csv("google_results.csv", organic_results)
print("Saved results to google_results.csv")
Add location and device parameters
Google results are not universal. The same query can return different results in New York, London, Singapore, or Sydney.
For serious SEO monitoring, collect search context every time.
Useful parameters include:
|
Parameter |
Example |
|
query |
best coffee shop near me |
|
country |
us |
|
language |
en |
|
city or location |
New York |
|
device |
desktop or mobile |
|
search engine |
|
|
timestamp |
2026-06-27T09:00:00Z |
You can update the function:
def get_google_results(
query: str,
country: str = "us",
language: str = "en",
location: str | None = None,
device: str = "desktop"
) -> Dict[str, Any]:
if not API_KEY:
raise RuntimeError("Missing SERP_API_KEY environment variable.")
params = {
"api_key": API_KEY,
"engine": "google",
"q": query,
"country": country,
"language": language,
"device": device,
"format": "json"
}
if location:
params["location"] = location
response = requests.get(API_URL, params=params, timeout=30)
response.raise_for_status()
return response.json()
Now you can run:
data = get_google_results(
query="best dentist near me",
country="us",
language="en",
location="Austin, Texas",
device="mobile"
)
What fields should you store?
For a simple Google Search JSON workflow, store these fields first:
|
Field |
Why it matters |
|
query |
Keeps the search context |
|
country |
Makes results comparable |
|
language |
Explains result language |
|
location |
Important for local SEO |
|
device |
Desktop and mobile may differ |
|
collected_at |
Enables historical tracking |
|
position |
Measures ranking |
|
title |
Shows result headline |
|
url |
Shows ranking page |
|
domain |
Useful for competitor grouping |
|
snippet |
Shows search message |
If you are building a more advanced SEO or AI workflow, also store:
|
Field |
Use case |
|
ads |
Paid search pressure |
|
local results |
Local SEO tracking |
|
related questions |
Content planning |
|
shopping results |
Ecommerce monitoring |
|
news results |
Freshness tracking |
|
sitelinks |
Brand visibility |
|
AI-style answer fields |
AI search visibility analysis |
If you want Google search results in JSON without maintaining your own scraper, a SERP API provider can act as the search data layer.
Talordata is useful in this kind of workflow when you need structured search results for SEO monitoring, competitor tracking, AI agents, RAG pipelines, or market research. The practical value is that you can request search data, receive JSON or HTML output, and focus on analysis instead of building the collection infrastructure yourself.
For example, you may use Talordata to collect:
|
Data |
Use case |
|
Organic results |
Rank tracking and SEO reports |
|
Titles and snippets |
Content analysis |
|
URLs and domains |
Competitor monitoring |
|
Local results |
Local SEO |
|
Multi-engine data |
Google, Bing, Yandex, DuckDuckGo |
|
Search results for AI |
Agent tools and RAG context |
Final thoughts
Getting Google search results in JSON using Python is straightforward once you use the right workflow.
Do not scrape raw Google HTML unless you are prepared to maintain parsers, location handling, anti-bot work, and layout changes. For most product, SEO, and AI teams, a Search Results API is the cleaner path.
Start small:
-
Get JSON
-
Parse organic results
-
Store title, URL, snippet, position, and timestamp
-
Add location, device, and SERP features when needed
Once your search data is structured, it becomes useful everywhere: SEO dashboards, competitor reports, content planning, AI agents, RAG systems, and market research.
Search results are messy in the browser. JSON turns them into building blocks.
FAQ
Can I get Google search results in JSON with Python?
Yes. The usual approach is to use Python with a SERP API or Search Results API. The API returns structured JSON, and Python can parse fields such as titles, URLs, snippets, and positions.
Should I scrape Google HTML directly?
For production workflows, usually no. Direct HTML scraping is fragile because search layouts, localization, CAPTCHA, and SERP features can change. A SERP API is usually cleaner.
What Python library should I use?
For basic API requests, requests is enough. For larger workflows, you may also use pandas, tenacity for retries, and a database such as PostgreSQL.
What fields should I extract first?
Start with query, country, language, location, device, timestamp, position, title, URL, domain, and snippet.