How to Extract Titles, Links, and Snippets from SERP JSON
Learn how to extract titles, links, snippets, positions, domains, and search metadata from SERP JSON using Python. Includes example JSON, parsing code, CSV export, and best practices for SEO and AI workflows.
To extract titles, links, and snippets from SERP JSON, read the organic_results array, loop through each result, and collect fields such as title, link or url, and snippet or description. For production use, also store position, domain, query, location, language, device, and timestamp.
SERP JSON is a structured search results response returned by a SERP API. It usually contains organic results, ads, local results, news results, shopping results, related searches, and search metadata such as query, location, language, and device.
For many workflows, three fields come first:
-
title -
link -
snippet
These fields are enough to build a search results table, feed URLs into a crawler, monitor ranking changes, or prepare sources for an AI agent or RAG workflow.
What SERP JSON Usually Looks Like
A typical SERP API response may look like this:
{
"search_parameters": {
"engine": "google",
"query": "best project management software",
"location": "United States",
"language": "en",
"device": "desktop"
},
"organic_results": [
{
"position": 1,
"title": "Best Project Management Software of 2026",
"link": "https://example.com/project-management-software",
"snippet": "Compare the best project management software for teams, pricing, features, and integrations."
},
{
"position": 2,
"title": "Top Project Management Tools for Small Businesses",
"link": "https://example.com/small-business-tools",
"snippet": "A practical guide to choosing project management tools for small teams."
}
]
}
The key part is usually organic_results.
Each item inside that array represents one organic search result.
SERP JSON Fields You Should Know
|
SERP JSON Field |
Meaning |
|
|
List of organic search results |
|
|
Ranking position in the search results |
|
|
Search result title |
|
|
Destination URL |
|
|
Search result summary |
|
|
Website domain extracted from the URL |
|
|
Query, engine, location, language, and device context |
For SEO and AI workflows, do not only save title, link, and snippet. Search metadata is also important because the same query can return different results by country, city, language, and device.
Basic Python Example
Here is the simplest way to extract titles, links, and snippets:
serp_json = {
"organic_results": [
{
"position": 1,
"title": "Best Project Management Software of 2026",
"link": "https://example.com/project-management-software",
"snippet": "Compare the best project management software for teams, pricing, features, and integrations."
},
{
"position": 2,
"title": "Top Project Management Tools for Small Businesses",
"link": "https://example.com/small-business-tools",
"snippet": "A practical guide to choosing project management tools for small teams."
}
]
}
results = []
for item in serp_json.get("organic_results", []):
results.append({
"position": item.get("position"),
"title": item.get("title"),
"link": item.get("link"),
"snippet": item.get("snippet")
})
print(results)
This works when the JSON schema is stable and the fields are always named title, link, and snippet.
Extract Title, Link, Snippet, Position, and Domain
Different SERP APIs may use slightly different field names.
For example:
|
Common Field |
Alternative Field |
|
|
|
|
|
|
|
|
result index |
|
|
provider-specific result array |
A safer parser should handle these differences.
from urllib.parse import urlparse
def get_domain(url: str | None) -> str | None:
if not url:
return None
parsed = urlparse(url)
return parsed.netloc.replace("www.", "") if parsed.netloc else None
def extract_organic_results(serp_json: dict) -> list[dict]:
organic_results = serp_json.get("organic_results", [])
extracted = []
for index, item in enumerate(organic_results, start=1):
link = item.get("link") or item.get("url")
extracted.append({
"position": item.get("position") or index,
"title": item.get("title"),
"link": link,
"domain": get_domain(link),
"snippet": item.get("snippet") or item.get("description")
})
return extracted
Usage:
results = extract_organic_results(serp_json)
for result in results:
print(result)
Example output:
{
"position": 1,
"title": "Best Project Management Software of 2026",
"link": "https://example.com/project-management-software",
"domain": "example.com",
"snippet": "Compare the best project management software for teams, pricing, features, and integrations."
}
Adding domain is useful for competitor tracking, deduplication, and source filtering.
Export SERP JSON Results to CSV
After extracting the fields, you may want to save them to a CSV file.
import csv
def save_results_to_csv(results: list[dict], filename: str = "serp_results.csv") -> None:
fieldnames = ["position", "title", "link", "domain", "snippet"]
with open(filename, mode="w", newline="", encoding="utf-8") as file:
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(results)
results = extract_organic_results(serp_json)
save_results_to_csv(results)
CSV is useful when you want to review search results in spreadsheets, import data into a dashboard, or share raw SERP data with SEO teams.
Parse SERP JSON from an API Response
In a real project, SERP JSON usually comes from an API request.
The request format depends on the provider, but the workflow is similar:
Send query parameters
→ Receive SERP JSON
→ Extract organic results
→ Normalize fields
→ Store or export the data
A simplified Python example:
import os
import requests
API_KEY = os.getenv("SERP_API_KEY")
params = {
"query": "best project management software",
"location": "United States",
"language": "en",
"device": "desktop"
}
headers = {
"Authorization": f"Bearer {API_KEY}"
}
response = requests.get(
"https://api.example.com/search",
params=params,
headers=headers,
timeout=30
)
response.raise_for_status()
serp_json = response.json()
results = extract_organic_results(serp_json)
for result in results:
print(result["position"], result["title"], result["link"])
The endpoint and authentication method will vary by provider. The important part is the parsing layer: once you receive JSON, normalize the fields into a structure your application can use.
You can test this workflow with tools like SerpApi, SearchAPI, Bright Data, or Talordata. The important part is whether the JSON response is clean enough for your SEO tool, AI agent, or data pipeline to use directly.
Handle Missing Fields Safely
SERP results are not always perfectly consistent.
Some results may not have snippets. Some links may be missing or replaced by special modules. Some results may belong to news, shopping, images, or local packs instead of standard organic results.
Your parser should not break when a field is missing.
def clean_text(value: str | None) -> str:
if not value:
return ""
return " ".join(value.split())
def extract_organic_results_safe(serp_json: dict) -> list[dict]:
organic_results = serp_json.get("organic_results", [])
extracted = []
for index, item in enumerate(organic_results, start=1):
link = item.get("link") or item.get("url")
result = {
"position": item.get("position") or index,
"title": clean_text(item.get("title")),
"link": link or "",
"domain": get_domain(link) or "",
"snippet": clean_text(item.get("snippet") or item.get("description"))
}
if result["title"] and result["link"]:
extracted.append(result)
return extracted
This version removes extra whitespace and skips results that do not have both a title and a link.
Add Search Metadata
Titles, links, and snippets are useful, but they become more valuable when stored with search metadata.
def add_search_metadata(results: list[dict], serp_json: dict) -> list[dict]:
params = serp_json.get("search_parameters", {})
for result in results:
result["query"] = params.get("query") or params.get("q") or ""
result["engine"] = params.get("engine") or ""
result["location"] = params.get("location") or ""
result["language"] = params.get("language") or ""
result["device"] = params.get("device") or ""
return results
This gives you records like:
{
"position": 1,
"title": "Best Project Management Software of 2026",
"link": "https://example.com/project-management-software",
"domain": "example.com",
"snippet": "Compare the best project management software for teams, pricing, features, and integrations.",
"query": "best project management software",
"engine": "google",
"location": "United States",
"language": "en",
"device": "desktop"
}
This is especially important for SEO tracking. A ranking position without query, location, language, device, and timestamp is hard to compare later.
For implementation, you can also review SERP API query parameters to see how query, location, language, device, and result controls are usually structured.
Use Cases
SEO Rank Tracking
For SEO, extracted SERP fields can help monitor ranking changes and competitor visibility.
|
Field |
Why It Matters |
|
|
Tracks ranking movement |
|
|
Shows how the result appears |
|
|
Identifies the ranking URL |
|
|
Helps with competitor analysis |
|
|
Shows search result messaging |
|
|
Makes ranking data market-specific |
|
|
Separates desktop and mobile results |
AI Agents
AI agents can use SERP JSON as a source discovery layer.
A common workflow looks like this:
User question
→ Generate search query
→ Get SERP JSON
→ Extract titles, links, and snippets
→ Filter useful sources
→ Fetch selected pages
→ Generate grounded answer
The agent should not fetch every URL. It should first filter based on title, snippet, domain, and result type.
RAG Pipelines
For RAG, SERP JSON helps discover current public sources.
Useful fields include:
|
Field |
Purpose |
|
|
Source label |
|
|
Fetch and citation URL |
|
|
Initial relevance signal |
|
|
Source filtering |
|
|
Search visibility signal |
|
|
Retrieval context |
|
|
Freshness tracking |
FAQ
What is SERP JSON?
SERP JSON is a structured search results response returned by a SERP API. It usually contains organic results, ads, local results, news results, shopping results, and search metadata such as query, location, language, and device.
Where are titles, links, and snippets stored in SERP JSON?
In many SERP API responses, titles, links, and snippets are stored inside the organic_results array. Each item may include fields such as position, title, link, and snippet. Some APIs may use alternative names such as url or description.
How do I export SERP API results to CSV?
You can loop through the organic_results array, normalize fields into dictionaries, and use Python’s built-in csv.DictWriter to export the results. Useful CSV columns include query, location, device, position, title, link, domain, and snippet.
What fields should I store for SEO tracking?
For SEO tracking, store query, location, language, device, timestamp, position, title, link, domain, and snippet. These fields make ranking data easier to compare across markets, devices, and time periods.
Final Thoughts
Extracting titles, links, and snippets from SERP JSON is usually the first step in a larger search data workflow.
For SEO teams, these fields support ranking analysis and competitor monitoring.
For AI agents, they help discover and filter useful sources.
For RAG pipelines, they provide citation-ready metadata before full-page content is fetched.
The key is to normalize the response into a simple, stable structure. Once you have position, title, link, domain, snippet, and search metadata, your SERP data becomes much easier to store, analyze, and reuse.