Zomato Scraper - Restaurant Ratings & Prices by City avatar

Zomato Scraper - Restaurant Ratings & Prices by City

Pricing

from $0.49 / 1,000 restaurant scrapeds

Go to Apify Store
Zomato Scraper - Restaurant Ratings & Prices by City

Zomato Scraper - Restaurant Ratings & Prices by City

Zomato scraper: city slugs (Mumbai, Bangalore, Delhi NCR, Dubai...) to one row per restaurant with overall, dining and delivery ratings and review counts, cost for two, cuisines, locality, address, newly-opened and promoted flags, link and photo. For new-opening and rating watches.

Pricing

from $0.49 / 1,000 restaurant scrapeds

Rating

0.0

(0)

Developer

Superslow Sloth

Superslow Sloth

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Zomato scraper: restaurant ratings, prices and new openings by city

This Zomato scraper reads Zomato's restaurant list for each city you name (Mumbai, Bangalore, Delhi NCR, Pune, Dubai...) and returns one flat row per restaurant: the overall, dining and delivery ratings with their review counts, cost for two (in INR, or AED in the UAE), cuisines, locality and address, whether Zomato badges it Newly Opened, whether the listing is a paid placement, the link and the photo. Run it on a schedule and diff the dataset to get a per-city restaurant feed: which restaurants opened this week, which ratings moved, which places changed price band. Built for F&B suppliers, delivery and market analysts, and anyone tracking a city's dining scene.

No account, no API key, no login, no browser. One request returns 12 restaurants.

Input

FieldNotes
citiesZomato city slugs, one per line, as in the site's links (zomato.com/mumbai): mumbai, bangalore, ncr (Delhi NCR), pune, hyderabad, chennai, kolkata, goa, jaipur, ahmedabad, chandigarh, lucknow, kochi, indore, dubai, abudhabi and others. A zomato.com city link works too. Case does not matter. A slug Zomato does not know (delhi, delhi-ncr: Delhi is ncr) fails for that city at no charge and the run goes on.
maxItemsRestaurants to read per city (default 100, up to 500), in Zomato's own Popularity order. See "How deep it goes" below for why 500.
onlyNewlyOpenedReturn only restaurants Zomato badges "Newly Opened" (is_newly_opened). The others are read, not returned and not charged, and do not count toward maxItems. Expect around a dozen per city.
proxyConfigurationApify datacenter proxy by default.

Example input:

{
"cities": ["mumbai", "bangalore", "ncr"],
"maxItems": 500,
"onlyNewlyOpened": false
}

Output

FieldNotes
city, city_name, countryThe slug you asked for, and the city and country as Zomato names them (ncr is Delhi NCR, bangalore is Bengaluru).
positionWhere the restaurant sat in the city's list, 1 being first, counted over every listed entry of the pages read (promoted entries included, in place).
res_idZomato's restaurant id, a number, the unique key. A restaurant listed twice is returned once.
name, urlAs shown, and the link to the restaurant's Zomato page.
locality, addressThe locality (Lower Parel, Mumbai) and street address as shown.
cuisinesCuisine names in Zomato's order (empty list if none).
cost_for_two, cost_for_oneZomato's cost estimates as whole numbers in currency, from text such as ₹1,900 for two.
currencyINR for Indian cities, AED for Dubai and Abu Dhabi.
cost_textThe cost-for-two text exactly as shown.
rating, rating_labelThe overall rating (1 to 5) and Zomato's word for it (Excellent, Very Good). rating is null for a restaurant Zomato shows as "Not rated": it sends 0, which is not a rating of 0.
votesHow many reviews the overall rating is from: the dining and delivery counts added up.
dining_rating, dining_reviewsThe dine-in rating and its review count.
delivery_rating, delivery_reviewsThe delivery rating and its review count. A rating is null when Zomato shows none (too few reviews, or a place that does not deliver or seat); its count is still the real count, often 0.
rounded_countsWhich of votes, dining_reviews, delivery_reviews Zomato sent abbreviated. Popular places show 10.8K, which is stored as 10800 and is accurate only to the digits shown; this field says so instead of passing the rounding off as an exact count. Empty when every count was exact.
is_newly_openedTrue when Zomato badges the restaurant "Newly Opened".
is_promotedTrue for a paid placement ("Promoted"). Zomato mixes them into the list, most heavily on the first pages (11 of the first 12 in Mumbai, 50 of 500 overall).
image_urlThe restaurant's featured photo.

