# Douban Scraper API – 豆瓣 Movies, Books, Reviews & Comments (`deadc0dex/douban-scraper`) Actor

Douban scraper API, no login: Douban movie, TV, book & music search, ratings & details (IMDb id, star distribution), short comments (短评), full reviews (影评), cast, photos, Top 250 & hot charts, group topics. Arrays, filters, only-new delta, lean JSON for AI agents. $0.002/row, $0.01/detail.

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

## Pricing

from $2.00 / 1,000 subject / list rows

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

## Douban Scraper API – 豆瓣 Movies, Books, Reviews & Comments

Scrape **Douban (豆瓣)** without login: **Douban movie, TV, book and music search**, **ratings and full details** (5-star distribution, cast, IMDb id, ISBN), **short comments (短评)**, **full reviews (影评/书评)**, **cast & crew**, **photos**, **Douban Top 250 and hot charts**, **explore by tag**, **Douban groups (小组), group topics with replies and discussion search**, plus a one-call **research workflow** (title → details + comments + reviews + free insights row). One Actor, array inputs, flat JSON rows, free error rows with a fix, and a lean mode for AI agents.

- **No login, no cookies, no proxy needed** – uses Douban's public mobile JSON endpoints; if Douban rate-limits an IP, the Actor slows down and switches to Apify Proxy by itself.
- **Fast at volume** (measured on Apify, 256 MB): full Top 250 in one request (~4.6 s), 150 short comments in ~2.6 s, 10 full subject details in ~3.6 s, 100 full details in ~24 s.
- **14 operations in one Actor**, chosen automatically from your input (`operation: "auto"`); v2 adds `subject_research` and `topic_search`.
- **Batch everything**: many keywords, URLs, ids, charts or tags in one run.
- **Agent controls**: `fields`, `include`, `outputMode` (compact / lean / full), `minRating`/`maxRating`/`stars`/`dateFrom` filters, `maxItems`, `maxItemsPerInput`, `maxCostUsd`, free `dryRun` and `capabilities`, `deltaKey` + `onlyNew` monitoring.
- **Trust fields on every row** (v2): `isPartial`, `unavailableFields`, `collectionWarnings`; the summary row lists per input how many rows were requested, returned and available on Douban.
- **Pay per result**: $0.002 per list row or short comment, $0.01 per full subject detail, $0.006 per full review or group topic. Error, plan and summary rows are free.

Unofficial; not affiliated with or endorsed by Douban.

### Quick start

```json
{ "keywords": ["流浪地球", "三体"] }
```

returns Douban search rows (id, type, title, year, rating, rating count, one-line summary). Leave the input empty to get the real-time hottest movies chart.

| You give | Operation (auto) | You get |
|---|---|---|
| `keywords` | `search` | movie/TV (default), book, music subject rows |
| `urls` / `ids` of subjects | `subject_details` | full movie/TV/book/music page |
| review URLs | `review_details` | full review as Markdown |
| group URLs / ids | `group_topics` | topic list of the group |
| topic URLs | `group_topic_details` | topic text + images |
| `charts` | `charts` | Top 250 / hot lists in rank order |
| `tags` | `explore` | movies or TV by tag |

### Douban movie & book search

`{"operation":"search","keywords":["哈利波特"],"subjectType":"movie"}` – `subjectType`: `movie` (movies **and** TV series, default), `tv` (TV only), `book`, `music`, `all`. English titles in the dictionary are translated automatically (`The Wandering Earth` → `流浪地球`; `queryUsed` shows it). Up to 500 rows per keyword. If Douban asks for login on a search, the Actor falls back to Douban's public suggest endpoint; if that is empty you get a free `LOGIN_REQUIRED` row whose fix says to pass subject ids/URLs, or use `charts`/`explore`.

### Douban ratings & details

`{"operation":"subject_details","urls":["https://movie.douban.com/subject/26266893/","https://book.douban.com/subject/1084336/"]}`

