Goodreads Books Scraper
Pricing
from $1.11 / 1,000 books
Goodreads Books Scraper
Search Goodreads by title, author or keyword and get one row per book: title with its series, author, average rating, how many people rated it, the listed edition's year, full-size cover and link. Up to 20 terms a run. No account. $1.14 per 1,000 books.
Pricing
from $1.11 / 1,000 books
Rating
0.0
(0)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
8 days ago
Last modified
Categories
Share
Type a title, an author or a plain keyword and get Goodreads search results back as rows: title, author, average rating, how many people rated it, the year of the edition Goodreads lists, the full-size cover and the book link.
What it gives you is the search listing, not the book page. That means ratings and counts, and it means no blurb, no ISBN, no genres and no reviews. The listing also does not show a book's first publication year or its edition count, so those two columns are always empty.
| Input | Titles, authors or keywords, up to 20 per run |
| Output | One row per book: title with its series, author, average rating, ratings count, listed edition's year, cover, link |
| Ceiling | 2,000 books per run |
| Account needed | None, no API key, no browser |
| Price | $1.14 per 1,000 books on the Free plan, a little less on paid plans. The free plan's $5 a month covers about 4,300 |
🔍 What Goodreads Books Scraper does
It runs each of your search terms and pages through the results until it has your share of the row budget. The budget is split evenly between terms, so four terms and 40 rows gives you ten of each rather than 40 of the first one.
searchField changes the answer more than it looks. Searching christie as an author gives you
Agatha Christie's novels. The same word as a title gives you books with Christie in the name. Those
are genuinely different result sets, not the same set reordered.
Two things it refuses to bill you for. A book Goodreads lists without a rating is skipped, because a row with no rating is the thing you came for missing. And "Goodreads looked and found nothing" is a real answer, kept separate from "the request never got through", so a term that genuinely has no matches is not charged as rows.
Goodreads serves 20 books per search page, and its deep pages start handing back books you have already seen. Paging stops at 50 pages per term, which is past where distinct results ran out in testing.
📋 What data you get from each Goodreads book
| What you get | Field |
|---|---|
| Goodreads' id for the book, and its link | bookId, url |
| The title as listed, series marker included | title |
| The author | author |
| Average rating and how many ratings it rests on | avgRating, ratingsCount |
| The year of the edition the listing shows | editionPublishedYear |
| The full-size cover | coverUrl |
| Which term found it, how, and at what position | query, searchField, rank |
| When it was read | scrapedAt |
▶️ How to scrape Goodreads books
- Open Goodreads Books Scraper and click Try for free.
- Put one term per line into Search terms.
- Pick Search in if you want author-only or title-only matching.
- Set Maximum rows. Start at 20 to see the shape of the output.
- Click Start, then download the dataset as JSON, CSV or Excel, or read it from the Apify API.
Start it with no search terms and you get one labelled sample row instead, which is not charged.
💰 How much does it cost to scrape Goodreads?
$1.14 per 1,000 books on the Free plan. Paid plans pay a little less: $1.13 on Starter, $1.12 on Scale and $1.11 on Business. On the free plan, the $5 Apify gives you each month covers about 4,300 books.
You pay per book row delivered. Duplicates across terms, books skipped for having no rating, the sample row, diagnostic rows and a term that finds nothing are not charged.
📥 What you give it
{"queries": ["dune", "project hail mary"],"searchField": "all","maxItems": 20}
| Field | Default | What it is |
|---|---|---|
queries | none, the form starts with dune and project hail mary | Titles, author names or keywords, one per line, up to 20. Each is searched in turn. |
searchField | all | all is Goodreads' own default and mixes titles, authors and series. title and author return different sets. |
maxItems | 20 | Total books across every term, up to 2,000, shared evenly between them. This is also your spending cap. |
proxyUrls | none | Leave it empty unless you have your own servers you want the traffic to leave through, one URL per line as http://user:pass@host:port. |
📤 What you get back
A real row from a run on 2 October 2026:
{"ok": true,"charged": true,"recordType": "book","query": "dune","searchField": "all","rank": 1,"bookId": "44767458","title": "Dune (Dune, #1)","author": "Frank Herbert","avgRating": 4.29,"ratingsCount": 1714417,"publishedYear": null,"editionPublishedYear": 2019,"editionsCount": null,"url": "https://www.goodreads.com/book/show/44767458","coverUrl": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1555447414i/44767458.jpg","scrapedAt": "2026-10-02T23:23:22.478Z"}
| Field | How to read it |
|---|---|
bookId | Goodreads' own id for the work. Stable, so use it to dedupe across runs. |
avgRating, ratingsCount | The average out of five and how many ratings it is built on. Every delivered row has both. |
editionPublishedYear | The year the edition Goodreads lists was published. For a reissue that is the reissue's year (2019 for the Dune above), not the year the book first came out. |
publishedYear, editionsCount | Always null. The search listing does not show the first publication year or the edition count. The columns stay so anything built on them keeps working. |
title | As listed, series marker and all, like Dune (Dune, #1). |
coverUrl | The full-size cover image on Goodreads' own servers. |
🧾 Reading the output
Three kinds of row can land in your dataset, and recordType tells them apart.
| Row | How to spot it | Billed |
|---|---|---|
| A book | recordType: "book" | yes |
| The sample row | _sample: true, recordType: "sample" | no |
| A diagnostic | _diagnostic: true and an errorCode | no |
The charged field is a label, not a receipt. It is stamped when the row is built, before
billing happens, so read it the way you read recordType: it separates real books from sample and
diagnostic rows, nothing more.
| Code | What it means |
|---|---|
NO_RESULTS | Goodreads has nothing matching that term. A real answer, and not charged. |
ROW_INCOMPLETE | A book was listed without a rating, so it was skipped rather than delivered. Not charged. |
TIME_BUDGET | The run ran out of time before reaching a term. Everything already delivered is complete. |
NOT_SERVED | This book was not served this run. Re-run it later. Until 12 October 2026 this code was called BLOCKED. |
NETWORK | Goodreads was unreachable. Re-run it. |
PROXY_INPUT_ADJUSTED | A connection setting in your input was not usable, so the run used its own. |
CHARGE_ERROR | Billing could not be recorded for some rows. Rare, and worth telling us about. |
One bad term never stops the others, and a diagnostic row never fails the run.
💡 What people use it for
- Checking how an author's back catalogue is rated, by searching them with
searchFieldset toauthorand sorting onratingsCount. - Building a shortlist for a reading list or a shop buy, where
avgRatingalone is misleading andratingsCountis the number that matters. - Watching how a new release gathers ratings week by week, scheduled and deduped on
bookId. - Resolving a messy list of titles to real Goodreads links and ids before enriching them elsewhere.
🚧 What it does not do
- Search results only. No blurb, no ISBN, no genres, no page count, no publisher.
- No reviews and no reviewer data. Only the rating average and the count.
- No user shelves, no lists, no author pages, and nothing that needs a Goodreads login.
- Books with no rating are skipped, so a very obscure or just-announced title may not appear.
- 50 pages per term. Goodreads' deep pages repeat, so a single term will not yield thousands of
distinct books however high you set
maxItems. - No first publication year and no edition count.
editionPublishedYearis the year of the edition the listing shows, which for a classic can be decades after it first came out. - Relevance order is Goodreads', applied before paging, so asking for 20 gives you the 20 it serves first.
- It is not an official Goodreads tool. Dami's Studio is independent and is not affiliated with or endorsed by Goodreads or Amazon, or by any other company named on this page.
🧭 Which reference scraper do you need?
| If you want | Use |
|---|---|
| Wikipedia search results or article text | Wikipedia Scraper |
| Wikidata Q-ids, aliases and claims, by name or by ID | Wikidata Scraper |
| Book metadata by keyword, title or ISBN | Books Scraper |
| Goodreads ratings and rating counts from a book search | This one |
| Books, audio, film and software held on archive.org | Internet Archive Scraper |
| Papers with readable abstracts and citation counts | OpenAlex Scraper |
| Wikipedia, arXiv and OpenAlex searches as tools for an AI agent | Research MCP Server |
❓ Questions people ask
Do I need a Goodreads account or an API key?
Neither. The search listing needs no login.
Can I get the book description or the ISBN?
Not from here. Books Scraper covers ISBN, publisher and page count.
Why do author and title searches give different books?
Because they are different searches. author matches the writer, title matches words in the name
of the book.
Why did I get fewer rows than I asked for?
Either the terms ran out of distinct results, or some books had no rating and were skipped. The diagnostic rows say which.
Why does the rating count differ from the Goodreads page?
Ratings keep arriving every day, so a row is a snapshot. Compare it with the page at the time in
scrapedAt, not with what the page says an hour later.
Can I call it from code or connect it to an AI assistant?
Yes. The API tab has ready-made
code for Python, JavaScript and the command line. For Claude, ChatGPT or another MCP client, connect
https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/goodreads-books-scraper. Either way the
run happens on your Apify account at the same price.
Is scraping Goodreads legal?
These are public catalogue pages. Author names are personal data under GDPR, so have a reason for collecting them. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.
🆘 If something breaks
Open the Issues tab on the actor page. Send the run ID and the search term you used. The
errorCode on the diagnostic row usually names the problem on its own.