Goodreads Review Scraper π
Pricing
from $1.99 / 1,000 results
Goodreads Review Scraper π
Goodreads Review Scraper extracts book reviews with rating, full text, reviewer, like and comment counts, spoiler status, shelving and timestamps. π Perfect for sentiment analysis, literary research and publisher review monitoring.
Pricing
from $1.99 / 1,000 results
Rating
0.0
(0)
Developer
Scrapers Hub
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
8 days ago
Last modified
Categories
Share
π Goodreads Review Scraper β Extract Book Reviews, Ratings & Reader Engagement Data
The Goodreads Review Scraper pulls structured book reviews straight from Goodreads book pages, returning review text, star ratings, reviewer profiles, like and comment counts, spoiler flags, shelving data and precise timestamps. Give it one or more Goodreads book URLs, set how many reviews you want, and the actor returns a clean JSON record per review β ready for sentiment analysis, market research, competitive publishing intelligence or reader-community studies.
Goodreads holds one of the largest bodies of long-form reader opinion anywhere on the web, and this Goodreads scraper turns that unstructured commentary into a dataset you can actually query. Because each record carries both the qualitative signal (text) and the quantitative signals (rating, likeCount, commentCount), you can rank reviews by influence rather than treating every opinion as equally weighted.
π What Data Can You Extract with This Goodreads Review Scraper?
Every review is returned as a flat record built from Goodreads' own review objects. The table below groups the real output fields into the categories most analysts work with.
| Category | Fields | What it gives you |
|---|---|---|
| π Review identity | id, __typename, bookUrl | The unique Goodreads review identifier, the object type name, and the book URL the review belongs to β enough to deduplicate and to join reviews back to titles. |
| β Rating signal | rating | The reviewer's star rating as an integer, the core quantitative measure for score distributions and average-rating analysis. |
| βοΈ Review body | text | The full written review β the long-form qualitative content that carries the actual opinion. |
| π€ Reviewer profile | creator | A nested object describing the review's author, including their Goodreads user identifiers and profile imagery. |
| π¬ Engagement metrics | likeCount, commentCount | How many readers liked the review and how many replied β the clearest proxy for which opinions the community actually rates. |
| π Timestamps | createdAt, updatedAt, lastRevisionAt | Epoch-millisecond timestamps for when the review was written, last updated, and last revised. |
| π·οΈ Flags & shelving | spoilerStatus, shelving, recommendFor, preReleaseBookSource, viewerHasLiked | Whether the review is marked as a spoiler, the reviewer's shelf assignment for the book, recommendation context, pre-release source, and viewer-like state. |
The most underrated field here is likeCount. Goodreads reviews are not equally visible β a handful of highly liked reviews shape how thousands of prospective readers perceive a book. Sorting your dataset by likeCount shows you the reviews that actually drive purchasing sentiment, rather than the long tail nobody reads.
π Key Features of the Goodreads Review Scraper
| Feature | Description |
|---|---|
| π Multi-book input | Supply an array of Goodreads book URLs and collect reviews for an entire catalogue, series or comparison set in one run. |
| π’ Review cap control | The maxItems setting bounds how many reviews are scraped, defaulting to 50, so you can keep runs tight or open them up for deep analysis. |
| π User-configurable proxy | A standard Apify proxy selector is exposed as proxyConfiguration, letting you choose whether and how proxies are used for the run. |
| β Full rating capture | Every review carries its integer rating, giving you a complete star distribution rather than just the aggregate score Goodreads displays. |
| π¬ Engagement metrics included | likeCount and commentCount come with every record, so you can weight reviews by community response. |
| π΅οΈ Spoiler awareness | The spoilerStatus boolean lets you include or exclude spoiler-flagged reviews before they reach your analysis or a public-facing display. |
| π₯ Reviewer context | The nested creator object preserves reviewer identity data, enabling repeat-reviewer detection and reviewer-level analysis. |
| β±οΈ Three-timestamp model | createdAt, updatedAt and lastRevisionAt distinguish original posting from later edits β important when tracking review manipulation or campaign timing. |
| π¦ Standard dataset output | Results land in an Apify dataset, exportable as JSON, CSV, Excel, XML or HTML, or retrievable through the API. |
π Why Choose This Goodreads Review Scraper?
Reviews with weight, not just volume. Anyone can count reviews. This Goodreads review scraper returns likeCount and commentCount alongside every review body, so you can separate the opinions the community amplified from the ones it ignored. That distinction changes conclusions: a 2-star review with 400 likes tells you far more about a book's reception than fifty unread 5-star entries.
Complete edit history signals. Most review datasets carry a single date. Here you get createdAt, updatedAt and lastRevisionAt as separate epoch-millisecond values. The gap between creation and revision is a genuine research signal β useful for spotting reviews rewritten after a controversy, or ratings adjusted long after publication.
Configurable proxy handling. The actor exposes a standard Apify proxy selector through proxyConfiguration, so you decide whether the run uses Apify Proxy and which groups apply. That control matters when you are scraping a large catalogue over an extended period.
A schema that matches Goodreads' own model. Fields such as __typename, shelving, spoilerStatus and preReleaseBookSource mirror the structures Goodreads itself uses. Nothing is flattened away or reinterpreted, so if you later need a field you did not think you needed, it is already in your dataset.
π₯ Input
The Goodreads scraper takes a list of book URLs plus two optional settings.
{"bookUrls": ["https://www.goodreads.com/book/show/1137215"],"maxItems": 50,"proxyConfiguration": {"useApifyProxy": false}}
π§ Goodreads Review Scraper Input Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
bookUrls | array of strings | β Yes | β (prefilled with https://www.goodreads.com/book/show/1137215) | List of Goodreads book URLs to scrape reviews from. |
maxItems | integer | β No | 50 | Maximum number of reviews to scrape. |
proxyConfiguration | object | β No | { "useApifyProxy": false } | Select proxies to be used by your scraper. Rendered as the standard Apify proxy editor. |
π‘ Input Examples
A single classic title, default review cap
{"bookUrls": ["https://www.goodreads.com/book/show/1137215"]}
A comparison set with a larger sample and Apify Proxy enabled
{"bookUrls": ["https://www.goodreads.com/book/show/1137215","https://www.goodreads.com/book/show/2657","https://www.goodreads.com/book/show/5107"],"maxItems": 250,"proxyConfiguration": {"useApifyProxy": true}}
A quick sample run for schema testing
{"bookUrls": ["https://www.goodreads.com/book/show/1137215"],"maxItems": 10}
π€ Output
Each review becomes one dataset item. The record below is a real result from an actual run, trimmed for readability.
{"__typename": "Review","id": "kca://review:goodreads/amzn1.gr.review:goodreads.v1.sdrC-ZRjzY6QMCANZHeBhQ","bookUrl": "https://www.goodreads.com/book/show/1137215","rating": 3,"text": "``Miss Eliza Bennet, let me persuade you to follow my example, and take a turn about the room. -- Iβ¦","creator": "{\"__typename\": \"User\", \"legacyId\": 1036930, \"imageUrlSquare\": \"https://i.gr-assets.com/images/S/compβ¦","likeCount": 389,"commentCount": 68,"spoilerStatus": false,"createdAt": 1267104748000,"updatedAt": 1778015368572,"lastRevisionAt": 1386195467000,"shelving": "{\"__typename\": \"Shelving\", \"creator\": {\"__typename\": \"User\", \"id\": \"kca://profile:goodreads/A30RDWR9β¦","recommendFor": null,"preReleaseBookSource": null,"viewerHasLiked": null}
π§Ύ Goodreads Review Output Fields
| Field | Type | Description |
|---|---|---|
bookUrl | string | null | URL of the item's book. |
id | string | null | Unique identifier of the review. |
__typename | string | null | Name of the typename β the Goodreads object type. |
rating | integer | null | Rating score given by the reviewer. |
text | string | null | Main text content of the review. |
createdAt | integer | null | When the review was created, as an epoch-millisecond timestamp. |
updatedAt | integer | null | When the review was last updated. |
creator | object | null | Creator of the review β the reviewer's profile object. |
likeCount | integer | null | Number of likes the review received. |
commentCount | integer | null | Number of comments on the review. |
spoilerStatus | boolean | null | Whether the review is flagged as containing spoilers. |
recommendFor | null | Recommendation context for the review. |
lastRevisionAt | integer | null | When the last revision happened. |
preReleaseBookSource | null | Pre-release book source of the review. |
shelving | object | null | Shelving information β how the reviewer shelved the book. |
viewerHasLiked | null | Whether the viewing account has liked the review. |
Timestamps are Unix epoch values in milliseconds, not seconds. Divide by 1000 before passing them to most date libraries, or your dates will land tens of thousands of years in the future.
π» How to Use the Goodreads Review Scraper (Step by Step)
Step 1: Collect the Goodreads Book URLs You Want
Open Goodreads and navigate to each book whose reviews you need. The URL you want is the canonical book page β the form https://www.goodreads.com/book/show/<id>. You can trim any trailing slug after the numeric ID. Gather these into a list: a single title for a focused study, or a dozen competing titles if you are building a comparative picture of a genre or an imprint's catalogue.
Step 2: Configure Your Input in the Apify Console
Open the Goodreads Review Scraper and go to the Input tab. Paste your URLs into the Book URLs string list, one per line. The field is prefilled with a sample Goodreads book URL that you can replace. Set Max Items to the number of reviews you want per run β it defaults to 50, which is a sensible sample for a first pass but too small for statistical work on a popular title.
Step 3: Decide on Proxy Configuration
The Proxy Configuration field uses the standard Apify proxy editor and defaults to { "useApifyProxy": false }. For small, occasional runs the default is often fine. For larger catalogues or repeated scheduled runs, enabling Apify Proxy distributes requests across a pool of addresses and generally makes long runs more stable.
Step 4: Run the Goodreads Scraper and Watch the Log
Click Start. The run log reports progress as reviews are collected for each book URL. Watch for the point at which the actor reaches your maxItems cap β if it stops well short of that number, the book simply has fewer public reviews available than you asked for, which is common for niche or newly published titles.
Step 5: Inspect the Dataset
When the run completes, open Storage β Dataset. Check three things immediately: that bookUrl matches the titles you submitted, that rating values fall in the expected 1β5 range, and that text contains genuine review prose rather than empty strings. Sort by likeCount descending to see the most influential reviews for each book at a glance.
Step 6: Export or Pipe the Review Data
Export the dataset as JSON, CSV, Excel, XML or HTML. JSON is strongly preferred here because creator and shelving are nested objects β CSV export flattens or stringifies them, and you will lose structure you may want later. For programmatic use, pull items straight from the dataset API.
Step 7: Schedule Ongoing Review Monitoring
Attach an Apify schedule if you want to track a title's reception over time. Re-running the same bookUrls weekly and comparing id sets tells you which reviews are new; comparing likeCount on existing review IDs shows which older reviews are gaining traction. Add a webhook on run success to push each batch into your own store automatically.
π API Access & Integrations
Trigger the Goodreads review scraper from the Apify API and receive dataset items in the same request.
curl -X POST "https://api.apify.com/v2/acts/scrapers-hub~golden-age-review-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"bookUrls": ["https://www.goodreads.com/book/show/1137215"],"maxItems": 50,"proxyConfiguration": { "useApifyProxy": false }}'
The equivalent call from Python with the official client:
from apify_client import ApifyClientclient = ApifyClient("YOUR_TOKEN")run_input = {"bookUrls": ["https://www.goodreads.com/book/show/1137215"],"maxItems": 100,"proxyConfiguration": {"useApifyProxy": True},}run = client.actor("scrapers-hub/golden-age-review-scraper").call(run_input=run_input)reviews = list(client.dataset(run["defaultDatasetId"]).iterate_items())reviews.sort(key=lambda r: r.get("likeCount") or 0, reverse=True)for review in reviews[:10]:print(review["rating"], "β β", review["likeCount"], "likes")print((review.get("text") or "")[:200], "\n")
The actor also connects to Zapier, Make, Google Sheets, Slack and generic HTTP webhooks, so new Goodreads review data can flow into a spreadsheet, a marketing dashboard or a team channel without writing integration code.
π‘ Best Use Cases for Goodreads Review Data
π Book Market Research and Reader Sentiment Analysis
Feed the text and rating fields into a sentiment model to map how readers actually talk about a title, then segment by star band to see what separates a 5-star reader from a 2-star one. Because likeCount weights each opinion by community endorsement, you can build a sentiment score that reflects influence rather than raw volume β a much better predictor of a book's public reputation.
π’ Publisher and Imprint Competitive Intelligence
Submit the Goodreads URLs for a competitor's entire front list and compare rating distributions across the catalogue. Grouping by bookUrl and analysing the spread of rating reveals which acquisitions landed and which underperformed, while commentCount highlights the titles generating genuine discussion rather than passive consumption.
βοΈ Author Reputation and Series Tracking
Authors and agents can track how each instalment of a series is received by scraping every book in the series and comparing createdAt clusters against release dates. The lastRevisionAt field is particularly telling: reviews revised long after publication often mark the point where a reader's opinion shifted after finishing the wider series.
π― Marketing Copy and Blurb Mining
The highest-likeCount reviews are, by definition, the ones the reading community found most persuasive. Mining their text for recurring phrases surfaces the exact language readers use to recommend a book β far better source material for ad copy and jacket blurbs than internal brainstorming. Filter out records where spoilerStatus is true before any public reuse.
π¬ Academic and Cultural Studies Research
Researchers studying reception theory, reading communities or digital literary criticism get a structured corpus with reviewer identity (creator), engagement (likeCount, commentCount) and precise chronology (createdAt, updatedAt, lastRevisionAt). That combination supports longitudinal analysis of how a work's critical reception evolves across years.
π‘οΈ Review Authenticity and Anomaly Detection
Suspicious review activity often shows a distinctive shape: dense clusters of createdAt values in a narrow window, near-zero likeCount and commentCount, and reviewers in creator with minimal profile history. Extracting these fields together lets fraud and trust teams flag patterns that are invisible when you only look at the aggregate rating.
π Recommendation Engines and Bookseller Catalogues
Retailers and reading apps can enrich catalogue entries with genuine reader commentary. Pair rating with shelving to understand how readers categorise a book in their own taxonomy, then use those shelf signals to power "readers who shelved this also shelvedβ¦" style recommendations grounded in real reader behaviour.
βοΈ Tips for Better Goodreads Review Scraping Results
- Raise
maxItemsdeliberately. The default of 50 reviews is a sample, not a census. For any statistical claim about a popular title, request several hundred so your rating distribution is not dominated by whichever reviews happen to surface first. - Enable Apify Proxy for larger runs.
proxyConfigurationdefaults to no proxy. If you are scraping many books or running on a schedule, switchinguseApifyProxyto true generally produces more stable long runs. - Use the canonical book URL. The
https://www.goodreads.com/book/show/<id>form is the reliable input. Edition-specific and localised variants may resolve to different review pools than you expect. - Deduplicate on
id. When re-running the same books over time, the reviewidis the stable key. Deduplicating on it lets you merge successive runs into a growing corpus without double counting. - Convert timestamps carefully.
createdAt,updatedAtandlastRevisionAtare epoch milliseconds. Divide by 1000 for libraries that expect seconds. - Filter
spoilerStatusbefore publishing. If review text will be shown to readers, exclude records wherespoilerStatusis true β it is a one-line filter that avoids a genuine reader-experience problem.
π οΈ Troubleshooting
The run returned fewer reviews than my maxItems value.
This normally means the book simply has fewer publicly visible reviews than you requested. Niche titles, recent releases and non-English editions often have small review pools. Check the book page on Goodreads directly to see how many reviews exist before assuming the scraper stopped early.
creator and shelving look like strings rather than objects in my export.
CSV and Excel exports cannot represent nested structures, so complex fields are stringified during export. Export as JSON instead, or parse the stringified values back into objects after import. The dataset itself stores them as objects.
My dates are showing up in the year 58000.
You are treating epoch-millisecond timestamps as seconds. createdAt, updatedAt and lastRevisionAt are all in milliseconds β divide by 1000 before converting.
Some fields are always null.
recommendFor, preReleaseBookSource and viewerHasLiked are typed as nullable and are frequently empty because Goodreads only populates them in specific contexts, such as advance reader copies or authenticated sessions. Null here means "not applicable to this review", not "extraction failed".
Runs are slow or unstable when scraping many books.
Reduce the number of bookUrls per run and split the work across several scheduled runs, and enable Apify Proxy through proxyConfiguration. Smaller, more frequent runs are easier to retry and easier to debug than one very large job.
β Frequently Asked Questions About Goodreads Review Scraping
What does the Goodreads Review Scraper extract?
It extracts individual book reviews from Goodreads book pages, including the review text, the rating, the reviewer object in creator, engagement counts (likeCount, commentCount), spoiler status, shelving data and three separate timestamps.
What input does the Goodreads scraper need?
One required field, bookUrls β an array of Goodreads book URLs. You can also set maxItems to cap how many reviews are collected and proxyConfiguration to choose proxy settings.
How many reviews does it collect by default?
maxItems defaults to 50. Increase it when you need a larger sample for analysis.
Can I scrape reviews for several books in one run?
Yes. bookUrls is an array, so you can submit a whole series, an imprint's catalogue or a competitive comparison set in a single run. Each review carries bookUrl so you can group results by title afterwards.
Does the Goodreads review scraper support proxies?
Yes. proxyConfiguration is exposed as a standard Apify proxy selector and defaults to { "useApifyProxy": false }, so you control whether and how proxies are used.
What format are the timestamps in?
createdAt, updatedAt and lastRevisionAt are Unix epoch timestamps in milliseconds.
What is the difference between updatedAt and lastRevisionAt?
Both track post-creation changes, but they are separate fields in Goodreads' own model and can differ. Keeping both lets you distinguish general record updates from the reviewer's last actual revision.
Can I filter out spoiler reviews?
Every record includes a spoilerStatus boolean. Filter on it in your downstream processing to exclude spoiler-flagged reviews before display or analysis.
What does the __typename field mean?
It is the Goodreads object type name for the record, typically Review. It is preserved so the output stays faithful to the source schema.
Can I get the reviewer's name and profile?
The creator field holds the reviewer object, which includes Goodreads user identifiers and profile imagery. Treat it as personal data and handle it in line with the privacy guidance in the disclaimer below.
How do I identify the most influential reviews?
Sort by likeCount descending, optionally breaking ties on commentCount. Those are the reviews the Goodreads community engaged with most, and they disproportionately shape how a book is perceived.
Can I schedule the Goodreads scraper to run regularly?
Yes. Apify schedules let you re-run the same bookUrls on any cadence, and webhooks can notify your systems when a run finishes so new reviews are ingested automatically.
What export formats are available for Goodreads review data?
JSON, JSONL, CSV, Excel, XML, HTML and RSS. JSON is recommended because it preserves the nested creator and shelving objects.
Does the actor scrape private or friends-only reviews? No. Only reviews that Goodreads displays publicly are accessible. Anything restricted to a reviewer's connections is out of scope.
How do I track new reviews over time?
Re-run the same book URLs on a schedule and compare the set of review id values between runs. IDs not seen before are new reviews; changes in likeCount on existing IDs show which older reviews are still gaining traction.
π Support & Feedback
Hit a bug or an unexpected result? Open a ticket on the actor's Issues tab, including the exact Goodreads book URL and the input you used. Reports that can be reproduced get resolved fastest.
Need something tailored β additional fields, a different review sorting strategy, bulk catalogue processing or a private build for your publishing workflow? Email scraperhubapi@gmail.com with the details of what you need.
If the Goodreads Review Scraper is useful to you, a review on the Apify Store genuinely helps. Feedback from real users determines which features get built next.
βοΈ Disclaimer
The Goodreads Review Scraper collects publicly available data only β reviews that Goodreads displays to any visitor without authentication. It does not access private profiles, friends-only content or anything behind a login.
You are responsible for how you use the extracted Goodreads review data. Review the Goodreads Terms of Service and robots.txt before running the scraper at scale, keep request volumes reasonable, and do not use the data in ways the platform prohibits.
Book reviews contain personal data. The creator object identifies real Goodreads users, and review text may include personal details that reviewers chose to share. If you process this data for individuals in the EU, UK or other regulated jurisdictions, you must comply with the GDPR and equivalent privacy legislation β establish a lawful basis, minimise what you store, honour data subject rights, and delete data you no longer need. Review text also remains the intellectual property of its author; extraction grants no licence to republish it.
If you believe data collected by this Goodreads scraper relates to you and you would like it removed, contact scraperhubapi@gmail.com with the relevant details and we will action your request.