Movies/TV: title, original title, aka, year, Douban rating, rating count, **rating distribution (1–5 stars, %)**, wish/watched counts, genres, countries, languages, directors, **writers**, actors, durations, release dates, episodes, intro, **IMDb id**, honors, comment and review counts, trailers. Books: authors, translators, publisher, pages, price, **ISBN**, binding, series, author intro, catalog. Music: singers, tracks, label, medium, barcode. Ids alone work too – movie/TV/book/music is detected without extra requests. Each detail is 3 small requests sent together (data + rating distribution + info table); with `fields` the unneeded ones are skipped.

Add `include: ["details"]` to `search`, `charts` or `explore` to get these full rows instead of list rows. Tip: `{"charts":["movie_top250"],"maxItemsPerInput":250,"include":["details"],"fields":["title","rating","imdbId","ratingDistribution"]}` maps the Top 250 to IMDb ids and star distributions with 2 tiny requests per film.

### Douban research in one call (subject_research, v2)

`{"operation":"subject_research","keywords":["流浪地球2"],"maxCommentsPerItem":50,"maxReviewsPerItem":10,"matchTerms":["特效"]}` – finds the title, then returns **1 full subject detail row, the hot short comments, the reviews, and one free `insights` row** per subject. Controls: `maxSubjects` (top hits per keyword, 1–10), `maxCommentsPerItem` (0–150), `maxReviewsPerItem` (0–40), `include: ["fullText"]` for review bodies (+ `"replies"` to embed review replies), `minRatingCount`, `matchTerms`, `maxCostUsd`. Ids/URLs work too (`"ids":["1292052"]`).

The insights row is computed from the rows returned in that run, with no LLM: author star mix, a **heuristic** sentiment split (author stars first, else a small Chinese/English word list), top Chinese 2–4 character terms, top IP provinces, per-term counts for `matchTerms`, and the most-voted positive and negative opinion. It also carries Douban's official rating and star distribution, so you can compare the sample with all ratings. `matchTerms` filters after fetching and before billing: rows that do not mention a term are not billed, but the fetch work is the same.

Measured on Apify (build 2.0.1, 256 MB): 1 detail + 20 comments + 5 reviews + insights in 5.9 s wall time (8 Douban requests), cost $0.06 (1 × $0.01 + 25 × $0.002).

### Douban short comments (短评)

`{"operation":"comments","ids":["26266893"],"maxItemsPerInput":50,"maxRating":2}` – star rating (1–5), text, useful votes, time, province, user name + id. Filters `minRating`, `maxRating`, `stars`, `dateFrom`, `textContains` run before billing. Douban shows guests the ~150 hottest comments per subject.

### Douban reviews (影评 / 书评)

`{"operation":"reviews","ids":["26266893"],"include":["fullText"],"maxItemsPerInput":10}` – title, abstract, stars, useful/useless votes, replies, reshares, time, user. With `include: ["fullText"]` each row carries the **full review body as Markdown** (+ images, read count, spoiler flag). Single reviews: `{"operation":"review_details","urls":["https://movie.douban.com/review/9943996/"]}`. Douban shows guests ~40 reviews per subject.

### Douban cast & photos

`{"operation":"celebrities","ids":["26266893"]}` – directors and actors with character, roles, Latin name, avatar, celebrity id.
`{"operation":"photos","ids":["26266893"],"maxItemsPerInput":20}` – stills and posters with image URL, size, caption, likes.

### Douban Top 250 & charts

`{"operation":"charts","charts":["movie_top250"],"maxItemsPerInput":250}`

Chart ids: `movie_top250`, `movie_showing` (now showing), `movie_soon`, `movie_real_time_hotest`, `movie_weekly_best`, `movie_hot_gaia`, `movie_latest`, `tv_real_time_hotest`, `tv_hot`, `tv_domestic`, `tv_american`, `tv_korean`, `tv_japanese`, `tv_animation`, `tv_variety_show`, `show_domestic`, `tv_chinese_best_weekly`, `tv_global_best_weekly`, `book_top250`, `book_fiction`, `book_nonfiction`, `book_bestseller`, `book_hot`, `book_latest`, `music_single`, `music_chinese`, `music_hot`, `movie_scifi`, `movie_comedy`, `movie_love`. Aliases like `top250`, `now_showing`, `kdrama` work, and so does any subject_collection id. With `deltaKey` every row gets `isNew`, `previousRank` and `rankChange`.

