Goodreads Scraper — Books, Ratings & Reviews
Under maintenancePricing
from $1.00 / 1,000 results
Goodreads Scraper — Books, Ratings & Reviews
Under maintenanceScrape public Goodreads book metadata, 1–5 star rating distributions, review-language counts, and linked reader reviews from book URLs, ISBNs, or queries.
Pricing
from $1.00 / 1,000 results
Rating
0.0
(0)
Developer
Hyperbach
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
6 days ago
Last modified
Categories
Share
Book metadata, rating distributions, language counts, and public reader reviews from Goodreads. Start from exact book URLs, ISBN-10/13 values, or search queries; no Goodreads login or API key is required.
What this Actor covers — and what it does not
- Exact-book detail, not broad catalog crawling. The Actor accepts book URLs and ISBNs, plus the top five matches for each text query. It does not walk Goodreads shelves, lists, author catalogs, or every search page.
- Distribution data in the base book record.
ratingHistogramcarries the 1-to-5-star counts andreviewsByLanguagecarries public text-review counts by language when Goodreads exposes its page state. - Book and review rows in one bounded run. Set
maxItemsfor the combined output cap andmaxReviewsPerBookfor the per-book review cap. Reviews link back throughbookId. - Public pages only. No account, cookies, private shelves, or authenticated reader data. Goodreads can omit fields or temporarily challenge automated requests, so unavailable values remain null or empty and blocked books are logged and skipped.
Who it's for
- Publishers and book marketers — compare ratings, rating distributions, review volume, and public reader responses for exact titles.
- Catalog and recommendation teams — enrich ISBN/title records with Goodreads identifiers, genres, edition metadata, covers, and aggregate ratings.
- Researchers and analysts — collect bounded, reproducible public book and review samples with stable book IDs.
Quick start
One exact book
{"bookUrls": ["https://www.goodreads.com/book/show/3735293-clean-code"],"includeReviews": false,"maxItems": 1}
ISBN with up to ten reviews
{"isbns": ["9780132350884"],"includeReviews": true,"maxReviewsPerBook": 10,"maxItems": 11}
Search, filter, and cap
{"queries": ["clean code"],"minRating": 4.0,"includeReviews": false,"maxItems": 5}
Output
The dataset contains book records and, when requested, linked review records. itemType identifies the shape and bookId joins reviews to books.
| field | type | meaning |
|---|---|---|
itemType | string | Record discriminator: book or review. |
bookId | integer | Goodreads' stable numeric identifier for the book; joins book and review records. |
url | string | Canonical Goodreads URL for a book record. |
title | string | Book title. |
titleComplete | string | Complete edition title, including subtitle when Goodreads exposes it. |
authors | array | Authors and their public Goodreads profile URLs. |
description | string | Plain-text book description from the public edition page. |
genres | array | Genre names associated with the book. |
coverUrl | string | Book cover image URL published by Goodreads. |
averageRating | number | Current Goodreads average rating for the book. |
ratingsCount | integer | Current number of Goodreads ratings. |
reviewsCount | integer | Current number of Goodreads text reviews. |
ratingHistogram | object | Counts for 1-, 2-, 3-, 4-, and 5-star ratings, keyed by star value. |
reviewsByLanguage | array | Public text-review counts grouped by ISO language code. |
isbn | string | ISBN-10 for the edition, when available. |
isbn13 | string | ISBN-13 for the edition, when available. |
asin | string | Amazon Standard Identification Number for the edition, when available. |
pages | integer | Page count for the displayed edition. |
publisher | string | Publisher for the displayed edition. |
language | string | Language of the displayed edition. |
format | string | Edition format, such as Paperback, Hardcover, or Kindle Edition. |
publishedAt | string | Publication date of the displayed edition in YYYY-MM-DD form. |
originalPublishedAt | string | Original work publication date in YYYY-MM-DD form, when available. |
originalTitle | string | Original title of the work, when available. |
series | array | Series memberships with title and the book's position. |
awards | array | Awards recorded for the work, including year, category, and designation when available. |
workId | integer | Goodreads' numeric identifier for the underlying work across editions. |
scrapedAt | string | UTC timestamp when the record was scraped. |
reviewId | integer | Goodreads' stable numeric identifier for the public review. |
bookTitle | string | Book title repeated on a review record for export convenience. |
reviewerName | string | Public display name of the reviewer. |
reviewerUrl | string | Public Goodreads profile URL for the reviewer. |
rating | number | Stars assigned by the reviewer, including half-stars where Goodreads exposes them. |
reviewText | string | Visible public review text with markup removed. |
reviewDate | string | Review date text as Goodreads displays it. |
reviewUrl | string | Permalink to the public Goodreads review. |
likesCount | integer | Number of likes displayed for the review. |
hasSpoiler | boolean | Whether Goodreads marks the review as containing a spoiler. |
Live example from a bounded run:
{"itemType": "book","bookId": 3735293,"url": "https://www.goodreads.com/book/show/3735293-clean-code","title": "Clean Code: A Handbook of Agile Software Craftsmanship","titleComplete": "Clean Code: A Handbook of Agile Software Craftsmanship","authors": [{"name": "Robert C. Martin","url": "https://www.goodreads.com/author/show/45372.Robert_C_Martin"}],"description": "Even bad code can function. But if code isn't clean, it can bring a development organization to its knees.","genres": ["Programming","Computer Science","Technology","Software"],"coverUrl": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1436202607i/3735293.jpg","averageRating": 4.35,"ratingsCount": 23742,"reviewsCount": 1494,"ratingHistogram": {"1": 159,"2": 447,"3": 2587,"4": 8317,"5": 12232},"reviewsByLanguage": [{"language": "en","count": 1303},{"language": "es","count": 46},{"language": "pt","count": 28}],"isbn": "0132350882","isbn13": "9780132350884","asin": "0132350882","pages": 431,"publisher": "Prentice Hall","language": "English","format": "Paperback","publishedAt": "2008-08-01","originalPublishedAt": "2007-01-01","originalTitle": "Clean Code: A Handbook of Agile Software Craftsmanship (Robert C. Martin Series)","series": [{"title": "Robert C. Martin Series","position": ""}],"awards": [],"workId": 3779106,"scrapedAt": "2026-08-03T11:23:04Z"}
Pricing
$0.004 per result — pay only for book and review rows the run delivers, with no start fee. maxItems caps the combined output and the Actor also clamps delivery to the run's pay-per-event budget.
Usage patterns
- Start with exact identifiers — Book URLs and ISBNs avoid search ambiguity. Text queries return at most the top five matches each.
- Bound the first run — Use a small
maxItems; it counts book and review rows together and is also clamped to the run's pay-per-event budget. - Treat reviews as optional fan-out — Keep
maxReviewsPerBooksmall initially. Goodreads' legacy review pagination is best-effort; the Actor falls back to public review cards embedded in the book page. - Handle source blocking — The managed Actor uses a shared cache that fetches direct first and falls back to residential egress after a source challenge. Supplying an Apify proxy configuration explicitly overrides that shared route; datacenter proxy addresses may themselves be challenged.
Input reference
| field | type | default | what it does |
|---|---|---|---|
bookUrls | array | [] | Goodreads book page URLs, e.g. https://www.goodreads.com/book/show/3735293-clean-code |
queries | array | [] | Free-text searches (title, author, keyword). The top matching books are scraped. |
isbns | array | [] | ISBN-10 or ISBN-13 codes. Each is resolved to the matching book page. |
includeReviews | boolean | true | Collect public reader reviews for each book. |
maxReviewsPerBook | integer | 10 | Cap on collected reviews per book. 0 disables review collection entirely. |
minRating | number | 0 | Skip books with an average rating below this value (0 = no filtering). |
maxItems | integer | 200 | Total dataset records cap (books + reviews). Default 200; set 0 for an unlimited run. |
delaySeconds | integer | 2 | Politeness delay between HTTP requests. Higher values reduce the risk of rate-limiting. |
maxRequestsPerMinute | integer | 20 | Hard rate limit across all requests. Lower values reduce the risk of IP blocking. |
proxyConfiguration | object | Apify Proxy (optional). Defaults to off: requests come directly from the run's IP, which works for typical volumes. If Goodreads starts blocking you (HTTP 202/403), enable it and consider residential proxy groups. |
FAQ
Does this crawl shelves, lists, authors, or all Goodreads search pages?
No. This Actor focuses on exact book detail and bounded discovery: direct book URLs, ISBNs, and the top five matches per text query. Use a broader catalog crawler when you need shelves, lists, author catalogs, or deep search pagination.
How many reviews can it return?
Up to maxReviewsPerBook for each accepted book, subject to the total maxItems cap. Deep review pagination uses a legacy Goodreads endpoint and is best-effort; when unavailable, the Actor falls back to visible public review cards from the book page.
Why are some fields null or empty?
Goodreads does not expose every field for every edition, and the richer histogram/language/series fields depend on page state that may be absent. The Actor returns observed values and does not invent missing data.
What happens when Goodreads blocks a request?
The managed Actor's shared fetch layer detects source challenges and retries through residential egress; cache hits avoid the source request altogether. If that service is unavailable, the Actor falls back to its own egress. An explicit proxy input always takes precedence. The client still rate-limits requests and backs off on 429/5xx responses.
Is maxItems a book limit?
No. It is the combined dataset-row limit: book rows plus review rows. With maxItems: 1, the Actor fetches and returns one book and does not make review requests.
Integration
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_TOKEN' });const run = await client.actor('hyperbach/goodreads-scraper').call({"bookUrls": ["https://www.goodreads.com/book/show/3735293-clean-code"], "includeReviews": false, "maxItems": 1});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Python
from apify_client import ApifyClientclient = ApifyClient('YOUR_TOKEN')run = client.actor('hyperbach/goodreads-scraper').call(run_input={'bookUrls': ['https://www.goodreads.com/book/show/3735293-clean-code'], 'includeReviews': False, 'maxItems': 1})items = client.dataset(run['defaultDatasetId']).list_items().items
CLI
$apify call hyperbach/goodreads-scraper --input '{"bookUrls": ["https://www.goodreads.com/book/show/3735293-clean-code"], "includeReviews": false, "maxItems": 1}'
REST
curl -X POST "https://api.apify.com/v2/acts/hyperbach~goodreads-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H 'Content-Type: application/json' -d '{"bookUrls": ["https://www.goodreads.com/book/show/3735293-clean-code"], "includeReviews": false, "maxItems": 1}'
Support
This page is generated from readme.toml, the Actor schemas, and a live sample. Edit the sources and run python gen_readme.py; do not hand-edit README.md.