# Restaurant Menu Scraper (`its_raghav/restaurant-menu-scraper`) Actor

Scrape restaurant menus with items, prices, descriptions, and dietary tags from Yelp.

- **URL**: https://apify.com/its\_raghav/restaurant-menu-scraper.md
- **Developed by:** [Raghav Dua](https://apify.com/its_raghav) (community)
- **Categories:** E-commerce, Automation, Integrations
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Restaurant Menu Scraper

Scrape **restaurant menus with full item details, prices, descriptions, and dietary tags** from Yelp. This Apify actor extracts structured menu data from Yelp restaurant menu pages, giving you clean, normalized JSON output ready for analysis or integration.

Whether you need competitive pricing intelligence, want to build a restaurant database, or need menu data for a food-related application, this scraper handles the heavy lifting. It runs on the [Apify platform](https://apify.com), giving you API access, scheduling, and integrations with tools like Google Sheets, Slack, and webhooks.

### Why use Restaurant Menu Scraper?

- **Structured menu data** -- Clean JSON output with menu sections, item names, descriptions, prices, and dietary tags instead of messy HTML
- **Dietary tag extraction** -- Automatically identifies vegetarian, vegan, gluten-free, dairy-free, halal, kosher, and other dietary attributes from item descriptions
- **Two input modes** -- Provide direct Yelp menu URLs for targeted scraping, or search by location and cuisine to discover restaurants automatically
- **Schema.org JSON-LD parsing** -- Yelp embeds structured data (Menu > MenuSection > MenuItem) in every menu page. Clean, standardized, reliable extraction with HTML fallback
- **No browser needed** -- Uses lightweight HTTP requests with Cheerio parsing. No Playwright, no Puppeteer. Fast and cheap to run
- **Massive coverage** -- Yelp has menu data for hundreds of thousands of restaurants across the US and internationally

### How to scrape restaurant menus

1. Click **Try for free** to open the actor in the Apify Console
2. Choose your input method:
   - **Direct URLs**: Paste one or more Yelp menu page URLs (e.g., `https://www.yelp.com/menu/restaurant-name`)
   - **Search**: Enter a `searchLocation` (e.g., "New York, NY") and optionally a `searchCuisine` (e.g., "italian")
3. Set `maxRestaurants` to control how many restaurants to scrape (default: 25)
4. Click **Start** and wait for the run to complete
5. Download your data from the **Dataset** tab in JSON, CSV, Excel, or other formats

### Input

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `restaurantUrls` | string[] | No | `[]` | Direct Yelp menu page URLs |
| `searchLocation` | string | No | - | City or address to search for restaurants |
| `searchCuisine` | string | No | - | Cuisine type filter (e.g., "italian", "chinese") |
| `maxRestaurants` | integer | No | `25` | Maximum number of restaurants to scrape (1-500) |
| `platform` | string | No | `"yelp"` | Source platform |

You must provide either `restaurantUrls` or `searchLocation` (or both). If both are provided, direct URLs are scraped first, then search results fill the remaining quota up to `maxRestaurants`.

#### Example input

```json
{
    "restaurantUrls": [
        "https://www.yelp.com/menu/joes-pizza-new-york-5"
    ],
    "searchLocation": "New York, NY",
    "searchCuisine": "pizza",
    "maxRestaurants": 10
}
````

### Output

Each restaurant produces one dataset item with full menu details.

#### Example output

```json
{
    "restaurantName": "McDonald's Menu",
    "address": "1560 Broadway, New York, NY 10036",
    "phone": "(212) 944-6664",
    "platform": "yelp",
    "rating": 2.5,
    "reviewCount": 156,
    "priceRange": "$",
    "cuisineTypes": ["Fast Food", "Burgers"],
    "menuSections": [
        {
            "sectionName": "Most Popular",
            "items": [
                {
                    "name": "Sausage McMuffin with Egg",
                    "description": "(530 Cal.)",
                    "price": 5.49,
                    "currency": "USD",
                    "dietaryTags": [],
                    "imageUrl": null
                },
                {
                    "name": "Egg McMuffin",
                    "description": "(310 Cal.)",
                    "price": 5.29,
                    "currency": "USD",
                    "dietaryTags": [],
                    "imageUrl": null
                }
            ]
        }
    ],
    "totalMenuItems": 627,
    "url": "https://www.yelp.com/menu/mcdonalds-new-york-320",
    "scrapedAt": "2026-04-06T17:00:00.000Z"
}
```

### Data fields

| Field | Type | Description |
|-------|------|-------------|
| `restaurantName` | string | Name of the restaurant |
| `address` | string | Full street address |
| `phone` | string | Phone number |
| `platform` | string | Source platform ("yelp") |
| `rating` | number | Average Yelp rating (1-5) |
| `reviewCount` | number | Total number of Yelp reviews |
| `priceRange` | string | Price level ("$", "$$", "$$$", "$$$$") |
| `cuisineTypes` | string\[] | Cuisine categories |
| `menuSections` | object\[] | Menu organized by sections |
| `menuSections[].sectionName` | string | Section name (e.g., "Most Popular", "Appetizers") |
| `menuSections[].items` | object\[] | Items in the section |
| `menuSections[].items[].name` | string | Item name |
| `menuSections[].items[].description` | string | Item description and calorie info |
| `menuSections[].items[].price` | number | Price in local currency |
| `menuSections[].items[].currency` | string | Currency code (default: USD) |
| `menuSections[].items[].dietaryTags` | string\[] | Detected dietary attributes |
| `menuSections[].items[].imageUrl` | string | Item image URL (if available) |
| `totalMenuItems` | number | Total count of menu items across all sections |
| `url` | string | Source URL |
| `scrapedAt` | string | ISO 8601 timestamp |

### How much does it cost?

This actor uses lightweight HTTP requests (no browser rendering), so it's very cost-effective. A single restaurant menu page typically costs less than $0.001 in Apify platform credits. Scraping 100 restaurants costs roughly $0.05-0.10.

The free Apify tier includes $5 of monthly platform credits, which is enough to scrape thousands of restaurant menus.

### Tips and advanced usage

- **Use direct menu URLs for best results** -- Yelp menu pages follow the pattern `https://www.yelp.com/menu/restaurant-slug`. Provide these directly for the most reliable extraction.
- **Not all restaurants have menus on Yelp** -- Menu availability depends on whether the restaurant has published their menu on Yelp. Major chains and popular restaurants typically have full menus.
- **Dietary tag detection** -- The scraper searches item descriptions for keywords like "vegetarian", "vegan", "gluten-free", "gf", "dairy-free", "nut-free", "spicy", "halal", and "kosher". Tags are only detected when mentioned in the description text.
- **Calorie data** -- Many Yelp menu items include calorie counts in the description (e.g., "(530 Cal.)"). This is included in the description field as-is.
- **Large menus** -- Some restaurants have 500+ menu items across dozens of sections. All items are extracted regardless of menu size.

### Limitations

- **Yelp menu pages only** -- This actor scrapes Yelp's menu pages specifically. Not all Yelp restaurant listings have a menu page.
- **Search discovery** -- Location-based search finds restaurants on Yelp, then converts to menu page URLs. Not all discovered restaurants will have menus available.
- **Price accuracy** -- Prices reflect what Yelp displays at scrape time and may differ from current in-restaurant prices.
- **Anti-bot** -- Yelp may rate-limit or block requests. The actor includes retry logic and delays between requests. For large-scale scraping (100+ restaurants), consider using Apify proxy.

### FAQ

**Is it legal to scrape Yelp?** Web scraping publicly available data is generally legal in the United States under the hiQ Labs v. LinkedIn precedent. However, always review Yelp's Terms of Service and ensure your use case complies with applicable laws. This actor is provided as a technical tool — you are responsible for how you use the data.

**I'm getting empty menus.** Not all Yelp restaurant listings have a dedicated menu page. Check that your URL follows the pattern `https://www.yelp.com/menu/restaurant-slug`. If the restaurant doesn't have a menu on Yelp, no data will be returned.

**Can I scrape menus from other platforms?** Not yet in v1. The codebase is designed for extensibility — additional platforms may be added in future versions.

**Need a custom solution?** Open an issue in the Issues tab or reach out for a custom solution.

# Actor input Schema

## `restaurantUrls` (type: `array`):

Direct Yelp menu page URLs (e.g., https://www.yelp.com/menu/restaurant-name)

## `searchLocation` (type: `string`):

City or address to search for restaurants (e.g., 'New York, NY')

## `searchCuisine` (type: `string`):

Cuisine type to filter by (e.g., 'italian', 'chinese', 'mexican')

## `maxRestaurants` (type: `integer`):

Maximum number of restaurants to scrape

## `platform` (type: `string`):

Source platform (currently Yelp)

## Actor input object example

```json
{
  "restaurantUrls": [
    "https://www.yelp.com/menu/mcdonalds-new-york-320"
  ],
  "maxRestaurants": 25,
  "platform": "yelp"
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "restaurantUrls": [
        "https://www.yelp.com/menu/mcdonalds-new-york-320"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("its_raghav/restaurant-menu-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "restaurantUrls": ["https://www.yelp.com/menu/mcdonalds-new-york-320"] }

# Run the Actor and wait for it to finish
run = client.actor("its_raghav/restaurant-menu-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "restaurantUrls": [
    "https://www.yelp.com/menu/mcdonalds-new-york-320"
  ]
}' |
apify call its_raghav/restaurant-menu-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=its_raghav/restaurant-menu-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Restaurant Menu Scraper",
        "description": "Scrape restaurant menus with items, prices, descriptions, and dietary tags from Yelp.",
        "version": "1.0",
        "x-build-id": "ZZyhjtLXl04lthBqQ"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/its_raghav~restaurant-menu-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-its_raghav-restaurant-menu-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/its_raghav~restaurant-menu-scraper/runs": {
            "post": {
                "operationId": "runs-sync-its_raghav-restaurant-menu-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/its_raghav~restaurant-menu-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-its_raghav-restaurant-menu-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "restaurantUrls": {
                        "title": "Restaurant URLs",
                        "type": "array",
                        "description": "Direct Yelp menu page URLs (e.g., https://www.yelp.com/menu/restaurant-name)",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "searchLocation": {
                        "title": "Search Location",
                        "type": "string",
                        "description": "City or address to search for restaurants (e.g., 'New York, NY')"
                    },
                    "searchCuisine": {
                        "title": "Search Cuisine",
                        "type": "string",
                        "description": "Cuisine type to filter by (e.g., 'italian', 'chinese', 'mexican')"
                    },
                    "maxRestaurants": {
                        "title": "Max Restaurants",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Maximum number of restaurants to scrape",
                        "default": 25
                    },
                    "platform": {
                        "title": "Platform",
                        "enum": [
                            "yelp"
                        ],
                        "type": "string",
                        "description": "Source platform (currently Yelp)",
                        "default": "yelp"
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