### Explore Douban by tag

`{"operation":"explore","tags":["科幻"],"subjectType":"movie","sortBy":"rating","minRating":8}` – movies or TV (`subjectType: "tv"`) by Douban tag (科幻, 喜剧, 美国, 韩剧, 豆瓣高分…; combine as `"科幻,美国"`), sorted by `recommend`, `hot`, `time` or `rating`.

### Douban groups (小组)

- Find groups: `{"operation":"group_search","keywords":["租房"]}`
- Topic list: `{"operation":"group_topics","ids":["beijingzufang"],"maxItemsPerInput":50,"sortBy":"latest"}` (default order = latest activity; also `hot`, `elite`)
- Topic text: `{"operation":"group_topic_details","urls":["https://www.douban.com/group/topic/502396963/"]}` – body as Markdown, images, reply count, likes, province.
- **Topic replies (v2)**: add `"include":["replies"]` (and `maxRepliesPerItem`, default 20, max 200) – the topic row gets a `replies` array (text, votes, time, province, user, quoted reply-to) and `repliesTotal`. Replies are embedded in the topic row and **cost nothing extra** (the topic stays $0.006). Same for full reviews: `review_details` or `reviews` + `fullText` with `include: ["replies"]` embeds the review's replies (nested replies flattened, `replyToId`/`replyToName` set).
- **Discussion search across all groups (v2)**: `{"operation":"topic_search","keywords":["小米SU7"],"sortBy":"latest"}` – topic id, full title, reply count, last activity time, group id + name ($0.002 per row, up to 500 per keyword). Douban's search is fuzzy: results can include topics that only match part of the keyword; use `textContains` to keep exact matches.

### For AI agents

- **One call, many inputs**: every primary field is an array. Nothing is required.
- **Cheap first look**: `{"operation":"capabilities"}` (free manifest: operations, chart ids, fields, prices, limits) and `"dryRun": true` (free cost/row estimate per input).
- **Token-lean output**: `"outputMode":"lean"` drops null/empty keys and the envelope (kept once in the summary row), cuts long texts to 300 chars, keeps the first 10 actors (ask `fields:["actors"]` for all); `"leanFormat":"table"` also returns one TSV table. `fields` keeps only what you need and skips requests for fields you did not ask for.
- **Never silent**: a failed input returns a free `type: "error"` row with `errorCode` (`MISSING_INPUT`, `INVALID_INPUT`, `INVALID_URL`, `NOT_FOUND`, `NO_RESULTS`, `LOGIN_REQUIRED`, `UNSUPPORTED_OPERATION`, `BUDGET_REACHED`, `PARTIAL`, `BLOCKED`, `UPSTREAM_ERROR`), `message` and `fix`. The run still succeeds; the last row is always `type: "summary"` (rows, billed events, cost, warnings, next steps) and the status message repeats the first fix.
- **Budget**: `maxItems` (default 100), `maxItemsPerInput` (default 20), `maxCostUsd`.
- **Trust & completeness (v2)**: every data row has `isPartial`, `unavailableFields` (e.g. `ratingDistribution` when that request failed) and `collectionWarnings`. Rule: `0` = Douban reported zero, `null` = Douban does not provide the value. A list that stops on a failed page returns the rows before it plus a free `PARTIAL` row. The summary has `requestedRows`, `returnedRows` and `perInput` (requested, returned, availableOnDouban, stopReason).
- **Computed fields (v2, documented in capabilities)**: subject details get `positivePct` / `negativePct` (share of 4–5 / 1–2 star ratings), `wishToDoneRatio`, `commentsPer1kRatings`, `reviewsPer1kRatings`; reviews get `helpfulRatio`; topics get `likesPerReply`. Null when an input is missing.
- **Titles instead of ids**: `comments`, `reviews`, `subject_details`, `celebrities` and `photos` accept `keywords` – each is resolved to its top search hit for free.

