Scraping Google Search Results with SerpApi
June 8, 2026
SerpApi is a real-time SERP API that fetches and parses Google (and other engines') search results for you, returning clean structured JSON instead of raw HTML. It handles the painful parts of search scraping — rotating proxies, CAPTCHAs, geo-targeting, and Google's ever-changing markup — so you can pull ranked results reliably without maintaining your own scraping stack. It's a great fit for SEO rank tracking, competitive research, and any data pipeline that needs dependable access to live search data.
The endpoint
Everything runs through a single GET endpoint: https://serpapi.com/search.json. You pass your query as URL parameters. The essentials are engine (set to google for web search), q (your query), and api_key (your private key from the dashboard). Useful extras include location to geo-target results, hl and gl for language and country, num for results per page, and start for pagination.
1curl "https://serpapi.com/search.json?engine=google&q=coffee&location=Austin,+Texas&hl=en&gl=us&api_key=YOUR_API_KEY"Fetching results in Node.js
The official serpapi npm package wraps the endpoint in a tidy getJson helper. Keep your key in an environment variable — never hard-code it in source.
1import { getJson } from "serpapi";
2
3const response = await getJson({
4 engine: "google",
5 api_key: process.env.SERPAPI_API_KEY, // keep your key out of source
6 q: "coffee",
7 location: "Austin, Texas",
8 hl: "en",
9 gl: "us",
10});
11
12// organic_results is an array of ranked listings
13for (const result of response.organic_results) {
14 console.log(result.position, result.title, result.link);
15}...or in Python
The new official serpapi client mirrors the same parameters. (The older google-search-results package still works but is being phased out.)
1import os
2import serpapi
3
4client = serpapi.Client(api_key=os.environ["SERPAPI_API_KEY"])
5results = client.search(
6 q="coffee",
7 engine="google",
8 location="Austin, Texas",
9 hl="en",
10 gl="us",
11)
12
13for result in results["organic_results"]:
14 print(result["position"], result["title"], result["link"])What comes back
The response is a single JSON object. search_metadata and search_parameters describe the request, search_information holds result counts, and the main payload is organic_results — an array of ranked listings, each with position, title, link, displayed_link, and snippet. Depending on the query you may also get ads, related_questions (the People also ask box), a knowledge_graph, and more. Code defensively: a section like organic_results can be absent for some queries, so check before iterating.
1{
2 "search_metadata": { "status": "Success" },
3 "search_parameters": { "engine": "google", "q": "coffee" },
4 "organic_results": [
5 {
6 "position": 1,
7 "title": "Coffee - Wikipedia",
8 "link": "https://en.wikipedia.org/wiki/Coffee",
9 "snippet": "Coffee is a beverage brewed from roasted coffee beans..."
10 }
11 ]
12}That's the whole loop: one request, structured JSON back, ready to drop into a dashboard or pipeline. From here you'd add pagination with start, track positions over time, or fan out across a list of keywords. (This is a demo post — swap in your own key to run it for real.)