Example row (real values, Mumbai, 2026-10-21):

{
"city": "mumbai",
"city_name": "Mumbai",
"country": "India",
"position": 15,
"res_id": 39528,
"name": "Cream Centre - Vegetarian Legacy Since 1958",
"url": "https://www.zomato.com/mumbai/cream-centre-vegetarian-legacy-since-1958-lower-parel/info",
"locality": "Lower Parel, Mumbai",
"address": "3rd Floor, Phoenix Palladium, Opposite PVR, Senapati Bapat Marg, Lower Parel, Mumbai",
"cuisines": ["Street Food", "North Indian", "Chinese", "Biryani", "Mexican", "Pizza", "Pasta", "Italian"],
"cost_for_two": 1900,
"cost_for_one": 800,
"currency": "INR",
"cost_text": "₹1,900 for two",
"rating": 4.3,
"rating_label": "Very Good",
"votes": 10800,
"dining_rating": 4.4,
"dining_reviews": 8237,
"delivery_rating": 4.2,
"delivery_reviews": 2570,
"rounded_counts": ["votes"],
"is_newly_opened": false,
"is_promoted": true,
"image_url": "https://b.zmtcdn.com/data/pictures/8/39528/aa1c00e0b7ce2d0a3c011cab92293462_featured_v2.jpg"
}

Honest nulls

A field Zomato did not send is null, never 0 or "". A count Zomato sends as 0 is 0. cuisines and rounded_counts are empty lists when there are none.

  • No opening hours, phone, menu or reviews text. The city list does not carry them; this is the list, one row per restaurant.
  • No opening date. Zomato's "Newly Opened" badge is a flag with no date; diff scheduled runs to date an opening yourself.
  • No distance. The list's distance is measured from the city's default point, not from anywhere you chose, so it is left out.

Pricing

Pay per event:

  • $0.002 per run (actor-start), charged only after your input is validated, so a run that fails on bad input costs nothing.
  • $0.00049 per restaurant row written (restaurant-scraped), i.e. $0.49 per 1,000 restaurants. A row that is not written is not charged: restaurants filtered by onlyNewlyOpened, repeats, and cities Zomato does not know are free.

How it fetches

It reads the same web routes zomato.com's own city page uses: the city page data (for the city's location), a csrf token, then the restaurant search, 12 at a time, in Zomato's default Popularity order. Measured 2026-10-21: HTTP 200 JSON from Apify datacenter addresses (3 of 3) and from a plain connection, no account needed. A refusal (403, 429, 5xx), a 200 without the list data, a rejected token (401) or a dropped connection is treated as the address being blocked: the actor rotates to a fresh address, fetches a new token (the token is tied to the session's cookies) and retries.

Things worth knowing, all measured:

  • How deep it goes: about 500 restaurants per city. Zomato says Mumbai has 21,637 restaurants and Bangalore 19,128, but its list stops after about 500 however it is paged (Mumbai and Shimla both ended after the 501st entry), so at most 500 per city are offered. Reading a whole city's list (42 pages) took 26 seconds from a test machine. The site's own total is logged, not used.
  • The end of the list. The page after the last answers with no restaurants while still saying there are more, so the actor stops on the empty page.
  • No sort. Zomato's sort options sort only the first 12 and then return nothing, so none is offered; the order is Zomato's Popularity order.
  • Unknown cities. For a slug it does not know, Zomato answers its "404" page carrying the location of the previous city the session looked at. The actor recognises that page and fails the city rather than return another city's restaurants under its name.
  • Duplicates. One Mumbai walk listed one restaurant twice in 501 entries; it is returned once.

If Zomato changes its page data, the run fails with a message instead of returning empty rows.