# Douban Scraper: Movie & Book Reviews, Ratings, Groups (`scrapewise/douban-scraper`) Actor

Scrape Douban (豆瓣) movie reviews, book reviews, ratings and group discussions, no login: long-form reviews, short comments with ratings, and full data for movies, TV shows and books from search, Top 250 lists or URLs. For Chinese-language corpora and sentiment analysis.

- **URL**: https://apify.com/scrapewise/douban-scraper.md
- **Developed by:** [Scrapewise Data](https://apify.com/scrapewise) (community)
- **Categories:** Social media, News, AI
- **Features:** Limited permissions
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.30 / 1,000 long-form reviews

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 Scraper: Reviews, Ratings, Movies, Books and Group Discussions

This Douban scraper (豆瓣) collects what people wrote on China's largest reviews community: long-form reviews with their full text, short comments with ratings, and group discussions with the whole post and its replies. It also returns complete records for movies, TV shows and books, from search, ready-made lists like Top 250, or any Douban URL.

Built for Chinese-language corpora, sentiment analysis, entertainment research and market tracking. Exports to JSON, CSV or Excel.

### What you can ask for

| You send | You get |
|---|---|
| `urls`: `https://movie.douban.com/subject/1291561/`, `https://book.douban.com/subject/1084336/` or a bare id | the full subject record; long-form reviews and short comments come when you set `maxReviewsPerSubject` and `maxCommentsPerSubject` (both off by default) |
| `searchQueries`: `matrix`, `三体` | subjects matching the term, in Chinese or English |
| `collections`: `movie_top250`, `movie_showing`, `tv_hot`, `book_top250` | the list, up to `maxItems`, `rank` included |
| `groups`: `https://www.douban.com/group/732764/` or `732764` | that group's topics, each with the full post text, plus replies if you ask |
| `groups`: a single discussion URL `.../group/topic/<id>/` | just that thread and its replies |
| `searchQueries` with `searchType: group` | group profiles: name, members, topic count |

Available lists, with how many rows each one holds (checked 22/09/2026):

| List | Rows | What it is |
|---|---|---|
| `movie_top250` | 250 | Douban's all-time Top 250 films |
| `book_top250` | 250 | the same for books |
| `tv_hot` | 204 | TV shows people are watching now |
| `book_fiction`, `book_nonfiction` | 100 each | current fiction and non-fiction charts |
| `show_hot` | 60 | variety shows |
| `tv_domestic` | 49 | Chinese TV shows |
| `movie_showing` | 20 | now in cinemas |
| `movie_weekly_best` | 10 | the weekly critics' board |

Ask for more than a list holds and you simply get the whole list.

### Limits you can set

| Field | What it does |
|---|---|
| `maxReviewsPerSubject` | Long-form reviews per subject, 0 to 500. Default 0 (off). Each review is charged as a long-form review. |
| `maxCommentsPerSubject` | Short comments with star ratings per subject, 0 to 500. Default 0 (off). |
| `maxTopicsPerGroup` | Topics per group, newest first. Default 20. |
| `fullTopicText` | On by default: each group topic comes with its complete post. |
| `maxRepliesPerTopic` | Replies per group topic, 0 to 2,000. Default 0 (off). |

### Schedule it daily: only new topics

Turn on `onlyNew` (alias `onlyNewPosts`), save the input as a Task and attach a daily Schedule:

```json
{ "groups": ["732764"], "maxTopicsPerGroup": 20, "onlyNew": true }
```

- The first run delivers up to your limits and marks everything it read as seen, so the back
  catalog never comes back as "new".
- Every run after that delivers, and charges, only the group topics, search results or list
  entries that were not delivered before, and stops at the first page with nothing new.
- The group row comes only on the first run or together with a new topic, so a quiet day costs
  nothing: the run ends green with the status "No new items since the last run".
- The memory lives in a Key-Value Store named `douban-scraper-only-new` in your own Apify account,
  one record per group, search or list. Delete it to start over. Subject and discussion URLs are
  always returned in full.

With a Slack, e-mail or Google Sheets integration on the Task, new discussions land where you read them.

### Output

One row per thing, with `type` telling them apart: `subject`, `review`, `comment`, `group`,
`topic`. Discussion rows carry `groupId`, `groupName` and `topicId`, so replies join back to
their thread and their group.

```json
{
  "type": "review",
  "id": "1005608",
  "subjectId": "1291561",
  "subjectType": "movie",
  "title": "千与千寻",
  "reviewTitle": "喜欢《千与千寻》那个无脸怪",
  "rating": 4,
  "text": "看完《千与千寻》，我一直没弄清楚那只无脸怪从哪里来。可要命的是，我对它念念不忘。……",
  "textLength": 1249,
  "createdAt": "2005-09-26 17:20:32",
  "voteCount": 11350,
  "commentsCount": 1341,
  "authorName": null,
  "url": "https://movie.douban.com/review/1005608/",
  "scrapedAt": "2026-10-21T20:18:26+00:00"
}
```

A `subject` row carries `title`, `originalTitle`, `year`, `ratingValue`, `ratingCount`,
`genres`, `countries`, `durations`, `directors`, `actors` for screen titles, and `author`,
`press`, `pubdate`, `pages` for books, plus `intro`, `commentCount`, `reviewCount` and
`coverUrl`.

#### Error codes

| errorCode | Meaning |
|---|---|
| `SUBJECT_NOT_FOUND` | The subject was removed, is private or never existed |
| `INVALID_SUBJECT` | The line is not a Douban subject URL or id |
| `NO_REVIEWS`, `NO_COMMENTS`, `NO_TOPICS` | That subject or group has nothing public of that kind |
| `GROUP_NOT_FOUND`, `TOPIC_NOT_FOUND` | The group or discussion is gone, private or never existed |
| `INVALID_GROUP`, `INVALID_TOPIC` | The line is not a Douban group or discussion URL or id |
| `NO_RESULTS` | The search term returned nothing public |
| `COLLECTION_NOT_FOUND` | No list with that name, or it came back empty |
| `BLOCKED` | Douban refused every retry for that request. Run again in a few minutes. |
| `ITEM_UNREADABLE` | One row came in a shape this Actor cannot read. Only that row is lost, and it is free. |
| `UNEXPECTED` | Something unforeseen broke on that request. The run keeps everything already delivered, and nothing extra is charged. |

### Pricing

Pay per event, no monthly fee and no charge per run:

| Event | Price |
|---|---|
| List item, short comment, reply or group profile | US$ 0.004 (US$ 4.00 per 1,000) |
| Full subject record | US$ 0.01 (US$ 10.00 per 1,000) |
| Long-form review or group topic | US$ 0.0027 (US$ 2.70 per 1,000) |

The example input (one movie with its full record, 5 long-form reviews and 20 short comments) costs **US$ 0.1035**.
One thousand reviews for a sentiment dataset cost **US$ 2.70**. The Top 250 list, as rows, costs **US$ 1.00**.
Twenty discussions from a group, with 50 replies each, costs **US$ 4.05**.

### How it works, and what it will not do

- **No login, no account, no cookies of yours.** Everything comes from Douban's public content.
- **Blocked requests are retried on their own.** If a request still fails, it comes back as a free `BLOCKED` row.
- **Only public content, and no user tracking.** Reviews and comments carry the text, the
  rating, the date and the display name. This Actor never returns user ids, profile links or
  avatars, and there is no mode to scrape a person's profile.

### FAQ

**Do failed rows cost anything?** No. Only rows with real content are charged, and duplicates
inside a run are removed before charging.

**Can I get the complete review text?** Yes, `fullReviewText` is on by default and opens each
review. Turn it off and you get the abstract Douban shows in the list, at the same price.

**Chinese or English?** Both work in search. The content comes as Douban stores it, which for
most subjects is Chinese.

**Which rows have the most text?** Long-form reviews are the densest single rows, around a
couple of thousand characters each. Group discussions bring the volume instead: the post itself
plus dozens of replies, all of them text people wrote.

**Why are there two prices for a subject?** A row from a search or a list is cheap because it
comes 20 or 100 at a time. Opening the subject for the full record costs one request each, so it
is charged as a full record. `includeSubjectDetails` controls that, and it is off by default.

### Changelog

- **2026-11-10:** lower price: US$ 2.70 per 1,000 long-form reviews and group topics on Free, less on paid plans.

- **2026-10-25:** lower price for long-form reviews and group topics: US$ 5.00 per 1,000 on Free, less on paid plans.

- **2026-10-04 (b):** the example input now asks for 5 long-form reviews and 20 short comments, so the first run shows the text, not only the subject record.

- **2026-10-04:** `onlyNew` for scheduled runs: only new group topics, search results and list entries are returned and charged. Same price.

# Actor input Schema

## `urls` (type: `array`):

Douban pages to read, one per line: movie, TV show or book pages (https://movie.douban.com/subject/1291561/, https://book.douban.com/subject/1084336/), group pages (https://www.douban.com/group/732764/) or a single discussion (https://www.douban.com/group/topic/123456789/). Bare numeric ids work for subjects. Each subject returns its full record (rating, votes, star breakdown, cast or authors, genres, summary), charged as 'Full subject record', plus the reviews and comments set below; each group returns its topics.

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

Keywords to search on Douban, one per line, in Chinese or English, for example 霸王别姬 or Harry Potter. Each term returns up to 'Max items' results from the catalogue chosen in 'Search in', charged as list items unless 'Open every search or list result' is on.

## `searchType` (type: `string`):

Which catalogue the search terms run against: Movies and TV shows (default), Books, or Groups. 'Groups' returns group profiles whose links you can then paste into the groups field to get their topics.

## `collections` (type: `array`):

Douban ready-made lists, one name per line. Sizes checked in September 2026: movie_top250 (250), book_top250 (250), tv_hot (204), book_fiction (100), book_nonfiction (100), show_hot (60), tv_domestic (49), movie_showing (20, now in cinemas), movie_weekly_best (10). Asking for more than a list holds returns the whole list. Each entry is charged as a list item.

## `groups` (type: `array`):

Douban groups or single discussions, one per line. Group links or ids (https://www.douban.com/group/732764/ or 732764) return that group's topics with the full post text; a discussion link (https://www.douban.com/group/topic/123456789/) returns just that thread. Groups hold most of the long Chinese-language discussion on Douban.

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

Maximum results for each search term and each ready-made list, from 1 to 10,000 (default 30). Subject links are always returned in full and are not limited by it. You pay per row, so this caps the cost of each search or list.

## `onlyNew` (type: `boolean`):

For scheduled runs. Remembers which group topics, search results and list entries were already delivered (in a named key-value store in your account, 'douban-scraper-only-new') and skips them on the next runs: skipped rows are not charged and do not count against the limits. The first run marks everything it read as seen; later runs stop at the first page with nothing new. The group row comes only on the first run or together with a new topic. Subject and discussion links are always returned.

## `maxReviewsPerSubject` (type: `integer`):

Long-form reviews to fetch for each subject, on top of the subject itself, from 0 to 500. Default 0 (off) because every review is charged as a 'Long-form review' on top of the subject record: one movie with 10 reviews is 1 record plus 10 review events. Set 5 or 10 when the reviews are what you need.

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

On (default): opens each review to get the complete text instead of the short abstract shown in the list. One extra request per review, same price. Turn off for faster runs when the abstract is enough.

## `maxCommentsPerSubject` (type: `integer`):

Short comments with star ratings to collect for each subject link, from 0 (default, off) to 500, for example 20. They come 20 per request and each is charged as a list item.

## `maxTopicsPerGroup` (type: `integer`):

How many topics to collect from each group, newest first, from 1 to 2,000 (default 20). Each topic is charged as a long-form item.

## `fullTopicText` (type: `boolean`):

On (default): opens each group topic to get the complete post instead of the abstract. One extra request per topic, same price.

## `maxRepliesPerTopic` (type: `integer`):

How many replies to collect from each group topic, from 0 (default, off) to 2,000, for example 50. They come 50 per request and each is charged as a list item.

## `includeSubjectDetails` (type: `boolean`):

Off (default): search and list rows come with what the listing shows (title, year, rating, cover, card subtitle), charged as list items. On: each result is opened for the full subject record, one extra request per subject, charged as 'Full subject record'.

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

Apify Proxy by default; blocked requests are retried on their own, with no extra charge. Change it only to use your own proxies.

## Actor input object example

```json
{
  "urls": [
    "https://movie.douban.com/subject/1291561/"
  ],
  "searchType": "movie",
  "maxItems": 30,
  "onlyNew": false,
  "maxReviewsPerSubject": 5,
  "fullReviewText": true,
  "maxCommentsPerSubject": 20,
  "maxTopicsPerGroup": 20,
  "fullTopicText": true,
  "maxRepliesPerTopic": 0,
  "includeSubjectDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `resultsCsv` (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 = {
    "urls": [
        "https://movie.douban.com/subject/1291561/"
    ],
    "maxItems": 30,
    "maxReviewsPerSubject": 5,
    "maxCommentsPerSubject": 20,
    "maxTopicsPerGroup": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapewise/douban-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 = {
    "urls": ["https://movie.douban.com/subject/1291561/"],
    "maxItems": 30,
    "maxReviewsPerSubject": 5,
    "maxCommentsPerSubject": 20,
    "maxTopicsPerGroup": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapewise/douban-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 '{
  "urls": [
    "https://movie.douban.com/subject/1291561/"
  ],
  "maxItems": 30,
  "maxReviewsPerSubject": 5,
  "maxCommentsPerSubject": 20,
  "maxTopicsPerGroup": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call scrapewise/douban-scraper --silent --output-dataset

```

## MCP server setup

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