Copy-paste inputs:

```json
{"operation":"search","keywords":["流浪地球","三体"]}
{"operation":"search","keywords":["三体"],"subjectType":"book","outputMode":"lean"}
{"operation":"subject_details","ids":["26266893","1084336"],"fields":["title","rating","ratingCount","ratingDistribution","imdbId","isbn"]}
{"operation":"comments","ids":["26266893"],"maxItemsPerInput":100,"stars":["1","2"],"outputMode":"lean"}
{"operation":"reviews","keywords":["流浪地球"],"include":["fullText"],"maxItemsPerInput":5}
{"operation":"review_details","urls":["https://movie.douban.com/review/9943996/"]}
{"operation":"celebrities","ids":["26266893"]}
{"operation":"photos","ids":["26266893"],"maxItemsPerInput":20}
{"operation":"charts","charts":["movie_top250","book_top250"],"maxItemsPerInput":250,"maxItems":500,"deltaKey":"top250"}
{"operation":"explore","tags":["韩剧"],"subjectType":"tv","sortBy":"hot"}
{"operation":"group_search","keywords":["租房"]}
{"operation":"group_topics","ids":["beijingzufang"],"maxItemsPerInput":50,"onlyNew":true,"deltaKey":"bj-rent"}
{"operation":"group_topic_details","ids":["502396963"]}
{"operation":"subject_research","keywords":["流浪地球2"],"maxCommentsPerItem":50,"maxReviewsPerItem":10}
{"operation":"subject_research","ids":["1292052","2567698"],"include":["fullText","replies"],"maxReviewsPerItem":5,"outputMode":"lean"}
{"operation":"comments","ids":["26266893"],"maxItemsPerInput":100,"include":["insights"]}
{"operation":"group_topic_details","urls":["https://www.douban.com/group/topic/502224433/"],"include":["replies"],"maxRepliesPerItem":100}
{"operation":"topic_search","keywords":["小米SU7"],"sortBy":"latest","maxItemsPerInput":50}
{"operation":"capabilities"}
```

### Output example

Compact `comment` row:

```json
{"type":"comment","operation":"comments","input":"26266893","queryUsed":"26266893","id":"1656169114","url":"https://movie.douban.com/subject/26266893/comments","fetchedAt":"2026-10-13T06:00:00.000Z","rank":1,"commentId":"1656169114","subjectId":"26266893","rating":3,"text":"1.从特效和技术上讲，这应该是迄今为止此类中国电影的巅峰了…","voteCount":6511,"createdAt":"2019-02-05T16:29:48+08:00","region":null,"userName":"frozenmoon","userId":"1233038"}
```

Lean `subject` row (charts):

```json
{"type":"subject","id":"1292052","rank":1,"subjectType":"movie","title":"肖申克的救赎","year":1994,"rating":9.7,"ratingCount":3350087,"cardSubtitle":"1994 / 美国 / 剧情 犯罪 / 弗兰克·德拉邦特 / 蒂姆·罗宾斯 摩根·弗里曼","chart":"movie_top250"}
```

Times are ISO 8601 with Beijing offset (+08:00); lean rows use compact UTC (`2019-02-05T08:29Z`).

### Pricing (pay per event)

| Event | Price | What |
|---|---|---|
| `subject-row` | $0.002 | search / chart / explore row, cast member, photo, group, group-topic list row |
| `subject` | $0.01 | full subject detail (subject_details or include details) |
| `comment` | $0.002 | short comment or review list row |
| `review` | $0.006 | review with full Markdown body |
| `group-topic` | $0.006 | group topic with full text |
| Actor start | $0.00005 | per run |

Error, plan, capabilities, insights and summary rows are free; replies embedded with `include: ["replies"]` cost nothing extra. Rows dropped by filters or `onlyNew` are not billed.

### Limits

