Tutorial

How to Extract Local Business Data with Search API

Get Google Maps business data via the Scavio SERP API. Extract business names, addresses, ratings, and phone numbers for local lead generation.

Google Maps contains structured business data that is valuable for lead generation, market research, and competitive analysis. Scraping Maps directly is difficult due to JavaScript rendering and bot detection. The Scavio API returns local business data as part of SERP results when you include location-based queries. This tutorial extracts business listings, contact information, ratings, and addresses from local search results at $0.005 per query.

Prerequisites

  • Python 3.9+ installed
  • requests library installed
  • A Scavio API key from scavio.dev
  • A target business category and location

Walkthrough

Step 1: Search for local businesses

Use location-specific queries to trigger local pack and Maps results in the SERP. The API returns structured local business data.

Python
import os, requests, json, time

SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}
URL = 'https://api.scavio.dev/api/v1/search'

def search_local_businesses(category: str, location: str, num: int = 10) -> dict:
    resp = requests.post(URL, headers=H,
        json={'query': f'{category} in {location}', 'country_code': 'us', 'num_results': num})
    data = resp.json()
    # Extract local pack results (Maps listings)
    local_pack = data.get('local_results', data.get('local_pack', []))
    # Also check organic results for business pages
    organic = data.get('organic_results', [])
    return {
        'local_pack': local_pack,
        'organic': organic,
        'knowledge_graph': data.get('knowledge_graph', {}),
    }

results = search_local_businesses('plumbers', 'Austin TX')
print(f'Local pack: {len(results["local_pack"])} businesses')
print(f'Organic: {len(results["organic"])} results')

Step 2: Extract and normalize business data

Parse the local results to extract business name, address, phone, rating, and review count into a normalized format.

Python
def extract_business_data(search_results: dict) -> list:
    businesses = []
    # From local pack
    for biz in search_results.get('local_pack', []):
        businesses.append({
            'name': biz.get('title', biz.get('name', '')),
            'address': biz.get('address', ''),
            'phone': biz.get('phone', ''),
            'rating': biz.get('rating', ''),
            'reviews': biz.get('reviews', biz.get('reviews_count', 0)),
            'type': biz.get('type', ''),
            'website': biz.get('website', biz.get('link', '')),
            'source': 'local_pack',
        })
    # From organic results (business websites)
    for r in search_results.get('organic', []):
        if any(signal in r.get('link', '').lower() for signal in ['yelp.com', 'yellowpages', 'bbb.org']):
            continue  # Skip directories
        businesses.append({
            'name': r.get('title', ''),
            'website': r.get('link', ''),
            'snippet': r.get('snippet', ''),
            'source': 'organic',
        })
    return businesses

businesses = extract_business_data(results)
print(f'Extracted {len(businesses)} businesses')
for b in businesses[:5]:
    print(f'  {b["name"][:40]} | {b.get("rating", "N/A")} stars | {b.get("phone", "N/A")}')

Step 3: Batch search across multiple categories and locations

Scale the extraction across multiple business categories and locations. Export results to CSV for use in CRM or outreach tools.

Python
import csv

def batch_local_search(searches: list, output_file: str = 'local_businesses.csv') -> list:
    all_businesses = []
    for category, location in searches:
        results = search_local_businesses(category, location)
        businesses = extract_business_data(results)
        for b in businesses:
            b['category'] = category
            b['location'] = location
        all_businesses.extend(businesses)
        print(f'{category} in {location}: {len(businesses)} businesses')
        time.sleep(0.3)
    # Export to CSV
    if all_businesses:
        keys = ['name', 'category', 'location', 'address', 'phone', 'rating', 'reviews', 'website']
        with open(output_file, 'w', newline='') as f:
            writer = csv.DictWriter(f, fieldnames=keys, extrasaction='ignore')
            writer.writeheader()
            writer.writerows(all_businesses)
    print(f'\nTotal: {len(all_businesses)} businesses exported to {output_file}')
    print(f'Cost: ${len(searches) * 0.005:.3f}')
    return all_businesses

searches = [
    ('plumbers', 'Austin TX'),
    ('electricians', 'Austin TX'),
    ('HVAC contractors', 'Austin TX'),
]
batch_local_search(searches)

Python Example

Python
import os, requests, time

SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}

def local_businesses(category, location):
    resp = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
        json={'query': f'{category} in {location}', 'country_code': 'us', 'num_results': 10})
    data = resp.json()
    local = data.get('local_results', data.get('local_pack', []))
    print(f'{category} in {location}: {len(local)} local results')
    for b in local[:5]:
        name = b.get('title', b.get('name', ''))
        rating = b.get('rating', 'N/A')
        print(f'  {name[:35]} | {rating} stars')

for cat in ['plumbers', 'electricians']:
    local_businesses(cat, 'Austin TX')
    time.sleep(0.3)

JavaScript Example

JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;

async function localBusinesses(category, location) {
  const resp = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST',
    headers: { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ query: `${category} in ${location}`, country_code: 'us', num_results: 10 })
  });
  const data = await resp.json();
  const local = data.local_results || data.local_pack || [];
  console.log(`${category} in ${location}: ${local.length} results`);
  local.slice(0, 5).forEach(b => {
    console.log(`  ${(b.title || b.name || '').slice(0, 35)} | ${b.rating || 'N/A'} stars`);
  });
}

(async () => {
  await localBusinesses('plumbers', 'Austin TX');
  await localBusinesses('electricians', 'Austin TX');
})();

Expected Output

JSON
Local pack: 8 businesses
Organic: 10 results

Extracted 12 businesses
  ABC Plumbing & Drain Service          | 4.8 stars | (512) 555-0123
  Austin Reliable Plumbers               | 4.6 stars | (512) 555-0456
  Radiant Plumbing & Air Conditioning    | 4.9 stars | (512) 555-0789

plumbers in Austin TX: 8 businesses
electricians in Austin TX: 7 businesses
HVAC contractors in Austin TX: 6 businesses

Total: 21 businesses exported to local_businesses.csv
Cost: $0.015

Related Tutorials

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

Python 3.9+ installed. requests library installed. A Scavio API key from scavio.dev. A target business category and location. A Scavio API key gives you 250 free credits per month.

Yes. The free tier includes 250 credits per month, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Start Building

Get Google Maps business data via the Scavio SERP API. Extract business names, addresses, ratings, and phone numbers for local lead generation.