Douban 豆瓣 Scraper: Movies, Books, Music, Charts & Ratings avatar

Douban 豆瓣 Scraper: Movies, Books, Music, Charts & Ratings

Pricing

from $4.35 / 1,000 douban title cards

Go to Apify Store
Douban 豆瓣 Scraper: Movies, Books, Music, Charts & Ratings

Douban 豆瓣 Scraper: Movies, Books, Music, Charts & Ratings

Douban (豆瓣电影, 豆瓣读书, 豆瓣音乐) movies, TV, books and music: ratings, cast, Top 250, charts and 29 genre rankings, short comments with stars, full reviews, search, rating and rank change tracking. No login, no browser. From $4.35 per 1,000 rows.

Pricing

from $4.35 / 1,000 douban title cards

Rating

0.0

(0)

Developer

Misha Ershov

Misha Ershov

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

25 days ago

Last modified

Security

Limited permissions

Share

Douban Scraper: Movies, Music, Books, Charts & Rating Tracker

Douban movies, TV series, books and music albums as clean rows: ratings, cast, tracklists, tags and Top 250 rank, the most popular short comments with stars, reviews with full text, keyword search, the Top 250 lists, Douban charts (now showing, weekly, hot, bestsellers, 29 genre rankings) and change tracking: rating and rank moves between two runs. One row per item. Plain HTTP requests through the Apify datacenter proxy: no login, no cookies, no extra software.

Modes

ModeWhat it doesExample input
subjects (default)one subject row per film, series, book or album you give, plus its comments and reviews on request{"subjectUrls": ["https://movie.douban.com/subject/1292052/", "https://book.douban.com/subject/2567698/"], "includeComments": true}
searchfilms and series (books with contentType: "book", albums with contentType: "music") for each keyword, one searchResult row each{"mode": "search", "keywords": ["三体"], "maxResults": 40}
top250the Douban Top 250 films (or books), one top250 row each{"mode": "top250", "maxResults": 100}
chartsDouban charts and genre rankings, one chartItem row per position{"mode": "charts", "charts": ["movie_showing", "movie_weekly_best"]}

contentType is movie (films and TV series; a series is given as a movie link), book or music. It applies to search and top250 and is ignored in subjects, where the link decides (movie., book. or music.douban.com). Music has no Top 250.

Charts

Mode charts reads the charts you pick in charts (one row per position, with rank, rating and rating count). Empty charts and genreCharts mean now showing + weekly best. 12 collections:

ValueChartPlace and place change
movie_showingMovies: now showing (正在热映)no
movie_hot_gaiaMovies: hot (热门)no
movie_real_time_hotestMovies: trending now (实时热门)yes
movie_weekly_bestMovies: weekly best (一周口碑榜)yes
movie_soonMovies: coming soon (即将上映)no
tv_hotTV: hot (热门剧集)no
tv_real_time_hotestTV: trending now (实时热门剧集)yes
tv_chinese_best_weeklyTV: Chinese weekly (华语口碑剧集榜)yes
tv_global_best_weeklyTV: global weekly (全球口碑剧集榜)yes
tv_variety_showTV: variety shows (综艺)no
book_bestsellerBooks: bestsellers (畅销图书)no
music_singleMusic: new singles (新碟/单曲)no

Sizes seen on 2026-10-13: now showing 54, hot movies 313, hot series 252, variety shows 63, book bestsellers 50, new singles 19; the weekly and trending charts hold 10 places each. The weekly and trending charts also return rankChange, the move in places Douban shows; the other charts have rankChange: null.

Genre rankings (genreCharts, films only) cover 29 genres: Documentary, Biography, Crime, History, Action, Erotic, Musical, Kids, Mystery, Drama, Disaster, Romance, Music, Adventure, Fantasy, Sci-Fi, Sport, Thriller, Horror, War, Short, Comedy, Animation, LGBT, Western, Family, Wuxia, Costume, Film Noir. genreScoreBand picks the slice of the genre to list. Douban splits every genre into 10% slices by how a film scores against the rest of the genre: 100:90 = films better than 90-100% of the genre (the best 10%), 90:80 = the next 10%, and so on down to 10:0. It is a percentile inside the genre, not a range of ratings. A slice holds about 1100 films, read in pages of 20, best rated first.

{"mode": "charts", "charts": ["movie_weekly_best", "tv_chinese_best_weekly"], "genreCharts": ["Drama", "Sci-Fi"], "genreScoreBand": "100:90"}

