Goodreads Review Scraper
Pricing
from $1.21 / 1,000 results
Goodreads Review Scraper
Goodreads Review Scraper collects public reviews from Goodreads book URLs or IDs: star rating, review text, reviewer profile, likes, comments, shelves and timestamps. Filter by language and sort order. No login or cookies. Export as JSON, CSV or Excel, or use the API.
Pricing
from $1.21 / 1,000 results
Rating
0.0
(0)
Developer
Fast Data API
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
9 days ago
Last modified
Categories
Share
Goodreads Review Scraper — Ratings, Text and Reviewer Profiles
Goodreads Review Scraper pulls every public review from a Goodreads book page — star rating, full review text, reviewer profile, likes, comments, shelving, and both epoch and ISO-8601 timestamps. Reviews can be filtered by language and by edition scope before they reach your dataset. Every response is structured JSON, ready to pass to an LLM, load into a spreadsheet, or index for search. No Goodreads account or login is needed — only what any visitor already sees is read. Start with one book URL, add the rest of your list.

What data can I extract with Goodreads Review Scraper?
Using this Goodreads reviews API, you will be able to extract the following Goodreads review data:
| 🆔 Review ID | ⭐ Star rating | 💬 Review text | 🚩 Spoiler flag |
|---|---|---|---|
| 👤 Reviewer profile (nested) | 👍 Like count | 💬 Comment count | 📅 Created date (epoch + ISO) |
| 📅 Updated date (epoch + ISO) | 📅 Last revision date (epoch + ISO) | 📚 Shelving & tags (if attached) | 🎯 Recommended for (if provided) |
| 📦 Pre-release source (rare, if applicable) | 🔗 Book URL | 🏷️ Record type label | 👁️ Viewer-liked flag (always null, anonymous) |
Pair star ratings with like and comment counts, and it works equally well as a Goodreads ratings scraper focused only on the numbers rather than full review text.
How to use Goodreads Review Scraper
Anyone studying how readers actually respond to a book — a publisher, an AI/RAG engineer, or a market researcher — gets one typed JSON row per review, filtered by language and edition scope before it ever reaches the dataset, from a single run.
Copy to your AI assistant:
Goodreads Review Scraper (Apify Actor ID: fastdataapi/goodreads-review-scraper, https://apify.com/fastdataapi/goodreads-review-scraper) is an Apify Actor that returns public Goodreads book reviews as structured JSON: star rating, full review text, reviewer name and profile link, like count, comment count, and both epoch and ISO-8601 timestamps. Use it whenever someone needs Goodreads review data without cookies, a login, or a browser - tracking how a title's reviews trend after launch, feeding review text into a sentiment model as grounded context, or building a versioned review dataset for research. Inputs: bookUrls (array, required, one or more Goodreads book URLs or bare numeric book IDs), maxItems (integer, default 20, minimum 1, maximum 100000, applies per book on paid plans; free-plan accounts are capped at 20 reviews per run in total across every book, and 200 per month), sortBy (string, one of "popular"|"newest"|"oldest", default "popular"), languageCode (string, "all" or one of 19 language codes, default "all"), Review_Edition (string, "ALL"|"only_this_book", default "ALL"), proxyConfiguration (object, proxy editor, used automatically if a request is blocked). A book that can't be resolved is skipped with a warning and the run continues with the rest of the list; the run only fails if zero reviews were collected across every requested book.
Goodreads Review Scraper MCP Server: use these Actors from ChatGPT, Claude or Cursor
Add the Apify MCP server and your AI assistant can find and call this Actor on its own — no glue code, no scraping logic in your prompts.
$claude mcp add --transport http apify "https://mcp.apify.com?tools=fastdataapi/goodreads-review-scraper"
Step by step
- Create a free Apify account.
- Open Goodreads Review Scraper in the Apify Store.
- Enter the Goodreads book URL or bare numeric book ID.
- Click Start.
- Download or stream your results in JSON, CSV or Excel.
How to scale Goodreads Review Scraper to bulk
Pass an array of book URLs or IDs in bookUrls — up to 4 books are processed concurrently within a run. On paid plans, maxItems applies separately to each book rather than to the run as a whole, so 50 in maxItems with 3 books can return up to 150 rows. Free-plan accounts are capped at 20 reviews per run in total across every book in the list, and 200 per month, no matter how high maxItems is set. A book that can't be reached after its own retries is skipped with a warning rather than aborting the run; the run only fails if zero reviews were collected across every requested book.
Used this way, it works as a bulk Goodreads review scraper: queue as many book URLs as you need and let per-book retries and concurrency handle the rest without babysitting individual runs.
✨ Features
Goodreads Review Scraper fetches clean, structured reviews from a Goodreads book page ⚡ with built-in language and edition-scope filtering. It's ideal for review-mining, sentiment analysis, publisher/author reception tracking, and building a versioned research corpus.
As a Goodreads book review extractor built for structured output rather than raw HTML, every row also carries the kind of reviewer detail a Goodreads reviewer data scraper needs — name, profile link, and engagement counts — nested under a single creator field.
It extracts, per review:
- Review text and star rating – the reviewer's own words and their 1–5 rating
- Reviewer profile – a nested
creatorobject with the reviewer's name, profile link, and engagement counts - Engagement counts – like count and comment count per review
- Shelving and tags – the shelf a reviewer filed the book under, plus any attached tags, when Goodreads has that data
- Three timestamp fields – created, updated, and last revision, each as both raw epoch milliseconds and an ISO-8601 string
⚡ Reviews are pushed to the dataset the moment each one is parsed, not buffered until a book or the run finishes, so results are visible in the Apify Console while a run is still going.
Use cases 💡
- Publisher or author — track rating and like-count trends before and after a launch or cover redesign.
- AI/RAG engineer — feed review text and rating into a sentiment model as grounded, structured context.
- Market researcher — compare reader reception across several competing titles in one run.
- Academic/data team — build a versioned, reproducible review dataset keyed by review ID.
- Reader-insight analyst — run it as a Goodreads review scraper by language to study reception in one specific market.
Building an AI agent? Connect Goodreads Review Scraper over MCP and let it call the actor on its own.
Why choose this actor?
- Every review streamed as it's found. A recorded run requesting 3 reviews for one book returned 3 review rows, each with every documented field populated — pushed to the dataset as each one was parsed, not buffered until the book finished.
- 19 documented fields per review, nested reviewer and shelving included. Every row carries its own rating, text, and spoiler flag, plus a nested reviewer profile and — when Goodreads has the data — a nested shelf and tag object, with three timestamp fields each given in both epoch and ISO-8601 form.
- 3 real query controls, applied server-side.
sortBy,languageCode(20 languages or all), andReview_Edition(whole work vs. one edition) are all applied by Goodreads before a row reaches your dataset — not filtered afterward.
⬇️ Input

The Actor accepts one or more Goodreads book URLs or bare numeric book IDs in bookUrls — the only required field.
| Parameter | Required | Type | Description | Example value |
|---|---|---|---|---|
bookUrls | Yes | array | One or more Goodreads book links. A bare numeric ID (e.g. 26032825) is accepted and rewritten to a full book URL automatically. | ["https://www.goodreads.com/book/show/26032825"] |
maxItems | No | integer (default 20, minimum 1, maximum 100000) | How many reviews to collect for each book. Applies per book on paid plans; free-plan accounts are capped at 20 reviews per run in total (all books together) and 200 per month, regardless of this value. | 50 |
sortBy | No | string enum (default "popular") | Review order: popular (most helpful first), newest, or oldest. | "newest" |
languageCode | No | string enum (default "all") | all for no filter, or one of 19 language codes. | "es" |
Review_Edition | No | string enum (default "ALL") | ALL for reviews across the whole work, or only_this_book for just the edition the URL points to. | "only_this_book" |
proxyConfiguration | No | object (proxy editor) | Apify Proxy configuration. The Actor starts with a direct connection and only switches to a proxy if a request is blocked. | {"useApifyProxy": true} |
Example input
{"bookUrls": ["https://www.goodreads.com/book/show/26032825","18143977"],"maxItems": 50,"sortBy": "newest","languageCode": "en","Review_Edition": "ALL","proxyConfiguration": { "useApifyProxy": true }}
Free plan limits
Free Apify accounts get up to 20 reviews per run (every book in bookUrls combined, not 20 per book) and 200 reviews per month in total, no matter how high maxItems is set. The run stops cleanly once either cap is hit, so you keep whatever was already collected and saved. Paid Apify plans have no limit — maxItems then applies per book exactly as described above.
⬆️ Output

Every review is one typed, normalized JSON item with the same field set on every run, streamed to the dataset as each review is found. Results export as JSON, CSV, Excel, XML, or RSS from the Apify Console or API.
That makes it a straightforward Goodreads review data export pipeline — pick Goodreads reviews to CSV for a spreadsheet-ready file, or keep JSON for direct ingestion into code.
Example output
{"bookUrl": "https://www.goodreads.com/book/show/26032825","__typename": "Review","id": "kca://review:goodreads/amzn1.gr.review:goodreads.v1.sdrC-ZRjzY6QMCANZHeBhQ","creator": {"id": 5477612,"name": "Emily May","webUrl": "https://www.goodreads.com/user/show/5477612-emily-may","imageUrlSquare": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/users/1583425448i/5477612._UY200_CR0,0,200,200_.jpg","isAuthor": false,"followersCount": 323630,"textReviewsCount": 2305,"viewerRelationshipStatus": null,"contributor": null},"recommendFor": null,"updatedAt": 1452890265000,"updatedAtIso": "2016-01-15T20:37:45Z","createdAt": 1452890265000,"createdAtIso": "2016-01-15T20:37:45Z","spoilerStatus": false,"lastRevisionAt": 1452890265000,"lastRevisionAtIso": "2016-01-15T20:37:45Z","text": "A gorgeous, cruel fairy tale that earns every bit of its darkness.","rating": 5,"preReleaseBookSource": null,"shelving": {"shelf": {"name": "read","displayName": "Read","sortOrder": 2,"webUrl": "https://www.goodreads.com/review/list/5477612?shelf=read"},"taggings": [{ "tag": { "name": "fantasy", "webUrl": "https://www.goodreads.com/review/list/5477612?shelf=fantasy" } }]},"likeCount": 3120,"viewerHasLiked": null,"commentCount": 84}
viewerHasLiked and creator.viewerRelationshipStatus are carried through on every row but are always null for this Actor's logged-out requests — real fields, just not populated outside a signed-in session. Fields Goodreads does not return for a given review — a missing creator, an unset lastRevisionAt, an empty shelving — come back as null, never a guessed value.
How does it work?
The Actor reads each book's own public reviews page — the same one any visitor's browser loads — and resolves what it needs fresh on every run rather than relying on a value that can go stale. Requests go out through rotating proxies: each one starts on a direct connection and only escalates to a proxy, and eventually a residential one, if Goodreads blocks it, locking onto that tier for the rest of that book once escalation is needed so a block mid-page never causes a duplicate row. It returns only publicly visible reviews — no login, account, or cookie is used — and the output schema stays stable even as Goodreads changes its own page.
How do you integrate Goodreads Review Scraper into your stack?
Goodreads Review Scraper works with what you already use: a REST API callable from any language, MCP for AI agents, and no-code automation tools.
No-code tools (n8n, Make, LangChain)
In n8n, use the Apify node's "Run an Actor" action, or the HTTP Request node pointed at the Actor's run-sync endpoint with your Apify token. In Make, use the Apify app's "Run an Actor" module followed by "Get Dataset Items" to pull the rows into your scenario. In LangChain, install langchain-apify and call ApifyActorsTool() once the Actor is in your account to let an agent run it directly.
MCP integration for AI agents
Add the Apify MCP server and your agent can search for, add, and call this Actor on its own:
$claude mcp add --transport http apify "https://mcp.apify.com?tools=fastdataapi/goodreads-review-scraper"
This registers the Apify MCP server as a tool your agent can call directly. Compatible with Claude Code, Cursor, and Windsurf.
Is it legal to scrape Goodreads reviews?
Scraping publicly accessible web data is generally lawful: courts in the U.S. have found that accessing data a website makes available without a login is not a CFAA violation (hiQ Labs, Inc. v. LinkedIn Corp., 9th Cir., 2019). Goodreads Review Scraper returns only what any visitor can see on a book's reviews page while logged out — it does not access private accounts or gated content. Because each review includes reviewer personal data (a name, a profile URL, a follower count), processing it at scale may still bring it within GDPR or CCPA obligations for storage, retention, and data-subject rights. Consult legal counsel if your use case involves bulk storage of personal data.
Frequently asked questions
What fields does Goodreads Review Scraper return?
The top fields are star rating, review text, reviewer profile, like count, and comment count — see the data fields section for the full list.
Does Goodreads Review Scraper require a Goodreads account or login?
No. Only public review data is extracted — no credentials are needed, and the Actor never opens a session.
What happens if a book is private or doesn't exist?
A book that can't be resolved is skipped for that run with a clear warning, and the run continues with the rest of the requested books; the run only fails if zero reviews were collected across every book.
Can I scrape reviews for multiple books at once?
Yes — pass an array of book URLs or IDs in bookUrls; up to 4 books are processed concurrently, and on paid plans maxItems applies separately to each one. Free-plan accounts are capped at 20 reviews per run in total across every book, and 200 per month — see Free plan limits.
Does Goodreads Review Scraper work with Claude, ChatGPT, and other AI agent tools?
Yes — it's reachable through the Apify MCP server, which lets an AI assistant find and call it directly. Any agent that can call an HTTP endpoint can also use the REST API directly.
Does Goodreads Review Scraper return data in a format LLMs can use directly?
Yes. Typed, normalized JSON with consistent field names, no HTML parsing and no selectors. Pass review text and rating straight to an LLM, index them into a vector store, or feed them to an agent tool with no transformation step.
What happens when Goodreads changes its layout or updates its anti-bot system?
The maintaining team updates the Actor when Goodreads changes its page or defenses — your calls keep returning the same JSON schema with no changes on your end.
Can I use Goodreads Review Scraper without managing proxies or Goodreads credentials?
Yes. No Goodreads account, login, or API key is required, and proxy handling is automatic — a run starts on a direct connection and only reaches for a proxy if Goodreads blocks it.
Which Goodreads review fields work best for AI training data and RAG indexing?
For RAG: review text, paired with the reviewer's name and the shelf/tag data for category context. For training data: star rating, like count, and comment count. All fields are typed primitives — no normalization needed.