Food delivery is a $300B global market. Scraping menu data, prices, and delivery times enables price comparison tools, market research, and restaurant analytics. Here's how to build it.
Architecture
Food delivery platforms heavily rely on APIs for their mobile and web apps. By intercepting and replicating these API calls, we get structured JSON data instead of messy HTML.
Menu and Price Scraper
pip install requests pandas beautifulsoup4
import requests
import pandas as pd
from datetime import datetime
import time
import json
from bs4 import BeautifulSoup
class FoodDeliveryScraper:
def __init__(self, api_key):
self.api_key = api_key
self.session = requests.Session()
def _proxy_request(self, url):
proxy_url = f"http://api.scraperapi.com?api_key={self.api_key}&url={url}"
return self.session.get(proxy_url, timeout=30)
def scrape_restaurant_menu(self, platform_url):
resp = self._proxy_request(platform_url)
soup = BeautifulSoup(resp.text, "html.parser")
menu_items = []
# Try structured data first
for script in soup.find_all("script", type="application/ld+json"):
try:
data = json.loads(script.string)
if data.get("@type") == "Restaurant":
for section in data.get("hasMenu", {}).get("hasMenuSection", []):
for item in section.get("hasMenuItem", []):
menu_items.append({
"name": item.get("name"),
"price": item.get("offers", {}).get("price"),
"section": section.get("name", ""),
})
except json.JSONDecodeError:
continue
# Fallback: HTML parsing
if not menu_items:
for item in soup.select(".menu-item, [data-testid='menu-item']"):
name = item.select_one(".item-name, h3, h4")
price = item.select_one(".price, .item-price")
if name:
menu_items.append({
"name": name.text.strip(),
"price": price.text.strip() if price else "N/A",
})
return menu_items
def compare_prices(self, restaurant_name, platform_urls):
comparison = []
for platform, url in platform_urls.items():
items = self.scrape_restaurant_menu(url)
for item in items:
item["platform"] = platform
item["restaurant"] = restaurant_name
comparison.extend(items)
time.sleep(3)
return pd.DataFrame(comparison)
# Usage
scraper = FoodDeliveryScraper("YOUR_SCRAPERAPI_KEY")
platforms = {
"ubereats": "https://www.ubereats.com/store/example-restaurant/abc123",
"doordash": "https://www.doordash.com/store/example-restaurant-456"
}
comparison = scraper.compare_prices("Pizza Palace", platforms)
print(comparison[["name", "price", "platform"]].to_string(index=False))
Price Tracking Over Time
import schedule
def track_prices():
scraper = FoodDeliveryScraper("YOUR_KEY")
restaurants = json.load(open("watchlist.json"))
for restaurant in restaurants:
df = scraper.compare_prices(restaurant["name"], restaurant["urls"])
df["date"] = datetime.now().strftime("%Y-%m-%d")
try:
history = pd.read_csv("price_history.csv")
history = pd.concat([history, df])
except FileNotFoundError:
history = df
history.to_csv("price_history.csv", index=False)
schedule.every(6).hours.do(track_prices)
Scaling Considerations
Food delivery scraping requires handling JavaScript-heavy SPAs. ScraperAPI renders pages and solves CAPTCHAs automatically. Use ThorData residential proxies for location-specific pricing data. Track scraper reliability with ScrapeOps.
Conclusion
Food delivery data scraping enables powerful comparison and analytics tools. Focus on structured data extraction from JSON-LD and API responses before falling back to HTML parsing. The combination of price tracking and ETA monitoring creates actionable market intelligence.
Top comments (0)