Restaurant and menu data powers food tech apps, delivery aggregators, price comparison tools, and market research. Here's how to extract it from the major platforms.
What you can extract
From restaurant platforms:
- Restaurant names, addresses, phone numbers, hours
- Menu items, descriptions, prices
- Cuisine type, dietary options (vegan, gluten-free, etc.)
- Star ratings and review counts
- Delivery/pickup availability and fees
Method 1: Yelp Fusion API (official, 500 free calls/day)
Yelp has an official API — get your key at yelp.com/developers:
import requests
YELP_API_KEY = "your_yelp_api_key"
def search_yelp_restaurants(location: str, cuisine: str = "restaurants") -> list:
url = "https://api.yelp.com/v3/businesses/search"
headers = {"Authorization": f"Bearer {YELP_API_KEY}"}
params = {
"location": location,
"categories": cuisine,
"limit": 50,
"sort_by": "rating",
}
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
return response.json().get("businesses", [])
return []
restaurants = search_yelp_restaurants("Austin, TX", "mexican")
for r in restaurants[:3]:
print(f"{r['name']}: {r['rating']} stars | {r['review_count']} reviews")
print(f" {r['location']['address1']}, {r['location']['city']}")
print(f" Price: {r.get('price', 'N/A')}")
For menu data (Yelp business details):
def get_yelp_menu(business_id: str) -> dict:
headers = {"Authorization": f"Bearer {YELP_API_KEY}"}
# Business details
r1 = requests.get(
f"https://api.yelp.com/v3/businesses/{business_id}",
headers=headers
)
# Menu (beta endpoint)
r2 = requests.get(
f"https://api.yelp.com/v3/businesses/{business_id}/food-order",
headers=headers
)
return {
"details": r1.json() if r1.status_code == 200 else {},
"menu": r2.json() if r2.status_code == 200 else {}
}
Method 2: Google Maps structured data
Many restaurants have Google Maps listings with structured data in JSON-LD format:
import requests
from bs4 import BeautifulSoup
import json
def scrape_restaurant_structured_data(url: str) -> dict:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/122.0.0.0"
}
response = requests.get(url, headers=headers, timeout=15)
if response.status_code != 200:
return {}
soup = BeautifulSoup(response.text, "html.parser")
for script in soup.find_all("script", type="application/ld+json"):
try:
data = json.loads(script.string)
if isinstance(data, dict) and data.get("@type") in ["Restaurant", "FoodEstablishment"]:
return {
"name": data.get("name"),
"address": data.get("address", {}).get("streetAddress"),
"phone": data.get("telephone"),
"cuisine": data.get("servesCuisine"),
"price_range": data.get("priceRange"),
"hours": data.get("openingHours"),
"menu_url": data.get("hasMenu"),
}
except (json.JSONDecodeError, AttributeError):
continue
return {}
Many chain restaurant and Google Maps listing pages include this structured data — no JavaScript rendering needed.
Method 3: Google Maps Scraper (bulk extraction)
For extracting hundreds of restaurants by city/area, use the Google Maps Scraper which handles pagination, anti-bot, and data normalization.
import apify_client
client = apify_client.ApifyClient("your_apify_token")
run = client.actor("vhubsystems/google-maps-scraper").call(run_input={
"searchStringsArray": ["Italian restaurants in Chicago"],
"maxCrawledPlacesPerSearch": 100,
"language": "en"
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(f"{item['title']} - {item['totalScore']} stars ({item['reviewsCount']} reviews)")
print(f" {item['address']}")
print(f" {item['phone']}")
Method 4: Pre-built restaurant scraper
The Restaurant Menu Scraper on Apify handles Google Maps, Yelp, and direct website scraping.
Input: city/area + cuisine type
Output: restaurant list with menus, ratings, hours, contact info
80+ production runs. Pay-per-result pricing.
Sample output:
{
"name": "Tartine Bakery",
"address": "600 Guerrero St, San Francisco, CA 94110",
"phone": "415-487-2600",
"cuisine": ["Bakery", "Coffee"],
"rating": 4.5,
"reviewCount": 3847,
"priceRange": "$$",
"hours": "Wed-Fri: 8am-7pm, Sat-Sun: 8am-6pm",
"menuItems": [
{"name": "Morning Bun", "price": 4.50, "description": "Orange, cinnamon, sugar"},
{"name": "Country Bread", "price": 16.00, "description": "Sourdough loaf"}
]
}
Use cases
- Food delivery app: Aggregate menus from all restaurants in an area
- Price tracking: Monitor menu price changes over time
- Market research: Restaurant density and cuisine distribution by neighborhood
- Lead generation: Get contact info for restaurants by city/cuisine
- Competitive analysis: Compare pricing across similar restaurants
Combining with review data
Pair with the TripAdvisor Reviews Scraper for complete competitive intelligence:
# Get restaurants
restaurants = get_area_restaurants("downtown Austin")
# Enrich with Yelp data
for r in restaurants:
yelp = search_yelp_restaurants(r["address"])
if yelp:
r["yelp_rating"] = yelp[0]["rating"]
r["yelp_review_count"] = yelp[0]["review_count"]
# Export
import pandas as pd
pd.DataFrame(restaurants).to_csv("austin_restaurants.csv", index=False)
n8n AI Automation Pack ($39) — 5 production-ready workflows
Skip the setup
Apify Scrapers Bundle — $29 one-time
Includes Restaurant Menu Scraper, Yelp Business Scraper, TripAdvisor Reviews, and 32+ more.
Top comments (0)