- Douban shows guests **~150 hot short comments** and **~40 reviews per subject**, and **~300 topics per group**; deeper pages need a Douban account and are not scraped.
- **Newest-first** comments/reviews require login on Douban; `sortBy: "latest"` returns the visible hot pool sorted by time (stated in the summary warnings).
- **Replies** are capped at 200 per review/topic row (`maxRepliesPerItem`). If a replies request fails (e.g. Douban asks for login on a locked thread), the row is still returned with `isPartial: true` and `unavailableFields: ["replies"]`.
- **Insights are heuristic**: the sample is the hot comments/reviews Douban shows guests (biased toward popular opinions); sentiment uses stars or a small word list, not a model.
- Some searches may get Douban's `need_login` answer; you then get suggest-endpoint rows or a free `LOGIN_REQUIRED` row with a fix.
- Privacy: only user display name, user id and province are returned for comment/review/topic authors.
- Cast and photos exist for movies and TV only (books/music return a free `UNSUPPORTED_OPERATION` row).

### FAQ

**Do I need a Douban account or cookies?** No. Nothing in the input asks for credentials.

**Can I monitor a chart or a group?** Yes: schedule the Actor with the same `deltaKey`; set `onlyNew: true` to receive (and pay for) only new rows. Chart rows show rank changes.

**What does 1,000 rows cost?** Search, chart or explore rows: $2. Short comments: $2. Full subject details: $10. Full reviews: $6. Example: Top 250 + full details for all 250 films = $2.50; 150 comments on one film = $0.30. Platform usage is included in these prices.

**How fast is it?** One request to Douban takes ~0.4–1.7 s from Apify's servers; the Actor keeps up to 8 in flight. Typical runs finish in 2–5 s; 100 full subject details in ~15–25 s.

**Is this the official Douban API?** No. It is an unofficial scraper of public pages. Unofficial; not affiliated with Douban.

# Changelog

This Actor's version history is a separate document: https://apify.com/deadc0dex/douban-scraper/changelog.md

# Actor input Schema

## `operation` (type: `string`):

auto (default): keywords->search, subject URLs/ids->subject_details, review URLs->review_details, topic URLs->group_topic_details, group URLs->group_topics, charts->charts, tags->explore. subject_research = title -> detail + hot comments + reviews + free insights. topic_search = discussions across all groups. topic_replies / review_replies = topic/review URL -> row with replies\[]. Also: comments 短评, reviews 影评, celebrities, photos, group_search, capabilities (free).

## `keywords` (type: `array`):

Search terms, one per item, for search (subjectType picks movie+TV, tv, book, music, all) or group_search. Chinese titles work best; English titles are auto-translated when known (The Wandering Earth -> 流浪地球). With comments/reviews/subject_details/celebrities/photos a keyword is resolved to its top hit (free).

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

movie./book./music.douban.com/subject/<id>/, m.douban.com/movie/subject/<id>/, …/review/<id>/, www.douban.com/group/<name>/, www.douban.com/group/topic/<id>/, m.douban.com/subject_collection/<id>. One per item; messy links are cleaned. Failed inputs return a free error row.

## `ids` (type: `array`):

Bare ids: subject ids (26266893; movie/TV/book/music detected automatically), review ids for review_details, topic ids for group_topic_details, group ids or names (beijingzufang) for group_topics.

## `charts` (type: `array`):

Chart ids for operation charts, in rank order: movie_top250, movie_showing, movie_real_time_hotest, movie_weekly_best, movie_hot_gaia, tv_hot, tv_domestic, tv_american, tv_korean, tv_japanese, tv_animation, tv_variety_show, book_top250, book_fiction, book_hot, music_single, music_hot … (capabilities lists all 30). Aliases: top250, now_showing, kdrama.

## `tags` (type: `array`):

Douban tags for operation explore (movies or TV by tag): 科幻, 喜剧, 爱情, 悬疑, 动画, 美国, 日本, 韩剧, 美剧, 豆瓣高分, 经典, 冷门佳片… One task per item; combine tags with commas in one item (科幻,美国).

