# Zomato Restaurant Reviews Scraper ⭐ (`shahidirfan/zomato-restaurant-reviews-scraper`) Actor

Extract Zomato restaurant reviews, ratings, reviewer feedback, dates, and restaurant details at scale. Turn customer opinions into structured data for sentiment analysis, reputation monitoring, market research, competitor tracking, and restaurant insights.

- **URL**: https://apify.com/shahidirfan/zomato-restaurant-reviews-scraper.md
- **Developed by:** [Shahid Irfan](https://apify.com/shahidirfan) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 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/actors/running/actors-in-store.md#pay-per-usage

## 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

### What does Zomato Restaurant Reviews Scraper do?

Zomato Restaurant Reviews Scraper collects public restaurant reviews, ratings, reviewer details, engagement counts, and restaurant context from Zomato. Add one or more restaurant overview, `/info`, or `/reviews` URLs, choose a sort order, and receive a clean dataset with one item per review.

Use the results for restaurant reputation monitoring, customer sentiment analysis, local market research, competitor comparison, hospitality reporting, or AI and RAG datasets. Reviews can be exported to JSON, CSV, Excel, XML, and other formats supported by Apify.

### Why use Zomato Restaurant Reviews Scraper?

- **Review text and ratings** - Collect the written feedback and numeric rating attached to each public review.
- **Reviewer context** - Save reviewer names, profile URLs, published review counts, and follower counts when available.
- **Restaurant context** - Add the restaurant name, cuisines, opening status, hours, and dining or delivery rating summaries to every review.
- **Flexible ordering** - Collect newest, oldest, highest-rated, or lowest-rated reviews first.
- **Multiple restaurants** - Process overview and review URLs together in one run.
- **Controlled pagination** - Set both a total review limit and a page limit per restaurant.
- **Clean output** - Empty and null values are omitted, so exported datasets contain only published values.
- **Automation-ready data** - Schedule runs, send results to webhooks, or connect the dataset to spreadsheets and other systems.

### What data can you extract from Zomato reviews?

Each dataset item represents one restaurant review. Fields that Zomato does not publish for a particular review are omitted from that item.

| Field                      | Type   | Description                                       |
| -------------------------- | ------ | ------------------------------------------------- |
| `restaurant_id`            | Number | Zomato restaurant identifier                      |
| `restaurant_name`          | String | Restaurant name                                   |
| `restaurant_url`           | String | Public restaurant overview URL                    |
| `reviews_url`              | String | Public restaurant reviews URL                     |
| `cuisines`                 | String | Published cuisine list                            |
| `opening_status`           | String | Current published opening status                  |
| `opening_hours`            | Object | Published hours and schedule details              |
| `dining_rating`            | Number | Restaurant dining rating                          |
| `dining_reviews_count`     | Number | Published dining review count                     |
| `delivery_rating`          | Number | Restaurant delivery rating                        |
| `delivery_reviews_count`   | Number | Published delivery review count                   |
| `review_id`                | Number | Unique review identifier                          |
| `review_url`               | String | Direct public review URL                          |
| `review_text`              | String | Full published review text                        |
| `rating`                   | Number | Review rating, normally from 1 to 5               |
| `rating_type`              | String | Dining or delivery rating label                   |
| `experience`               | String | Published experience category                     |
| `review_date`              | String | Date or relative timestamp displayed by Zomato    |
| `reviewer_name`            | String | Reviewer display name                             |
| `reviewer_user_id`         | Number | Zomato reviewer identifier                        |
| `reviewer_profile_url`     | String | Public reviewer profile URL                       |
| `reviewer_profile_image`   | String | Reviewer image URL                                |
| `reviewer_reviews_count`   | Number | Reviewer's published review count                 |
| `reviewer_followers_count` | Number | Reviewer's published follower count               |
| `helpful_votes`            | Number | Helpful vote count                                |
| `comment_count`            | Number | Number of comments on the review                  |
| `comments`                 | Array  | Published comment details when available          |
| `management_comments`      | Array  | Restaurant management replies when available      |
| `review_photos`            | Array  | Review photo details when available               |
| `review_tags`              | Array  | Review tags when available                        |
| `scraped_at`               | String | ISO timestamp showing when the item was collected |

### How to use Zomato Restaurant Reviews Scraper

1. Open the Actor in Apify Console.
2. Add one or more public Zomato restaurant overview, `/info`, or `/reviews` URLs.
3. Choose the review sort order.
4. Set the maximum reviews and maximum pages per restaurant.
5. Keep the recommended proxy configuration for reliable access.
6. Run the Actor and open the dataset when the run finishes.
7. Download the results or connect them to your workflow.

### Input Parameters

| Parameter            | Type    | Required | Default                 | Description                                                                     |
| -------------------- | ------- | -------: | ----------------------- | ------------------------------------------------------------------------------- |
| `startUrls`          | Array   |      Yes | Elgin Cafe reviews URL  | One or more Zomato restaurant overview, `/info`, or `/reviews` URLs             |
| `sortBy`             | String  |       No | `newest`                | Review order: `newest`, `oldest`, `highestRated`, or `lowestRated`              |
| `results_wanted`     | Integer |       No | `20`                    | Maximum unique reviews saved across all restaurant URLs                         |
| `max_pages`          | Integer |       No | `10`                    | Maximum pages processed for each restaurant; a page contains up to five reviews |
| `proxyConfiguration` | Object  |       No | Residential Apify Proxy | Proxy settings used for reliable Zomato access                                  |

User-provided values always take priority. The bundled sample input is used only when a run has no supplied input.

### Usage Examples

#### Collect reviews from a restaurant overview URL

The Actor accepts the normal restaurant page and automatically targets its reviews:

```json
{
    "startUrls": [
        {
            "url": "https://www.zomato.com/amritsar/elgin-cafe-2-ranjit-avenue/"
        }
    ],
    "results_wanted": 20,
    "max_pages": 10
}
```

The same restaurant also works when copied from Zomato's Info tab:

```json
{
    "startUrls": [
        {
            "url": "https://www.zomato.com/amritsar/kava-grill-lounge-fairfield-by-marriott-ina-colony/info"
        }
    ],
    "results_wanted": 20,
    "max_pages": 10
}
```

#### Collect lowest-rated reviews first

Use a `/reviews` URL and focus on critical feedback for service or quality analysis:

```json
{
    "startUrls": [
        {
            "url": "https://www.zomato.com/amritsar/elgin-cafe-2-ranjit-avenue/reviews"
        }
    ],
    "sortBy": "lowestRated",
    "results_wanted": 50,
    "max_pages": 10
}
```

#### Compare multiple restaurants

Mix overview and review URLs in the same run. The total result limit applies across the full list:

```json
{
    "startUrls": [
        {
            "url": "https://www.zomato.com/amritsar/amritsari-haveli-ranjit-avenue"
        },
        {
            "url": "https://www.zomato.com/amritsar/crystal-restaurant-ina-colony/reviews"
        }
    ],
    "sortBy": "highestRated",
    "results_wanted": 100,
    "max_pages": 10,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": ["RESIDENTIAL"]
    }
}
```

### Sample Output

```json
{
    "restaurant_id": 19803359,
    "restaurant_name": "Elgin Cafe",
    "restaurant_url": "https://www.zomato.com/amritsar/elgin-cafe-2-ranjit-avenue",
    "reviews_url": "https://www.zomato.com/amritsar/elgin-cafe-2-ranjit-avenue/reviews",
    "cuisines": "Cafe, Asian, Continental, Italian, North Indian, Turkish, Chinese, Fast Food",
    "opening_status": "Open now",
    "dining_rating": 4.7,
    "dining_reviews_count": 311,
    "delivery_rating": 3.7,
    "delivery_reviews_count": 31,
    "review_id": 501970048,
    "review_url": "https://www.zoma.to/ONdeQYn",
    "review_text": "The food was amazing. Staff was very helpful.",
    "rating": 5,
    "rating_type": "DINING",
    "experience": "dining_order",
    "review_date": "7 days ago",
    "reviewer_name": "Aryan Rajput",
    "reviewer_user_id": 40469566,
    "reviewer_profile_url": "https://www.zomato.com/users/aryan-rajput-40469566",
    "reviewer_reviews_count": 0,
    "reviewer_followers_count": 15,
    "helpful_votes": 0,
    "comment_count": 0,
    "scraped_at": "2026-08-30T08:24:18.362Z"
}
```

### Tips for best results

- Use complete public restaurant URLs copied from Zomato.
- Overview, `/info`, `/reviews`, and other restaurant tab URLs work; tracking and review query parameters are normalized.
- Start with 20 reviews when validating a new restaurant, then increase the result and page limits.
- Each page contains up to five reviews, so the page limit can stop a run before `results_wanted` is reached.
- Use `lowestRated` to find recurring complaints and `newest` for current reputation monitoring.
- Keep residential proxy settings enabled for frequent or larger scheduled runs.
- Some restaurants have fewer public dining reviews than the rating summary count suggests. The Actor stops when no more review pages are available.

### Integrations and export formats

- **Google Sheets** - Build review trackers and collaborative research sheets.
- **Webhooks** - Send new datasets to internal systems after every run.
- **Make or Zapier** - Trigger no-code sentiment, alerting, and reporting workflows.
- **Apify API** - Start runs and retrieve datasets programmatically.
- **JSON and XML** - Feed applications, AI pipelines, and data warehouses.
- **CSV and Excel** - Analyze ratings and review text in spreadsheet tools.

### Frequently Asked Questions

#### Can I use a normal Zomato restaurant URL instead of a reviews URL?

Yes. Overview, `/info`, `/reviews`, and other restaurant tab URLs are normalized to the matching reviews page automatically.

#### Can I scrape several restaurants in one run?

Yes. Add multiple entries to `startUrls`. The Actor processes them in order and stops when it reaches the total `results_wanted` limit.

#### How does pagination work?

Each Zomato review page normally contains up to five reviews. `max_pages` limits pages per restaurant, while `results_wanted` limits the total unique records saved across the run.

#### Can I collect only negative reviews?

Use `lowestRated` to collect the lowest ratings first. You can then filter the exported dataset by the numeric `rating` field.

#### Are duplicate or null records included?

No. Reviews are deduplicated by restaurant and review ID. Null values, empty strings, empty objects, and empty arrays are removed from each output item.

#### Can I schedule regular reputation monitoring?

Yes. Create an Apify schedule and run the Actor daily, weekly, or at another interval. Send the resulting dataset to a webhook, spreadsheet, or database workflow.

#### What should I do if no reviews are returned?

Confirm that the URL points to a public Zomato restaurant with visible dining reviews. Keep the recommended proxy configuration enabled and verify that `max_pages` is at least 1.

#### Is it legal to scrape Zomato reviews?

Collecting public web data may be legal, but you are responsible for complying with applicable laws, Zomato's terms, privacy requirements, and any restrictions that apply to your use case.

### Related Actors

- [Airbnb Reviews Scraper](https://apify.com/shahidirfan/airbnb-reviews-scraper) - Collect guest feedback and ratings for hospitality research.
- [Target Reviews Scraper](https://apify.com/shahidirfan/target-reviews-scraper) - Extract product ratings and customer feedback from Target.
- [Flipkart Reviews Scraper](https://apify.com/shahidirfan/flipkart-reviews-scraper) - Collect product reviews and ratings from Flipkart.

### Support

For issues, feature requests, or custom Actor work, use the Issues tab on the Actor page or contact the developer through Apify.

### Legal Notice

This Actor is designed for legitimate collection of publicly available restaurant review data. Users are responsible for using the data responsibly and complying with applicable laws, platform terms, privacy rules, and usage limits.

# Actor input Schema

## `startUrls` (type: `array`):

Zomato restaurant overview, /info, or /reviews URLs. Other restaurant tab URLs are normalized automatically.

## `sortBy` (type: `string`):

Choose the order in which reviews are collected.

## `results_wanted` (type: `integer`):

Maximum number of unique reviews to save across all restaurant URLs.

## `max_pages` (type: `integer`):

Safety limit for pages processed from each restaurant. Each page contains up to five reviews.

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

Residential Apify Proxy is recommended for reliable Zomato access.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.zomato.com/amritsar/elgin-cafe-2-ranjit-avenue/reviews"
    }
  ],
  "sortBy": "newest",
  "results_wanted": 20,
  "max_pages": 10,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `overview` (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 = {
    "startUrls": [
        {
            "url": "https://www.zomato.com/amritsar/elgin-cafe-2-ranjit-avenue/reviews"
        }
    ],
    "sortBy": "newest",
    "results_wanted": 20,
    "max_pages": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("shahidirfan/zomato-restaurant-reviews-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 = {
    "startUrls": [{ "url": "https://www.zomato.com/amritsar/elgin-cafe-2-ranjit-avenue/reviews" }],
    "sortBy": "newest",
    "results_wanted": 20,
    "max_pages": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("shahidirfan/zomato-restaurant-reviews-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 '{
  "startUrls": [
    {
      "url": "https://www.zomato.com/amritsar/elgin-cafe-2-ranjit-avenue/reviews"
    }
  ],
  "sortBy": "newest",
  "results_wanted": 20,
  "max_pages": 10
}' |
apify call shahidirfan/zomato-restaurant-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,shahidirfan/zomato-restaurant-reviews-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/rXquatosedrUMCMr2/builds/Apfm6LvALd91kS7Xm/openapi.json
