# Zomato Restaurant Scraper - India (`lulzasaur/zomato-scraper`) Actor

Scrape restaurant data from Zomato India. Browse restaurants by city, filter by cuisine. Get names, addresses, ratings, reviews, cuisines, price range, phone, GPS, and hours.

- **URL**: https://apify.com/lulzasaur/zomato-scraper.md
- **Developed by:** [lulz bot](https://apify.com/lulzasaur) (community)
- **Categories:** E-commerce
- **Stats:** 5 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Zomato Restaurant Scraper

Scrape restaurant data from [Zomato](https://www.zomato.com), India's leading food discovery platform. Extract ratings, reviews, cuisines, prices, addresses, phone numbers, GPS coordinates, and opening hours.

**Note:** Zomato is India-only. US and other non-Indian cities redirect to a goodbye page. Use Indian city slugs only.

### Features

- **City browsing** - Scrape restaurants from any Indian city
- **Cuisine filter** - Filter by cuisine type (Chinese, Italian, North Indian, etc.)
- **JSON-LD extraction** - Leverages structured data for reliable, rich output
- **Detail pages** - Optional deep scrape for phone, hours, GPS, full address
- **Pagination** - Automatically follows pages up to your result limit

### Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `city` | string | `mumbai` | Indian city slug (e.g. mumbai, delhi-ncr, bangalore, hyderabad, pune, kolkata, chennai) |
| `cuisine` | string | - | Optional cuisine filter (e.g. chinese, italian, north-indian, biryani, pizza, cafe) |
| `maxResults` | integer | `50` | Maximum number of restaurants to scrape |
| `scrapeDetails` | boolean | `false` | Visit detail pages for richer data (phone, hours, GPS). Slower. |
| `proxyConfiguration` | object | - | Optional proxy settings |

### Output

Each result includes:

| Field | Description |
|-------|-------------|
| `businessName` | Restaurant name |
| `address` | Full address |
| `city` | City name |
| `latitude` | GPS latitude |
| `longitude` | GPS longitude |
| `rating` | Average rating (0-5 scale) |
| `reviewCount` | Number of reviews/ratings |
| `cuisines` | Array of cuisine types |
| `priceRange` | Price range indicator |
| `phone` | Phone number (detail pages) |
| `openingHours` | Opening hours (detail pages) |
| `menuUrl` | Link to menu page |
| `imageUrl` | Restaurant image URL |
| `url` | Zomato restaurant page URL |
| `scrapedAt` | ISO timestamp of when the data was scraped |

### Usage Examples

#### Browse Mumbai restaurants

```json
{
    "city": "mumbai",
    "maxResults": 50
}
```

#### Chinese restaurants in Bangalore

```json
{
    "city": "bangalore",
    "cuisine": "chinese",
    "maxResults": 30
}
```

#### Detailed scrape of Delhi restaurants

```json
{
    "city": "delhi-ncr",
    "maxResults": 20,
    "scrapeDetails": true
}
```

#### Cafes in Pune

```json
{
    "city": "pune",
    "cuisine": "cafe",
    "maxResults": 100
}
```

### Supported Cities

Major Indian cities: mumbai, delhi-ncr, bangalore, hyderabad, pune, kolkata, chennai, ahmedabad, jaipur, lucknow, chandigarh, goa, kochi, indore, nagpur, vadodara, coimbatore, surat, visakhapatnam, and more.

### How It Works

1. **Listing pages**: Scrapes `zomato.com/{city}/restaurants` and extracts Restaurant schema from JSON-LD structured data. The ItemList schema contains 9+ restaurants per page.

2. **Detail pages**: When `scrapeDetails` is enabled, visits each restaurant page to extract the full Restaurant schema including phone, opening hours, GPS coordinates, and menu URL.

3. **JSON-LD priority**: Zomato embeds rich JSON-LD data (Restaurant schema with aggregateRating, geo, servesCuisine, etc.), which is the primary extraction method.

4. **Pagination**: Follows `?page=N` query parameters to scrape multiple listing pages.

### Notes

- Zomato is India-only -- US and other non-Indian locations will not work
- No anti-bot protection detected (standard HTML responses)
- SSR via React Helmet ensures JSON-LD is available without JavaScript execution
- Ratings are on a 0-5 scale
- GPS coordinates and phone numbers require `scrapeDetails: true`

# Actor input Schema

## `city` (type: `string`):

Indian city to scrape restaurants from. Use the Zomato URL slug (e.g. mumbai, delhi-ncr, bangalore, hyderabad, pune, kolkata, chennai, ahmedabad, jaipur, lucknow, chandigarh, goa).

## `cuisine` (type: `string`):

Optional cuisine type to filter by (e.g. chinese, italian, north-indian, south-indian, biryani, pizza, cafe). Leave empty for all cuisines.

## `maxResults` (type: `integer`):

Maximum number of restaurants to scrape.

## `scrapeDetails` (type: `boolean`):

Visit each restaurant's detail page for richer data (phone, hours, full address, GPS). Slower but more complete.

## `proxyConfiguration` (type: `object`):

Optional proxy configuration for requests.

## Actor input object example

```json
{
  "city": "mumbai",
  "maxResults": 50,
  "scrapeDetails": false
}
```

# 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 = {
    "city": "mumbai"
};

// Run the Actor and wait for it to finish
const run = await client.actor("lulzasaur/zomato-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 = { "city": "mumbai" }

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

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

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

```

## CLI example

```bash
echo '{
  "city": "mumbai"
}' |
apify call lulzasaur/zomato-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lulzasaur/zomato-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/bHx0ap9FsTA8fpqFX/builds/76olu3bgdkrQgngMS/openapi.json
