# District Movies Scraper — India Catalog, Cast & Critic Reviews (`yugenox/district-movies-scraper`) Actor

Scrape movies from District (district.in, India): now showing in any city or the full catalog of 2,000+ titles. Synopsis, cast with bios, trailers, posters, languages, formats, show counts, per-outlet critic ratings and critic reviews (TOI, NDTV, India Today and more). No login needed.

- **URL**: https://apify.com/yugenox/district-movies-scraper.md
- **Developed by:** [Yugenox Corp](https://apify.com/yugenox) (community)
- **Categories:** Videos, News, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 movies

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## District Movies Scraper: India Movie Catalog, Cast & Critic Reviews

Scrape movie data from **District** (district.in, the going-out app by Zomato) for any Indian city, or for its **full catalog of 2,000+ movies**.

For each movie you get the synopsis, cast with bios, trailers, posters, languages, genres, certificate, runtime, release date, and show counts per city, language and screen format (IMAX, 4DX, 3D and others). You also get **per-outlet critic ratings** and **critic reviews** from Indian outlets such as Times of India, India Today, NDTV, The Indian Express, Bollywood Hungama, News18, Rediff, Pinkvilla, Firstpost and Taran Adarsh.

No login and no cookies are needed. The scraper is fast: a whole city takes about 15–30 seconds, and 300 catalog movies take about 20 seconds.

### What you can do with it

- **Box-office and release tracking.** See what is playing in Mumbai, Delhi-NCR, Bengaluru, Hyderabad and 1,000+ other cities, how many shows each title has per language and format, and which titles are new releases or open for advance booking.
- **Critic consensus.** Get structured ratings from each outlet plus an average score, and join them to your own box-office or streaming data.
- **Review datasets for NLP and sentiment work.** Full-length critic reviews with reviewer and date, one row per review.
- **Content and metadata enrichment.** Add posters, trailers (YouTube links), synopses and cast lists to your movie database, app or newsletter.
- **Regional cinema research.** Filter by Telugu, Tamil, Malayalam, Kannada, Bengali, Marathi, Punjabi and more.

### Modes

| Mode | What you get |
|---|---|
| **Now showing** (default) | Every movie currently playing or open for booking in the cities you list, ordered by District's popularity ranking. A movie playing in several cities is returned once, with a per-city breakdown of shows. |
| **Full catalog** | Every movie District has a page for: past, current and upcoming, newest first. Combine it with the release-date filters or with *Only movies with critic reviews*. |
| **Specific movies** | Paste District movie URLs or ids. Only those movies are scraped. |

### Input

| Field | Description |
|---|---|
| `mode` | `nowShowing` or `fullCatalog`. |
| `cities` | City names, e.g. `mumbai`, `bengaluru` / `bangalore`, `delhi-ncr`, `hyderabad`, `chennai`, `pune`, `kolkata`. Neighbourhoods such as `Bandra` also work, and `top` means District's 12 top cities. |
| `movieUrls` | District movie URLs (`https://www.district.in/movies/...-MV207237`) or ids (`207237`). |
| `includeDetails` | Synopsis, cast, trailers, image gallery and all languages (default on). |
| `includeCriticReviews` | Critic reviews with the outlet's rating (default on). |
| `fullReviewText` | Complete review text instead of a ~400-character excerpt (default off). |
| `reviewsAsSeparateItems` | Also output one row per review (`dataType: "review"`). |
| `includeCastBios` | Short bio for each cast member where available (default on). |
| `onlyWithCriticReviews` | Keep only movies with at least one critic rating or review. |
| `languages`, `genres`, `formats` | Filters. Empty means all. Formats match partially (`imax` matches `IMAX 2D`). |
| `releasedAfter`, `releasedBefore` | `YYYY-MM-DD`, `today`, or relative values like `30 days`. |
| `maxItems` | Maximum number of movie rows (default 200, 0 means no limit). |

#### Example inputs

Everything playing in Mumbai and Bengaluru:

```json
{ "cities": ["mumbai", "bengaluru"] }
```

Telugu action movies across the top 12 cities, listing only:

```json
{ "cities": ["top"], "languages": ["Telugu"], "genres": ["Action"], "includeCriticReviews": false }
```

Every catalog movie released in 2026 that has critic reviews, one row per review with full text:

```json
{ "mode": "fullCatalog", "releasedAfter": "2026-01-01", "onlyWithCriticReviews": true, "reviewsAsSeparateItems": true, "fullReviewText": true, "maxItems": 0 }
```

Upcoming movies (release date after today):

```json
{ "mode": "fullCatalog", "releasedAfter": "+1 day", "maxItems": 100 }
```

### Output

One row per movie. The sample below is shortened:

```json
{
  "dataType": "movie",
  "contentId": 207237,
  "name": "Resident Evil",
  "url": "https://www.district.in/movies/resident-evil-movie-tickets-in-mumbai-MV207237",
  "releaseDate": "2026-09-18",
  "isReleased": true,
  "languages": ["English", "Hindi", "Tamil", "Telugu"],
  "genres": ["Horror", "Sci-Fi", "Thriller", "Action"],
  "censor": "A",
  "durationMin": 94,
  "popularityRank": 5,
  "averageCriticRating": 3.5,
  "criticRatingCount": 4,
  "criticReviewCount": 4,
  "synopsis": "A courier is hired to deliver a package to a remote hospital. Along the way he becomes caught in a viral outbreak...",
  "posterUrl": "https://b.zmtcdn.com/data/edition_assets/17893843514534149.jpg",
  "cities": [
    {
      "city": "mumbai", "popularityRank": 8, "bookingStatus": null, "totalSessions": 204,
      "formats": [
        { "language": "English", "format": "4DX-2D", "sessions": 12, "nextShowDate": "2026-09-24" },
        { "language": "English", "format": "2D", "sessions": 117, "nextShowDate": "2026-09-24" }
      ]
    },
    { "city": "delhi-ncr", "popularityRank": 7, "totalSessions": 306, "formats": ["..."] }
  ],
  "formats": [{ "language": "English", "format": "IMAX 2D" }, { "language": "Hindi", "format": "2D" }],
  "totalSessions": 756,
  "criticRatings": [
    { "outlet": "Times of India", "rating": 4, "ratingBase": 5 },
    { "outlet": "Bollywood Hungama", "rating": 3.5, "ratingBase": 5 }
  ],
  "criticReviews": [
    {
      "reviewId": 6446,
      "outlet": "Bollywood Hungama",
      "reviewer": "Bollywood Hungama News Network",
      "date": "2026-09-18",
      "rating": 3.5,
      "ratingBase": 5,
      "text": "Zach Cregger and Shay Hatten's story is impressive as it remains in the zone of the RESIDENT EVIL series...",
      "textTruncated": true,
      "textLength": 3530,
      "outletLogoUrl": "https://cdn.district.in/movies-assets/images/cinema/hungama-....png"
    }
  ],
  "cast": [{ "id": 175621, "name": "Austin Abrams", "imageUrl": "https://cdn.district.in/...jpeg", "bio": null }],
  "trailers": [{ "title": "Resident Evil - Official Teaser Trailer", "url": "https://youtu.be/V6Zrk18sEx0", "source": "youtube", "duration": "1:46", "thumbnailUrl": "https://cdn.district.in/...jpg" }],
  "images": ["https://cdn.district.in/movies-assets/images/cinema/Resident-Evil-....jpg"],
  "bannerUrl": null,
  "sessionMovieCodes": ["OBCQPD", "OB66RB"],
  "source": "nowShowing",
  "scrapedAt": "2026-09-24T08:25:14.904Z"
}
```

With **Reviews as separate rows** turned on, each review is also output as its own row: `dataType: "review"`, `contentId`, `movieName`, `movieUrl`, `releaseDate`, `outlet`, `reviewer`, `date`, `rating`, `ratingBase`, `text`, `textTruncated`, `textLength`, `outletLogoUrl`.

Field notes:

- `averageCriticRating` is the mean of the critic outlets' ratings, rescaled to 0–5. Some older titles also list an IMDb score (out of 10) in `criticRatings`; it is kept there but not counted in the critic average.
- `isReleased` is `false` for movies whose release date (India time) is still ahead, even if advance booking is open.
- `cities[].totalSessions` / `formats[].sessions` are the show counts District lists for that city at scrape time; `nextShowDate` is the next date with shows.
- `popularityRank` is District's own ordering of the city's movie list (1 = top). The top-level value is the best rank across your cities.

### Reliability

Every run finishes with a clear status message, and you only pay for rows that actually landed in the dataset.

- **Bad input never fails a run.** An unknown city, a non-District URL, a misspelt mode or date ends the run with 0 rows, no charge, and a message that says what to fix (with city suggestions). Common aliases such as `maxResults`, `limit`, `city`, `startUrls` and `includeReviews` are accepted (and take effect even though the platform pre-fills the standard fields with their defaults). A disabled or unusable proxy setting falls back to the default Apify proxy instead of ending the run.
- **Best-available data when District misbehaves.** Requests retry on fresh IPs with backoff; a blocked datacenter IP hands the same request to India residential proxies automatically; a retired listing endpoint falls back to District's discovery feed; a missing catalog sitemap is re-discovered or, failing that, the run returns what is now showing in the 12 top cities and says so ("Partial — …"). A movie whose reviews could not be fetched is still delivered with its ratings, and a now-showing movie whose detail page will not load is delivered with its listing data (name, genres, poster, formats, show counts) — the status message says how many.
- **Time limit and budget.** The run stops about 75 s before its timeout (a fifth of the run on very short timeouts) and ends as "Partial — …" with everything saved so far, including movies already fetched when the clock ran out. With a maximum charge set, the budget is checked before each row is written, so no row is delivered unpaid and none is paid for undelivered — also with many rows being written in parallel. If the platform restarts a run (server migration), movies saved before the restart are neither written nor charged again.
- **Never a FAILED run on District's account.** Even an unexpected error ends the run SUCCEEDED with the rows already saved, a "Stopped — …" status and a `RUN_REPORT` record in the key-value store with request counts, proxy tier and per-stage statistics.

### FAQ

**Which cities are supported?**
Every city District lists for movies (more than 1,100), including all metros and most tier-2 and tier-3 towns. Common spellings like "Bangalore", "Bombay", "Gurugram" and "Delhi NCR" are understood. An unknown city is reported clearly and does not fail silently.

**How much does it cost?**
You pay per row delivered to your dataset: $2 per 1,000 movies, and $0.50 per 1,000 review rows. Review rows are only created when **Reviews as separate rows** is on; the critic ratings and reviews inside each movie row are included in the movie price. There is no start fee, and failed requests, movies removed by your filters and rows beyond your charge limit are never billed. For example, everything showing in Mumbai (about 40 movies, with details and reviews) costs about $0.08, the 12 top cities (about 120 movies) about $0.24, and the full catalog of about 2,300 movies about $4.60.

**Are the critic reviews complete?**
You get the reviews and ratings District displays on each movie page, with the reviewer, date and outlet. District mainly shows positive and mixed reviews: nearly every rating on the site is 3/5 or higher. Treat the data as "critic reviews as displayed on District", not an unbiased sample of all reviews. For balanced sentiment analysis, combine it with other sources.

**Why is review text shortened by default?**
Reviews belong to their publishers. The default output is an excerpt plus the full length. Turn on **Full review text** to get the complete text for research use.

**How many movies have critic reviews?**
Usually the big Hindi, English and South Indian releases. That is about a third of what is playing in a major city on a given day, and about 250 movies (roughly 1 in 9) across the full catalog, with 600+ reviews in total. Scanning the whole catalog for them takes about a minute.

**Does it include showtimes, cinemas and ticket prices?**
This actor returns show counts per city, language and format. For individual showtimes, cinemas, seat prices and occupancy, use a dedicated District showtimes scraper.

**How fast is it?**
One city takes about 5–30 seconds with details and reviews. The full catalog runs at about 10–15 movies per second.

**Audience ratings and "interested" counts?**
District does not publish these to logged-out visitors, so they are not included.

**Is it legal to scrape District?**
This actor collects only public information that District shows to every visitor without an account: movie titles, synopses, cast lists, trailers, show counts, and the critic ratings and reviews displayed on each movie page. Scraping publicly available data is generally legal, but you are responsible for how you use the results. Rows include the names of actors and film critics, and short cast bios where District has them, which can count as personal data, so only keep and use it for a legitimate purpose. Critic reviews remain the work of their publishers: the default excerpt suits reference and analysis, and republishing full review text may need the publisher's permission. Follow the laws that apply to you (such as India's DPDP Act, GDPR, PIPEDA or CCPA) and District's terms, and check with a lawyer if you are unsure. Read more in Apify's guide [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

**Does it access any private data?**
No. The actor needs no District account, login, cookie or phone number, and never sees anyone's bookings, payment details or profiles. It reads the same public movie listings, movie pages and critic reviews that the District website shows to a visitor who is not logged in. Audience reactions that District shows only to signed-in users are not collected.

# Actor input Schema

## `mode` (type: `string`):

<b>Now showing</b>: every movie currently playing (or open for advance booking) in the cities below, with show counts per language and format.<br><b>Full catalog</b>: every movie District has a page for (2,000+ titles: past, current and upcoming), newest first. Cities are ignored in this mode.

## `cities` (type: `array`):

City names, e.g. mumbai, bengaluru (or bangalore), delhi-ncr, hyderabad, chennai, pune, kolkata, ahmedabad. Neighbourhoods such as "Bandra" also work. Use <code>top</code> for District's 12 top cities. One movie playing in several cities is returned once, with a per-city breakdown.

## `movieUrls` (type: `array`):

District movie URLs (https://www.district.in/movies/...-MV207237) or numeric movie ids. When set, only these movies are scraped and the mode and cities are ignored. A URL that contains a city ("-in-mumbai-") also returns that city's show counts.

## `includeDetails` (type: `boolean`):

Synopsis, cast, trailers, image gallery and all languages. Turn off in "Now showing" mode for a faster, lighter listing (name, genres, censor rating, duration, poster, formats, show counts and critic ratings are still included). Always on for the full catalog and specific movies.

## `includeCriticReviews` (type: `boolean`):

Critic reviews shown on District (Times of India, India Today, NDTV, The Indian Express, Bollywood Hungama, News18, Rediff, Pinkvilla, Firstpost, Taran Adarsh...) with reviewer, date and the outlet's rating. Only fetched for movies that have reviews.

## `fullReviewText` (type: `boolean`):

Off: each review has a ~400-character excerpt plus its full length. On: the complete review text (usually 2,000–7,000 characters).

## `reviewsAsSeparateItems` (type: `boolean`):

Also output one row per critic review (dataType "review") instead of nesting reviews inside each movie row. Handy for spreadsheets and sentiment analysis. Movie rows keep their ratings and review counts.

## `includeCastBios` (type: `boolean`):

Short biography for each cast member where District has one.

## `onlyWithCriticReviews` (type: `boolean`):

Skip movies that have no critic rating or review on District. In full-catalog mode roughly 1 title in 9 qualifies (~250 movies; a full scan takes about a minute), so the run checks many more movies than it returns (you only pay for returned rows).

## `languages` (type: `array`):

Keep movies in any of these languages, e.g. Hindi, Telugu, Tamil, English, Malayalam, Kannada. Empty = all.

## `genres` (type: `array`):

Keep movies with any of these genres, e.g. Action, Drama, Comedy, Thriller, Horror. Empty = all.

## `formats` (type: `array`):

Keep movies playing in any of these formats, e.g. IMAX, 4DX, 3D, 2D. Partial match: "imax" matches "IMAX 2D". Empty = all.

## `releasedAfter` (type: `string`):

YYYY-MM-DD, or relative like "30 days" (that many days ago). Combine with the full catalog to get e.g. this year's releases.

## `releasedBefore` (type: `string`):

YYYY-MM-DD, "today" (excludes upcoming movies), or relative like "30 days" (that many days from now).

## `maxItems` (type: `integer`):

Maximum number of movie rows. Review rows (when output separately) don't count toward this. 0 = no limit.

## `maxConcurrency` (type: `integer`):

Parallel requests. The default is fast and safe.

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

Apify datacenter proxy works well and is the default. If requests start failing, the actor switches to residential (India) automatically.

## Actor input object example

```json
{
  "mode": "nowShowing",
  "cities": [
    "mumbai"
  ],
  "includeDetails": true,
  "includeCriticReviews": true,
  "fullReviewText": false,
  "reviewsAsSeparateItems": false,
  "includeCastBios": true,
  "onlyWithCriticReviews": false,
  "maxItems": 10,
  "maxConcurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped movies (and review rows, if enabled).

## `run` (type: `string`):

Status and statistics for this run.

# 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 = {
    "mode": "nowShowing",
    "cities": [
        "mumbai"
    ],
    "maxItems": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("yugenox/district-movies-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 = {
    "mode": "nowShowing",
    "cities": ["mumbai"],
    "maxItems": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("yugenox/district-movies-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 '{
  "mode": "nowShowing",
  "cities": [
    "mumbai"
  ],
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call yugenox/district-movies-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,yugenox/district-movies-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/Pge2D9kIRIec1Q2bp/builds/mXLnpIF81bLL0MIum/openapi.json
