Extract Google business reviews through a SERP API by searching for a business name and parsing the knowledge graph panel that contains star ratings, review counts, and individual review snippets. Scraping Google Maps directly requires browser automation, proxy rotation, and constant selector maintenance. A SERP API returns the same review data as structured JSON from a single POST request. This tutorial extracts reviews for any business and compares the approach to direct scraping.
Prerequisites
- Python 3.8+ installed
- requests library installed
- A Scavio API key from scavio.dev
- A business name to look up
Walkthrough
Step 1: Search for the business
Query Google through Scavio using the business name and location to trigger the knowledge graph panel.
import os, requests, json
API_KEY = os.environ['SCAVIO_API_KEY']
def search_business(name: str, location: str = '') -> dict:
query = f'{name} {location} reviews' if location else f'{name} reviews'
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY},
json={'platform': 'google', 'query': query}, timeout=15)
resp.raise_for_status()
return resp.json()
data = search_business('Starbucks', 'Times Square New York')
print(f'Keys in response: {list(data.keys())}')Step 2: Extract knowledge graph reviews
Parse the knowledge graph section of the response to extract the overall rating, review count, and review snippets.
def extract_reviews(data: dict) -> dict:
kg = data.get('knowledge_graph', {})
reviews_data = {
'name': kg.get('title', kg.get('name', '')),
'rating': kg.get('rating', ''),
'review_count': kg.get('reviews', kg.get('review_count', '')),
'type': kg.get('type', ''),
'address': kg.get('address', ''),
}
# Extract individual review snippets if available
reviews = kg.get('reviews', kg.get('user_reviews', []))
if isinstance(reviews, list):
reviews_data['snippets'] = [{
'text': r.get('text', r.get('snippet', '')),
'rating': r.get('rating', ''),
'author': r.get('author', ''),
} for r in reviews[:5]]
return reviews_data
reviews = extract_reviews(data)
print(json.dumps(reviews, indent=2))Step 3: Parse organic results for review pages
Also check organic results for review aggregation pages that contain additional review data.
def extract_review_links(data: dict) -> list:
results = data.get('organic_results', [])
review_links = []
review_signals = ['review', 'rating', 'stars', 'feedback', 'testimonial']
for r in results:
text = f"{r.get('title', '')} {r.get('snippet', '')}".lower()
if any(signal in text for signal in review_signals):
review_links.append({
'title': r.get('title', ''),
'url': r.get('link', ''),
'snippet': r.get('snippet', '')[:200],
})
return review_links
links = extract_review_links(data)
for link in links:
print(f"{link['title'][:50]}: {link['url']}")Step 4: Compare with direct scraping
Highlight the differences between API-based review extraction and direct Google Maps scraping in terms of reliability and cost.
def review_report(business: str, location: str = '') -> dict:
data = search_business(business, location)
reviews = extract_reviews(data)
review_links = extract_review_links(data)
report = {
'business': reviews.get('name', business),
'rating': reviews.get('rating', 'N/A'),
'review_count': reviews.get('review_count', 'N/A'),
'review_snippets': len(reviews.get('snippets', [])),
'review_pages_found': len(review_links),
'method': 'SERP API (1 API call, structured JSON)',
'alternative': 'Direct scraping (browser + proxy + selector maintenance)',
'api_cost': '$0.005 per query',
}
print(f"{report['business']}: {report['rating']} ({report['review_count']} reviews)")
print(f"Snippets: {report['review_snippets']}, Review pages: {report['review_pages_found']}")
return report
review_report('Blue Bottle Coffee', 'San Francisco')Python Example
import requests, os
H = {'x-api-key': os.environ['SCAVIO_API_KEY']}
def get_reviews(business, location=''):
query = f'{business} {location} reviews'.strip()
data = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
json={'platform': 'google', 'query': query}).json()
kg = data.get('knowledge_graph', {})
return {'name': kg.get('title', ''), 'rating': kg.get('rating', ''), 'reviews': kg.get('reviews', '')}
print(get_reviews('Blue Bottle Coffee', 'San Francisco'))JavaScript Example
const H = {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'};
async function getReviews(business, location = '') {
const r = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST', headers: H,
body: JSON.stringify({platform: 'google', query: `${business} ${location} reviews`})
});
const kg = (await r.json()).knowledge_graph || {};
return {name: kg.title, rating: kg.rating, reviews: kg.reviews};
}
getReviews('Blue Bottle Coffee', 'San Francisco').then(console.log);Expected Output
Business review data extracted from Google knowledge graph via SERP API, including rating, review count, and individual review snippets without browser scraping.