## `subjectType` (type: `string`):

search: movie (default) = movies and TV series, tv = TV only, book, music, all = movie+book+music, group = group search. explore: movie or tv. Subject ops detect the type from the id/URL (hint only).

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

Maximum billable rows for the whole run, all inputs together. Default 100. Range 1-10000; larger values are capped.

## `maxItemsPerInput` (type: `integer`):

Cap per keyword, chart, tag, subject or group. Default 20 (= maxItems when only maxItems is set). Range 1-2000. Douban guest caps: ~150 hot comments and ~40 reviews per subject, ~300 topics per group, 500 search/explore rows.

## `include` (type: `array`):

details = search/charts/explore rows -> full subject detail rows (billed as subject $0.01 instead of row $0.002). fullText = reviews with full body as Markdown (review $0.006 instead of comment $0.002). replies = replies\[] (up to maxRepliesPerItem) inside full review / group topic rows, no extra charge. insights = one free analysis row per subject after comments/reviews (sentiment heuristic, top terms, regions).

## `fields` (type: `array`):

Projection: keep only these fields per data row (type always kept), e.g. \["title","rating","ratingCount"]. Also skips requests not needed (rating distribution / desc page). Empty = default set of outputMode. Full list: operation capabilities.

## `outputMode` (type: `string`):

compact (default) = stable flat rows, every key present (null when unknown). lean = for LLM agents: no null/empty keys, no envelope (it is in the summary row once), compact dates, short texts cut at maxTextChars (300). full = all fields of the row type.

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

comments/reviews: hot (default); latest = visible hot pool sorted newest first (Douban requires login for its newest feed). explore: recommend (default), hot, time, rating. group_topics: Douban default (latest activity), latest = newest posts, hot, elite. search/charts: rating = by rating.

## `minRating` (type: `number`):

Keep rows with rating >= this, applied before billing. Subjects (search, charts, explore, details): Douban score 0-10 (e.g. 8). Comments/reviews: stars 1-5 (e.g. 4). Rows without a rating are dropped when set.

## `maxRating` (type: `number`):

Keep rows with rating <= this. Same scales as minRating. Example: comments with maxRating 2 = 1-2 star complaints.

## `dateFrom` (type: `string`):

comments, reviews, group topics, photos: keep items created on/after this date. 2026-10-01 (Beijing time), ISO date-time, or relative 7d / 24h / 4w. Applied before billing.

## `maxCostUsd` (type: `number`):

Stop before the run's charges would exceed this amount (e.g. 0.05). The run ends SUCCEEDED with the rows so far plus a free BUDGET_REACHED error row. Works together with Apify's max cost per run.

## `dryRun` (type: `boolean`):

true = fetch and bill nothing: one free plan row per input (operation, queryUsed, estimated rows, event, cost, seconds) plus a summary. Check routing and cost first.

## `deltaKey` (type: `string`):

Name of a memory shared by runs (e.g. top250-weekly). Rows get isNew; chart rows also previousRank and rankChange vs the last run with the same key. Combine with onlyNew. Stored in your named key-value store douban-delta-<key>.

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

true = skip (not billed) rows already returned by earlier runs with the same deltaKey (deltaKey "default" if empty), e.g. new comments, reviews or group topics since the last scheduled run.

## `maxSubjects` (type: `integer`):

subject_research: how many top search hits per keyword to research. Default 1, range 1-10 (clamped).

## `maxCommentsPerItem` (type: `integer`):

subject_research: hot short comments per subject (billed as comment). Default 50, range 0-150 (Douban shows guests ~150). 0 = none.

## `maxReviewsPerItem` (type: `integer`):

subject_research: reviews per subject. Default 10, range 0-40 (Douban guest cap ~40). Billed as comment (list row) or review with include fullText. 0 = none.

## `maxRepliesPerItem` (type: `integer`):

With include replies: replies embedded per full review or group topic (nested review replies flattened, replyToId/replyToName set). Default 20, range 0-200. No extra charge.

