# Douban Movie Scraper (`axiomworks/douban-movie-scraper`) Actor

Find movies through Douban search suggestions, collect a tagged list or the Top250, or look up subjects by ID. The dataset includes titles, years, ratings, posters, and available genres, directors, actors, and runtime. Top250 results can also include rank, rating count, and quote.

- **URL**: https://apify.com/axiomworks/douban-movie-scraper.md
- **Developed by:** [Axiom Works](https://apify.com/axiomworks) (community)
- **Categories:** Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $7.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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Douban Movie Scraper

**Returns:** one row per movie with title, year, rating, ratingCount, genres, directors, actors, and duration.
**Input:** `{"mode":"top250","maxItems":25,"includeDetails":true}`
**Best for:** movie catalog research, rating analysis, and film discovery lists.

```json
{"id":"1292052","title":"肖申克的救赎 The Shawshank Redemption","year":1994,"rating":9.7,"region":"美国","duration":"142分钟","directors":["弗兰克·德拉邦特"]}
```

### What does Douban Movie Scraper do?

Douban Movie Scraper collects public movie information from Douban's Top250 list, its hot movie tags, search suggestions, and individual movie subject abstracts. It gives each result a stable Douban subject ID and the page or endpoint URL that supplied the row. Choose one mode and a shared `maxItems` limit, then export the dataset. The Actor uses the public movie pages and JSON endpoints described here. No Douban login is needed.

The Top250 mode reads the ordered movie cards. A card supplies its list position, title, original and alternate titles when shown, release year, region, genres, score, rating count, quote, and poster URL. With `includeDetails` enabled, the Actor also asks Douban's public subject abstract endpoint for directors, actors, duration, and any region or genre information missing from the card. It does not visit movie subject detail pages or short comments.

Hot mode reads a Douban movie tag using the public search subjects endpoint. Search mode reads the public subject suggestion endpoint for a title or phrase. Subjects mode accepts numeric subject IDs and standard Douban movie URLs and asks the subject abstract endpoint for each. These modes have different source fields: a search suggestion does not carry a Top250 quote or rating count, for example. Empty values stay empty in the output instead of being guessed.

### What data can you get?

| Field | Meaning | Availability |
| --- | --- | --- |
| `id` | Stable Douban subject ID | Every row |
| `sourceUrl` | Page or JSON endpoint supplying the row | Every row |
| `subjectId` | Douban subject identifier | Every row |
| `rank` | Position in the chosen list or input order | Every row |
| `title` | Movie title displayed by Douban | Every row when available |
| `originalTitle` | Original or search subtitle | Top250 and some suggestions |
| `alternateTitles` | Other titles displayed on a Top250 card | Top250 when present |
| `year` | Release year | When listed |
| `region` | Production region text | Top250 or subject abstract |
| `genres` | Genre labels | Top250 or subject abstract |
| `rating` | Douban average rating | When listed |
| `ratingCount` | Number of people who rated a Top250 movie | Top250 |
| `quote` | Brief quote displayed under a Top250 card | Top250 when present |
| `posterUrl` | Poster image URL | List cards and suggestions |
| `directors` | Director names | Subject abstract when requested |
| `actors` | Cast names | Subject abstract when requested |
| `duration` | Runtime text | Subject abstract when requested |
| `isTv` | Subject abstract television flag | Subject abstract when requested |
| `subjectUrl` | Canonical Douban subject link | Every row |
| `subtype` | Source subject type | Abstract when supplied |
| `episodesCount` | Episode count | Abstract when supplied |
| `durationMinutes` | Minutes parsed from duration | When duration contains minutes |
| `shortComment` | One featured abstract comment | Abstract when supplied |
| `shortCommentAuthor` | Featured comment author | Abstract when supplied |

The overview table highlights the title, year, rating, rating count, genres, region, directors, actors, duration, source URL, and ID. The full JSON dataset includes every field above. Fields that Douban does not expose for a selected mode are `null` or empty arrays. A `rank` in search mode means suggestion order; in subjects mode it means input order. In Top250 mode it is the list's displayed rank. These meanings matter if you combine rows from several runs.

The Actor does not manufacture a review count for search suggestions or individual subject abstracts. It also does not infer an original title from the longer subject abstract title. Douban's data can include Chinese, English, and other scripts. Strings are preserved as Douban displays them, except for trimming surrounding whitespace and parsing numeric values. A single row identifies a movie, even when several pages mention the same subject ID in a run.

### How to use

Open the Actor input form and choose `top250` for the public ranked list. Leave `includeDetails` on if you need directors, cast, runtime, region, or genres from the subject abstract. Set `maxItems` to the total rows you want across all targets. A run stops saving data when it reaches that count. The Top250 list is paged in groups of 25; the Actor advances through those pages until it reaches the limit or the end of the public list.

Choose `hot` to collect a movie tag. Set `tag` to a Douban movie tag such as `热门` or `豆瓣高分`. The Actor requests the tag's public movie JSON list in pages and stops when the response is empty or the result limit is reached. The position recorded as `rank` is the position within that returned list. The values and ordering can change as Douban updates its catalog and recommendations.

Choose `search` and enter `searchQuery` to receive Douban subject suggestions. This endpoint returns a short list and has no pagination. If fewer suggestions exist than `maxItems`, the Actor returns fewer rows. Search is useful for resolving a movie name to a subject ID. The query can use non English words, including Chinese film names.

Choose `subjects` and put one or more numeric IDs or standard Douban movie subject URLs into `subjectIds`. The Actor reads each public subject abstract and removes duplicate IDs before saving rows. A missing subject is skipped. If none of the supplied IDs return a public subject, the run finishes with zero rows and a status message that says to check the IDs or proxy setting.

In subjects mode, `subjectUrls` and a single `subjectId` are merged with `subjectIds`. Duplicate subjects are fetched once, including an ID repeated as a URL. URL query strings are accepted. For example, `{"mode":"subjects","subjectId":"1292052","maxItems":1}` performs one lookup.

Search defaults to Douban’s suggestions or tag matches, which can include related titles. Set `searchMatch` to `titleContains` to keep only results whose source title or subtitle contains the query. Matching normalizes Unicode and letter case; it does not translate titles. Filtering happens before detail requests and charging. It can produce fewer rows than `maxItems`, including zero. Use Chinese title fragments for Chinese source titles.

### Input

| Field | Type | Use |
| --- | --- | --- |
| `mode` | enum | `top250`, `hot`, `search`, or `subjects`; default `top250` |
| `tag` | string | Tag for hot mode; default `热门` |
| `searchQuery` | string | Movie phrase for search mode |
| `searchQueries` | string array | Extra titles for search mode (up to 50, merged with `searchQuery`, duplicates removed) |
| `subjectIds` | string array | Numeric IDs or HTTPS Douban movie URLs for subjects mode |
| `subjectUrls` | string array | URL alias, merged with subjectIds; default empty |
| `subjectId` | string | Single ID or URL alias; default empty |
| `searchMatch` | enum | `any` (default) or `titleContains`; used only in search mode |
| `maxItems` | integer | Shared total row limit across pages, queries and IDs, 1 to 10000; default 50 |
| `includeDetails` | boolean | Read subject abstracts for extra fields; default true |
| `proxyConfiguration` | object | Apify Proxy configuration; datacenter by default |

Example Top250 input:

```json
{"mode":"top250","maxItems":25,"includeDetails":true,"proxyConfiguration":{"useApifyProxy":true}}
```

Example direct movie lookup:

```json
{"mode":"subjects","subjectIds":["1292052","https://movie.douban.com/subject/3541415/"],"maxItems":2,"includeDetails":true}
```

The input form supplies a Top250 prefill for trying the Actor. API calls should pass the mode and any mode specific target needed by that call. An empty `searchQuery` cannot work in search mode, and subjects mode needs at least one ID or URL. Malformed subject URLs are input errors. Valid IDs with no public result produce no data rather than an error record. Proxy settings can be adjusted in the form if Douban blocks a request from the current network.

### Output

The following record came from a local subjects run using ID 1292052. Scores and source text can change. Its sourceUrl identifies the public abstract endpoint; list-only values are null.

```json
{
  "id": "1292052",
  "sourceUrl": "https://movie.douban.com/j/subject_abstract?subject_id=1292052",
  "subjectId": "1292052",
  "rank": 1,
  "title": "肖申克的救赎 The Shawshank Redemption",
  "originalTitle": null,
  "alternateTitles": [],
  "year": 1994,
  "region": "美国",
  "genres": [
    "犯罪",
    "剧情"
  ],
  "rating": 9.7,
  "ratingCount": null,
  "quote": null,
  "posterUrl": null,
  "directors": [
    "弗兰克·德拉邦特"
  ],
  "actors": [
    "蒂姆·罗宾斯",
    "摩根·弗里曼",
    "鲍勃·冈顿",
    "威廉·赛德勒",
    "克兰西·布朗",
    "吉尔·贝罗斯",
    "马克·罗斯顿",
    "詹姆斯·惠特摩",
    "杰弗里·德曼",
    "拉里·布兰登伯格"
  ],
  "duration": "142分钟",
  "isTv": false,
  "subjectUrl": "https://movie.douban.com/subject/1292052/",
  "subtype": "Movie",
  "episodesCount": null,
  "durationMinutes": 142,
  "shortComment": "恐惧让你沦为囚犯，希望让你重获自由。——《肖申克的救赎》",
  "shortCommentAuthor": "如小果"
}
```

The abstract fields `subjectUrl`, `subtype`, `episodesCount`, `durationMinutes`, `shortComment`, and `shortCommentAuthor` come from the subject abstract and are `null` when details are off or Douban omits them. `null` values indicate that the selected source did not provide that field. Empty arrays mean the source did not list entries for that array.

### How much does it cost?

This Actor is charged per result. One saved movie row is one result event. The Actor stops before saving rows beyond `maxItems`, so that limit also bounds the number of result events. It does not add an enrichment event. The current terms for this Actor are shown in its Apify Pricing tab. Check that tab before running a large collection, since the displayed terms can change over time.

A Top250 run with details enabled makes an additional public abstract request for each movie. That request improves fields such as directors and duration when Douban makes them available, but the output remains one row per movie. A search may return fewer suggestions than requested and therefore fewer result events. A target that returns no public movies creates no result rows. Network retries and internal checks do not create placeholder result rows.

### Use with AI agents (MCP)

Apify MCP can expose this Actor to an AI agent. Add the MCP server URL below to your agent's MCP client configuration. The `tools` query narrows the server to this Actor's Store path:

```text
https://mcp.apify.com?tools=axiomworks/douban-movie-scraper
```

For an agent that supports a JSON MCP server configuration, a typical entry is:

```json
{"mcpServers":{"apify":{"url":"https://mcp.apify.com?tools=axiomworks/douban-movie-scraper"}}}
```

An agent can call the Actor with structured input. It should set `mode` and the matching target field when it needs a tag, search phrase, or IDs. It can use the returned `subjectId` as a stable catalog key and `sourceUrl` to see which Douban page or endpoint supplied a row. Ask for a small `maxItems` first when checking a query, then raise it only if more rows are useful.

Example prompts: “Find Douban suggestions for inception and return their IDs, titles, and years.” “Collect the first 25 Top250 movies and show ratings, genres, and directors.” “Look up Douban subject ID 1292052 and show its available cast and duration.” Those requests map directly to the Actor's modes and output fields. Agent generated summaries should treat missing values as unknown; they should not assume a missing field means a movie has no director or rating.

### Integrations and API

The Actor can run from Apify Console, an API client, or an automation that consumes its dataset. Use the Store path `axiomworks/douban-movie-scraper` in every programmatic call. Replace the token placeholder in these snippets with your own Apify access token in your local environment. Keep credentials out of shared code and logs.

Python with the Apify client:

```python
from apify_client import ApifyClient
import os
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("axiomworks/douban-movie-scraper").call(run_input={"mode": "top250", "maxItems": 5})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["id"], item["title"], item["rating"])
```

JavaScript with the Apify client:

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('axiomworks/douban-movie-scraper').call({ mode: 'search', searchQuery: 'inception', maxItems: 5 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => process.stdout.write(`${item.id} ${item.title}\n`));
```

A cURL request can start a synchronous run and return its dataset rows:

```bash
curl -X POST "https://api.apify.com/v2/acts/axiomworks~douban-movie-scraper/run-sync-get-dataset-items" \
  -H 'Authorization: Bearer $APIFY_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"mode":"hot","tag":"热门","maxItems":5}'
```

### FAQ

**Can I scrape the entire Top250 list?** Yes. Top250 mode paginates through the public list, and `maxItems` can be set to 250. The source may provide fewer rows if the list changes or a page cannot be read. The Actor stops when the list ends or the requested limit is reached.

**Why is `ratingCount` empty for a search or hot list?** The public suggestion and hot list responses used here do not provide that count. The Actor leaves it empty instead of inserting an estimate. Top250 cards show the number of people who rated a movie.

**Why are some director or cast arrays empty?** Those fields come from the public subject abstract. For list/search modes, disable `includeDetails` and they will be empty; subjects mode always reads abstracts. They can also be empty when Douban omits the field or blocks that abstract request after retries. Other fields from the list card can still be returned.

**Can I enter a URL instead of an ID?** Yes, in subjects mode. Use a standard HTTPS Douban movie subject URL containing the numeric ID. The Actor extracts the ID and reads the public subject abstract. It does not fetch the full subject page.

**What happens with an unknown search term?** A well formed query with no suggestions ends successfully with no dataset items and a status message. Try another title or spelling. A missing query in search mode is a validation error because there is nothing to search.

**Are results deduplicated?** Yes. The output helper uses the Douban subject ID as the stable row ID and skips repeats within a run. Across separate runs, use the `id` or `subjectId` field to join records yourself.

**Does the Actor translate movie names?** No. It retains the text Douban returns. Chinese and other language titles can appear together, and an original title is provided only when the source displays one.

### Is it legal to scrape Douban?

This Actor reads publicly accessible movie list and subject abstract data without logging into Douban. Access rules and site terms can change, and the right way to use data depends on your jurisdiction and purpose. Review Douban's current terms and any rights that apply to your project. Use a modest request rate, avoid redistributing material you do not have rights to, and respect requests to stop access. This Actor is not affiliated with Douban. It does not solve CAPTCHAs or access content behind a login.

### Feedback

Use the Actor's feedback option in Apify Console to report a broken extraction, missing public field, or input that returns an unexpected result. Include the mode, a sample input without secrets, the run link, and the subject ID or page URL involved. Those details help reproduce changes in Douban's response format. Suggestions for clearer field names are welcome.

# Actor input Schema

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

Choose "top250" (default: ranked movie list), "hot" (tag), "search" (title suggestions), or "subjects" (IDs/URLs). Example: "top250". Only inputs for the selected mode are used.

## `searchQuery` (type: `string`):

Movie title or phrase, e.g. "inception" or "千与千寻"; up to 200 characters. Used only with mode "search" and merged with searchQueries. Supply at least one query across these two fields. Default empty; unmatched terms return no rows.

## `searchQueries` (type: `array`):

Additional movie titles, e.g. \["千与千寻", "parasite"]. Used only with mode "search"; merged with searchQuery and deduplicated. Up to 50 combined queries, each at most 200 characters. Default \[]; maxItems is shared across all queries.

## `searchMatch` (type: `string`):

Choose any (default) to keep Douban suggestions and tag matches, or titleContains to retain only results whose returned title or subtitle contains the query. Case-insensitive, Unicode-normalized matching. Used only in search mode; filtering can return fewer than maxItems or zero rows.

## `subjectIds` (type: `array`):

Movie IDs or HTTPS subject URLs, e.g. \["1292052"]. Used only in subjects mode; merged with subjectUrls and subjectId. Supply at least one target. Default \[]; duplicate IDs are fetched once, unavailable targets return no rows, maxItems is shared.

## `subjectUrls` (type: `array`):

HTTPS movie subject URLs, e.g. \["https://movie.douban.com/subject/1292052/"]. In subjects mode, merged with subjectIds and subjectId. Query strings are accepted. Default \[]; maxItems is shared across targets. Unavailable targets return no rows.

## `subjectId` (type: `string`):

One movie ID or HTTPS subject URL, e.g. "1292052". In subjects mode, merged with subjectIds and subjectUrls. Default empty; use this for a single lookup. Unavailable targets return no rows.

## `tag` (type: `string`):

Movie tag, e.g. "热门" (default) or "豆瓣高分"; at most 100 characters. Used only with mode "hot". An unknown tag may return no rows; try a known Douban movie tag.

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

Total unique movie rows to save across all pages, queries, or IDs, e.g. 25. Whole number 1-10000, default 50. Stops at this shared limit or when available results end; top250 has at most 250 movies.

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

Set true (default), e.g. true, to fetch directors, actors, duration and other available abstract fields for list/search results. False reduces requests and leaves abstract-only fields empty. Subjects mode always reads abstracts. Missing or blocked details remain empty.

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

Proxy settings, e.g. {"useApifyProxy":true} (default: Apify datacenter proxy). Blocked requests retry on fresh sessions. If a target remains blocked, the run succeeds without rows for that target; retry later or change these proxy settings.

## Actor input object example

```json
{
  "mode": "top250",
  "searchQuery": "inception",
  "searchQueries": [],
  "searchMatch": "any",
  "subjectIds": [
    "1292052"
  ],
  "subjectUrls": [],
  "subjectId": "",
  "tag": "热门",
  "maxItems": 25,
  "includeDetails": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Dataset with one item per result, in the order found.

# 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": "top250",
    "searchQuery": "inception",
    "subjectIds": [
        "1292052"
    ],
    "tag": "热门",
    "maxItems": 25,
    "includeDetails": true,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axiomworks/douban-movie-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": "top250",
    "searchQuery": "inception",
    "subjectIds": ["1292052"],
    "tag": "热门",
    "maxItems": 25,
    "includeDetails": True,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("axiomworks/douban-movie-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": "top250",
  "searchQuery": "inception",
  "subjectIds": [
    "1292052"
  ],
  "tag": "热门",
  "maxItems": 25,
  "includeDetails": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call axiomworks/douban-movie-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,axiomworks/douban-movie-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/0OPmEM2C6lcQZtdsb/builds/JypMoocImZmWLJcXv/openapi.json