Track rating and rank changes

Set trackChanges: true and every subject, top250 and chartItem row is compared with the previous run of the same monitor. The snapshot lives in a named key-value store on your own Apify account, one record. The name is trackerName (default douban-tracker, lower-case letters, digits and dashes); use a different name for every monitor so snapshots do not mix.

New fields on tracked rows (all null when tracking is off): changeStatus, previousRating, ratingChange, previousRatingCount, ratingCountChange, commentCountChange (subjects), previousRank, rankDelta (previous place minus current place, so a positive number means the item moved up), firstSeenAt, lastSeenAt.

changeStatusMeaning
newnot in the previous snapshot
changedrating, rating count or (subjects) comment or review count differ
samenothing differs
up / downthe place in a chart or in the Top 250 moved up or down
droppedwas in the previous snapshot of a chart, is not in it now (a row with rank: null, previousRank and the old values)

onlyChanges: true (with trackChanges) leaves out rows with status same: they are not returned and not paid for, and are counted in RUN_SUMMARY.skippedUnchanged. maxResults counts the skipped rows too. To run it as a monitor, open Apify Console, Schedules, create a schedule (daily or weekly) and attach the Actor with the same input.

Example, weekly chart run with {"mode": "charts", "charts": ["movie_weekly_best"], "trackChanges": true, "onlyChanges": true} (the row is computed by the actor's diff code against a previous snapshot in which the film stood 3 places lower):

{
"type": "chartItem",
"chart": "movie_weekly_best",
"chartTitle": "Movies: weekly best (一周口碑榜)",
"rank": 2,
"rankChange": 9,
"id": "37068446",
"kind": "movie",
"title": "生化危机:爆发夜",
"rating": 7.3,
"ratingCount": 152283,
"subtitle": "2026 / 德国 法国 美国 / 科幻 惊悚 恐怖 / 扎克·克雷格 / 奥斯汀·艾布拉姆斯 扎克·切利",
"url": "https://movie.douban.com/subject/37068446/",
"coverUrl": "https://img2.doubanio.com/view/photo/m_ratio_poster/public/p2936442661.jpg",
"changeStatus": "up",
"previousRating": 7.3,
"ratingChange": 0.0,
"previousRatingCount": 152283,
"ratingCountChange": 0,
"previousRank": 5,
"rankDelta": 3,
"firstSeenAt": "2026-10-06T09:00:00Z",
"lastSeenAt": "2026-10-06T09:00:00Z"
}

Input

FieldDefaultMeaning
modesubjectssubjects, search, top250 or charts
subjectUrls[]mode subjects: movie., book. or music.douban.com/subject/<id>/, m.douban.com/movie/subject/<id> URLs or a bare numeric id (a bare id is tried as a film, then as a series). Entries without an id are skipped, logged and counted in invalidInputs
keywords[]mode search: Chinese or English words
maxResults501 to 1000, per keyword (search) or in total (top250, 250 exist); in charts per chart. With onlyChanges skipped unchanged rows count too
includeCommentsfalseadd the most popular short comments of every subject
maxCommentsPerSubject501 to 400. Douban caps films and series at 150 (books at 100) and albums at about 400
includeReviewsfalseadd the most popular reviews of every subject
maxReviewsPerSubject201 to 40
fullReviewTexttrueopen every review for its full text, useful and useless votes, read count and the original flag
fetchDetailsfalsemodes search and top250: open the card of every result and return a subject row instead of the short list row. Comments and reviews then work as in mode subjects
contentTypemoviemovie (Movies & TV), book or music (albums, keyword search only). Modes search and top250. Ignored in mode subjects
minRating00 to 10; list results rated lower (or unrated) are dropped. 0 = off
minRatingCount0list results with fewer ratings are dropped. 0 = off
yearFrom, yearTo0list results outside the years (or without a known year) are dropped. 0 = off; if yearFrom > yearTo they are swapped
genres[]keep list results with at least one of these genres (Chinese names, English labels in the form). Ignored for books and music
charts[]mode charts: the collections listed in "Charts". Empty with no genreCharts = movie_showing + movie_weekly_best
genreCharts[]mode charts: genre rankings of films, English genre names (see "Charts")
genreScoreBand100:90genre rankings: percentile slice inside the genre, 100:90 (best 10%) down to 10:0
sortBynonenone (source order), rating, ratingCount or year, high to low. Results are collected first (up to maxResults), then sorted; unknown values go last. Search sorts within one keyword
extraDetailsfalsesubject rows only: add rating distribution, want/done counts, genre ranks, IMDb id and awards. Slower (2 to 3 extra requests per card), the price is the same subject event
trackChangesfalsecompare subject, Top 250 and chart rows with the previous run (see "Track rating and rank changes")
onlyChangesfalsewith trackChanges: do not return (and do not pay for) rows that did not change
trackerNamedouban-trackername of the key-value store with the snapshot; one name per monitor
proxyConfigurationApify datacenterdatacenter proxy is enough

Filters (minRating, minRatingCount, yearFrom, yearTo, genres) run before anything is returned or opened, so dropped results are neither charged nor fetched as cards; RUN_SUMMARY.filtered counts them by reason. Filters that drop everything are not an error. Invalid values (a rating outside 0 to 10, negative numbers, text) switch that filter off.

Examples: books by keyword {"mode": "search", "keywords": ["三体"], "contentType": "book"}; the best-rated crime films since 2000 {"mode": "top250", "genres": ["犯罪"], "yearFrom": 2000, "sortBy": "rating"}; full cards with extras {"subjectUrls": ["1292052"], "extraDetails": true}.

Mode subjects needs subjectUrls, mode search needs keywords. Otherwise the run ends with exit code 1 and a clear status message; nothing is charged. In modes search and top250 comments and reviews are returned only with fetchDetails. Mode charts needs charts or genreCharts (or neither, for the default pair).

Honest limits

Douban shows visitors who are not logged in:

  • short comments: at most 150 of a film or series (100 of a book), up to about 400 of an album; the most popular ones only;
  • reviews: at most about 40 per title;
  • newest-first order is not available without login. For albums it is closed outright (HTTP 403), so music comments are popular-first only;
  • the desktop pages (movie.douban.com) are behind a sec.douban.com check, so full comment feeds beyond 150 are not reachable without a login or a browser. This actor uses neither, so these are the ceilings. The total counts (commentCount, reviewCount) are still returned on the subject row;
  • genre rankings exist for films only;
  • music has no Top 250 and genres filters do not apply to it.

Change tracking limits: dropped rows are returned only when the chart was read to its end (its total). A run that stops on maxResults, on the budget or on an error emits none, because the missing items may simply not have been read. RUN_SUMMARY.skippedUnchanged appears only with trackChanges. Mode search without fetchDetails is not tracked.

Output

Rows from extraDetails add to the subject row: ratingDistribution (percent per star, keys "5" to "1"), wishCount, doneCount, typeRanks ([{"type": "犯罪片", "betterThanPercent": 99}]), imdbId and awards (ceremony, year, category, won, url). Without extraDetails, and for books (imdbId, awards), they are null. searchResult and top250 rows also carry year and genres (genres are [] for books); top250 rows carry kind. A failed extra request leaves its fields null and is counted in RUN_SUMMARY.extraFailed; the row is still returned.

Every row has a type: subject, comment, review, searchResult, top250 or chartItem. Fields the source does not have are null, never 0. Times are ISO 8601 UTC (Douban shows Beijing time, UTC+8). Long fields below are shortened, the values shown are real.

Subject row, film (scrapedAt, the UTC time of the scrape, and the tracking fields are left out here; a series has kind: "tv" and episodes):

{
"type": "subject",
"id": "1292052",
"kind": "movie",
"title": "肖申克的救赎",
"originalTitle": "The Shawshank Redemption",
"year": 1994,
"rating": 9.7,
"ratingCount": 3350090,
"genres": [
"剧情",
"犯罪"
],
"countries": [
"美国"
],
"languages": [
"英语"
],
"durations": [
"142分钟"
],
"directors": [
"弗兰克·德拉邦特"
],
"actors": [
"蒂姆·罗宾斯",
"摩根·弗里曼",
"鲍勃·冈顿"
],
"releaseDates": [
"2026-08-28(中国大陆)"
],
"intro": "一场谋杀案使银行家安迪(蒂姆·罗宾斯 Tim Robbins 饰)蒙冤入狱,谋杀妻子及其情人的指控将囚禁他终生。在肖申克…",
"commentCount": 668186,
"reviewCount": 14990,
"aka": [
"月黑高飞(港)",
"刺激1995(台)",
"地狱诺言",
"铁窗岁月",
"消香克的救赎"
],
"tags": [
"犯罪",
"越狱",
"励志",
"信念"
],
"top250Rank": 1,
"episodes": null,
"authors": null,
"translators": null,
"publisher": null,
"publishDate": null,
"pages": null,
"price": null,
"subtitle": null,
"coverUrl": "https://img3.doubanio.com/view/photo/m_ratio_poster/public/p2934829882.webp",
"url": "https://movie.douban.com/subject/1292052/"
}

Subject row, book (film-only fields stay null, book-only fields are null on films):

{
"type": "subject",
"id": "2567698",
"kind": "book",
"title": "三体",
"originalTitle": null,
"year": null,
"rating": 8.9,
"ratingCount": 518667,
"genres": null,
"countries": null,
"languages": null,
"durations": null,
"directors": null,
"actors": null,
"releaseDates": null,
"intro": "文化大革命如火如荼进行的同时。军方探寻外星文明的绝秘计划“红岸工程”取得了突破性进展。但在按下发射键的那一刻,历经劫难的…",
"commentCount": 125005,
"reviewCount": 4800,
"aka": null,
"tags": [],
"top250Rank": null,
"episodes": null,
"authors": [
"刘慈欣"
],
"translators": [],
"publisher": "重庆出版社",
"publishDate": "2008-1",
"pages": 302,
"price": "23.00",
"subtitle": "“地球往事”三部曲之一",
"coverUrl": "https://img3.doubanio.com/view/subject/l/public/s2768378.jpg",
"url": "https://book.douban.com/subject/2567698/"
}

Music album (kind: "music"; the tracking fields, all null here, are left out; lists are cut to 3 elements, as in every example):

{
"type": "subject",
"id": "26812952",
"kind": "music",
"title": "周杰伦的床边故事",
"year": 2016,
"rating": 8.1,
"ratingCount": 31074,
"genres": [
"流行"
],
"intro": "夜深了\n猫头鹰出没\n数完第一千零一个尖叫声\n开始听周杰伦 的床边故事\nJay Chou’s Bedtime Stories\n今年最令人激动的乐坛震撼弹\n周杰伦2…",
"commentCount": 9692,
"reviewCount": 139,
"tags": [],
"publisher": "杰威尔音乐",
"publishDate": "2016-06-24",
"coverUrl": "https://img9.doubanio.com/view/subject/m/public/s28836865.jpg",
"url": "https://music.douban.com/subject/26812952/",
"artists": [
"周杰伦"
],
"media": "CD",
"tracks": [
"床边故事",
"说走就走",
"一点点"
]
}

Chart row from a collection (rankChange is the move in places Douban shows on the weekly and trending charts; the tracking fields and scrapedAt are left out):

{
"type": "chartItem",
"chart": "movie_weekly_best",
"chartTitle": "Movies: weekly best (一周口碑榜)",
"rank": 1,
"rankChange": 0,
"id": "35322132",
"kind": "movie",
"title": "罗斯",
"rating": 8.5,
"ratingCount": 21268,
"subtitle": "2026 / 奥地利 德国 / 剧情 / 马库斯·施莱泽 / 桑德拉·惠勒 卡洛·布劳恩",
"year": null,
"genres": null,
"releaseDate": null,
"url": "https://movie.douban.com/subject/35322132/",
"coverUrl": "https://img3.doubanio.com/view/photo/m_ratio_poster/public/p2935294362.jpg"
}

Chart row from a genre ranking:

{
"type": "chartItem",
"chart": "genre:Drama:100:90",
"chartTitle": "Drama",
"rank": 1,
"rankChange": null,
"id": "1292052",
"kind": "movie",
"title": "肖申克的救赎",
"rating": 9.7,
"ratingCount": 3350220,
"subtitle": "美国 / 犯罪 / 剧情",
"year": 2026,
"genres": [
"犯罪",
"剧情"
],
"releaseDate": "2026-08-28",
"url": "https://movie.douban.com/subject/1292052/",
"coverUrl": "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2934829882.jpg"
}

A row with tracking is shown in "Track rating and rank changes".

Comment row:

{
"type": "comment",
"subjectId": "1292052",
"subjectKind": "movie",
"commentId": "28737569",
"text": "人的生命不过是从一个洞穴通往另一个世界..然后在那个世界的雨中继续颤抖.i hope",
"stars": 4,
"createdAt": "2008-01-13T17:53:08Z",
"votes": 5238,
"ipLocation": null,
"userId": "1781395",
"userName": "文泽尔",
"userUid": "wenzel",
"userLocation": "苏黎世"
}

Review row (with fullReviewText; without it text, uselessCount, readCount and isOriginal are null):

{
"type": "review",
"subjectId": "1292052",
"subjectKind": "movie",
"reviewId": "1000369",
"title": "十年·肖申克的救赎",
"abstract": "距离斯蒂芬·金(Stephen King)和德拉邦特(Frank Darabont)们缔造这部伟大的作品已经有十年了。我…",
"text": "距离斯蒂芬·金(Stephen King)和德拉邦特(Frank Darabont)们缔造这部伟大的作品已经有十年了。我…",
"stars": 5,
"createdAt": "2005-05-12T12:44:13Z",
"usefulCount": 18956,
"uselessCount": 735,
"commentsCount": 1082,
"readCount": 1428817,
"isOriginal": true,
"url": "https://movie.douban.com/review/1000369/",
"userId": "1000152",
"userName": "大头绿豆"
}

Search result row:

{
"type": "searchResult",
"keyword": "三体",
"position": 1,
"id": "26647087",
"kind": "tv",
"title": "三体",
"year": 2023,
"rating": 8.7,
"ratingCount": 540074,
"subtitle": "中国大陆 / 剧情 科幻 / 杨磊 / 张鲁一 于和伟",
"coverUrl": "https://qnmob3-sign.doubanio.com/view/photo/large/public/p2886492021.jpg",
"url": "https://movie.douban.com/subject/26647087/",
"genres": [
"剧情",
"科幻"
]
}

Top 250 row:

{
"type": "top250",
"rank": 1,
"id": "1292052",
"title": "肖申克的救赎",
"rating": 9.7,
"ratingCount": 3350090,
"subtitle": "1994 / 美国 / 剧情 犯罪 / 弗兰克·德拉邦特 / 蒂姆·罗宾斯 摩根·弗里曼",
"quote": "希望让人自由。",
"url": "https://movie.douban.com/subject/1292052/",
"year": 1994,
"genres": [
"剧情",
"犯罪"
],
"kind": "movie"
}

How the run works

Requests go to Douban's mobile JSON API and carry the Referer it requires. A request that fails (HTTP 403, 5xx or a transport error) is retried up to 3 times, each on a new proxy session. A subject or list that still fails is logged, counted in RUN_SUMMARY.failed and skipped; the rest goes on. A page after the first one that comes back empty, repeats rows already seen or answers HTTP 403 is the end of what Douban shows to visitors: the source stops with

stoppedBy: "sourceLimit"
, which is not a failure. An unknown id is counted in notFound. Rows are deduplicated by id within a run. Requests are paced (one every 1 to 2 seconds). RUN_SUMMARY holds bySource (pages, items and stoppedBy per source), pushed by type, charged per event, failed, notFound, invalidInputs, skippedUnchanged (only with trackChanges) and stoppedBy (maxResults, sourceLimit, budget or end).

FAQ

Do I need a Douban account? No. No login or cookies are used.

Why not more comments or reviews? See "Honest limits": that is all Douban shows to anonymous visitors.

Why only 150 comments per movie? Douban's mobile API gives visitors who are not logged in the 150 most popular short comments of a film. The desktop pages with longer feeds are behind a sec.douban.com check, so more comments are not reachable without a login or a browser. Albums go further, up to about 400.

Can I get the newest comments instead of the most popular? No. Douban answers the newest-first order with an error for visitors who are not logged in, so only the popular order is used.

How do I monitor a weekly chart? Run mode charts with charts: ["movie_weekly_best"], trackChanges: true and onlyChanges: true, then put it on a weekly schedule (Console, Schedules). Every run returns only the films that are new, moved or changed rating, plus dropped rows for films that left the chart.

Can I get music comments sorted by newest? No. Douban closes the newest-first order for albums to visitors who are not logged in, so only the popular order is used.

Are TV series supported? Yes. A series is a subject row with kind: "tv" and episodes, and its comments and reviews work like a film's.

Pricing events: one event per row: subject, comment, review (abstract only), review-full (full text, instead of review), list-row (search and Top 250 rows).

Missing something? Open an issue. We add fields on request.

Development

cd partner_actors/dima/douban-scraper
python3 -m pytest -q