## `matchTerms` (type: `array`):

Keep only comments/reviews/topics whose text mentions any term (case-insensitive) and count each term in the insights row. Filtering happens after fetching and before billing: dropped rows are not billed, but fetch work is the same.

## `minRatingCount` (type: `integer`):

Skip subjects with fewer Douban ratings (search, charts, explore, subject_research). Rows without a rating count are skipped too.

## `insights` (type: `boolean`):

subject_research: free insights row per subject is on unless false. Other comments/reviews runs: true adds it (same as include insights).

## `dateTo` (type: `string`):

Keep items created on/before this date. Same formats as dateFrom.

## `stars` (type: `array`):

Keep comments/reviews with exactly these star ratings, e.g. \["1","2"]. Applied before billing.

## `strictMatch` (type: `boolean`):

Douban group search is fuzzy: 小米SU7 also returns topics that only say 小米. true = keep only topics (group names) whose title contains the keyword, spaces and case ignored, or every part of it (小米 + SU7); mixed keywords are also searched by their Latin part. Filtered before billing. Default false.

## `textContains` (type: `array`):

Keep rows whose title/text/abstract contains at least one of these words (case-insensitive), checked before billing.

## `leanFormat` (type: `string`):

Only with outputMode lean. rows (default) = dataset rows. table = also one tab-separated table per row type in the summary row (leanTable, when < 20 KB) and key-value record LEAN_TABLE.

## `maxTextChars` (type: `integer`):

Cut text, abstract, intro and description to this many characters (ends with …, row gets truncated: true). Default 300 in lean mode, no cut otherwise. When set, also cuts full review/topic bodies (contentMarkdown).

## `expandQuery` (type: `boolean`):

English titles/names are mapped to Chinese with a curated dictionary (~950 entries: The Wandering Earth -> 流浪地球, Harry Potter -> 哈利波特, Jay Chou -> 周杰伦). queryUsed shows the term searched. false = search the keyword as typed.

## `dedupe` (type: `boolean`):

Drop rows already returned earlier in the run (same type + id), e.g. when two keywords find the same movie.

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

Optional. Default: no proxy (Douban's mobile API answers Apify IPs directly); if Douban rate-limits the IP, the Actor slows down and switches to Apify Proxy by itself ({"useApifyProxy":false} forbids that). Set {"useApifyProxy":true} to always use a proxy.

## `maxRequestRetries` (type: `integer`):

Retries with backoff on rate limits or server errors (0-6). Login walls are not retried.

## `requestDelayMs` (type: `integer`):

Minimum spacing between request starts (0-5000). Default 0 = up to 8 requests in flight; after a Douban rate limit the Actor slows itself to 3 in flight and 300 ms spacing. Raise (e.g. 500) only for very large runs.

## Actor input object example

```json
{
  "operation": "auto",
  "charts": [
    "movie_real_time_hotest"
  ],
  "outputMode": "compact",
  "dryRun": false,
  "onlyNew": false,
  "leanFormat": "rows",
  "expandQuery": true,
  "dedupe": true,
  "maxRequestRetries": 3,
  "requestDelayMs": 0
}
```

# Actor output Schema

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

All dataset rows. Filter by type; the last row is type summary.

## `subjects` (type: `string`):

Search / chart / explore rows.

## `comments` (type: `string`):

Short comment rows.

## `reviews` (type: `string`):

Review rows.

## `runSummary` (type: `string`):

RUN_SUMMARY record: rowsByType, billedEvents, costUsd, stopReason, warnings, notes, nextSteps.

## `leanTable` (type: `string`):

Only with outputMode lean + leanFormat table.

# 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 = {
    "charts": [
        "movie_real_time_hotest"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("deadc0dex/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 = { "charts": ["movie_real_time_hotest"] }

# Run the Actor and wait for it to finish
run = client.actor("deadc0dex/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 '{
  "charts": [
    "movie_real_time_hotest"
  ]
}' |
apify call deadc0dex/douban-scraper --silent --output-dataset

```

## MCP server setup

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