Good Reads Book Scraper
Pricing
$14.99/month + usage
Good Reads Book Scraper
The Good Reads Book Scraper extracts detailed book data from Goodreads, including title, author, rating, reviews, genres, and publication info. Great for researchers, publishers, and book lovers to analyze trends, track popular books, or build datasets for recommendations and literary insights.
Pricing
$14.99/month + usage
Rating
0.0
(0)
Developer
Scraper Engine
Maintained by CommunityActor stats
0
Bookmarked
9
Total users
0
Monthly active users
8 days ago
Last modified
Categories
Share
Goodreads Book Scraper — Ratings, Editions and Book Metadata
Goodreads Book Scraper searches Goodreads by phrase or by search URL and returns every result row as structured JSON — title, author, average rating, ratings count, first publication year, edition count, book ID, book URL and cover URL, in both text and numeric form. No HTML parsing, no login, no browser to manage. Rows land in the dataset as each results page is read, so you can start using books before a large run finishes. Give it a search phrase and try it on the Actor's Apify Store page below.
What is Goodreads Book Scraper?
Goodreads Book Scraper is an Apify Actor that runs Goodreads book searches and turns each result row into a typed JSON record — title, author, rating, ratings count, publication year, edition count, and links to the book page and cover image. It reads Goodreads' public search-results pages directly over HTTP; no Goodreads account, login, or API key is required or used anywhere in the Actor. It's built for developers, data analysts, and AI engineers who need clean, structured book-search data without scraping HTML by hand.
What Goodreads book data is publicly available to scrape?
Everything a visitor sees on a Goodreads search-results page is publicly accessible without an account — title, author, rating, and edition information for every matching book. Personal reading data tied to a Goodreads account is not.
| Data category | Publicly available | Requires login |
|---|---|---|
| Title, author, cover image | ✅ | ❌ |
| Average rating & ratings count | ✅ | ❌ |
| First publication year | ✅ | ❌ |
| Edition count | ✅ | ❌ |
| Book ID and canonical book URL | ✅ | ❌ |
| Full synopsis & individual reviews (book detail page — not fetched by this Actor) | ✅ | ❌ |
| Personal shelves ("want to read", "currently reading") | ❌ | ✅ |
| Friends' activity feed & reading progress | ❌ | ✅ |
Goodreads Book Scraper only returns publicly visible data — what any visitor sees on a Goodreads search-results page. Nothing behind a login wall.
What data can I extract with Goodreads Book Scraper?
Goodreads Book Scraper returns 16 fields per book: identity and publication details, rating and edition metrics in both text and numeric form, and metadata about where each row came from in your run.
| Field name | Description |
|---|---|
title | Book title as shown in the search result |
author | Author name as shown in the search result |
bookId | Numeric Goodreads book ID, extracted from the book's URL |
url | Full URL of the book's Goodreads page |
coverUrl | URL of the book's cover thumbnail image |
published | Publication year, as text (e.g. "2015"), empty string if Goodreads doesn't show one for this result |
publishedYear | Publication year as an integer, or null if not present |
rating | Average rating, as text (e.g. "4.53") |
ratingValue | Average rating as a float, or null if not parsed |
ratingsCount | Number of ratings, as text with comma formatting (e.g. "3,224") |
ratingsCountValue | Number of ratings as an integer, or null if not parsed |
editions | Edition count, as text (e.g. "12") |
editionsCount | Edition count as an integer, or null if not parsed |
searchRank | 1-based position of the book within its search line's results |
sourceQuery | The search phrase or search URL (from urls) that produced this row |
scrapedAt | UTC timestamp (ISO 8601) when the row was scraped |
Identity and publication fields
title, author, bookId, url, coverUrl, published, publishedYear — what the book is, who wrote it, where it lives on Goodreads, and when it first appeared.
Rating and edition metrics
rating, ratingValue, ratingsCount, ratingsCountValue, editions, editionsCount — Goodreads' own popularity and reception signals, delivered both as the original text Goodreads displays and as a parsed number ready for sorting, filtering, or aggregation.
Search and run metadata
searchRank, sourceQuery, scrapedAt — which search line each book came from, its rank in that search, and when the row was collected. Useful for reconciling results across a multi-line run.
🤖 Add-on: Need more ratings and review data?
Goodreads Book Scraper is scoped to search-results data. If your project also needs review or rating data from other platforms, Scraper-Engine publishes standalone Actors for that: Udemy Course Reviews Scraper, Walmart Reviews Scraper, and Airbnb Review Scraper cover ratings and review text outside Goodreads. Run them alongside this Actor rather than as a single combined job.
Why not build this yourself?
Goodreads' public developer API stopped issuing new keys in December 2020 and Goodreads has been winding it down since, so a new integration generally cannot register for official API access today (as observed on Goodreads' own developer discussion and reporting on the shutdown, checked 2026-08-15). That leaves scraping the public site as the practical option for fresh Goodreads book data.
Building and running that scraper yourself means writing and maintaining an HTML parser against Goodreads' markup, handling retries and connection failures, and either buying proxy access or accepting that a fixed IP gets rate-limited or blocked over time. Goodreads Book Scraper already does the parsing (label-anchored, not brittle position matching), the retry logic, and the proxy routing, and pushes typed rows to a dataset as it works instead of a raw HTML dump.
Use the Goodreads site directly if you only need to look up a handful of books by hand. Use Goodreads Book Scraper when you need search results collected, normalized, and exported at scale.
How to use Goodreads Book Scraper
You don't need any code to run a search — the Actor runs on Apify's platform and reads its input from a form.
- Open Goodreads Book Scraper on the Apify Store and click Try for free (or Run, if you already have it).
- Provide the required input:
urls— one search phrase (e.g. mystery novels) or full Goodreads search URL per line. - Optionally set
resultsPerQuery,maxItems,delayMs, andproxyConfigurationto control how much is collected and how gently. - Start the run.
- Read results from the Output tab as the run progresses, or export the dataset as JSON, CSV, Excel, XML, RSS, or HTML once it finishes.
How to scale to bulk book extraction
urls is a list — put one search phrase or search URL per line and the Actor works through them in order, applying resultsPerQuery to each line independently and maxItems as a shared cap across the whole run. There's no separate "batch" input beyond this: a hundred search lines in one run is the same shape as one, just longer. For very large catalogs, splitting across multiple runs with different urls lists lets you parallelize instead of waiting on one long sequential run.
What can you do with Goodreads book data?
- 📚 A recommendation-engine developer building a training corpus uses
title,author, andratingValueto backfill a catalog of well-rated books by genre before feeding it into a model. - 📈 A market researcher tracking genre trends uses
publishedYearandratingsCountValuetogether to see which years produced the most widely-rated titles in a category. - 🛒 A used-book reseller uses
bookIdandurlto cross-reference Goodreads listings against their own inventory before setting prices. - 🔬 A publishing researcher studies a backlist's staying power by tracking
editionsCountalongsidepublishedYearto see how many editions a title has accumulated since release. - 🤖 An AI engineer building a book-recommendation agent uses
title,author, andratingas grounding context in a RAG pipeline, so the agent cites real Goodreads ratings instead of hallucinating them.
How does Goodreads Book Scraper handle rate limits and blocking?
Each results page fetch opens a fresh connection: on the first attempt it uses a direct connection (or Apify Proxy immediately, if useApifyProxy is set), and warms up with a request to the Goodreads landing page before asking for the results page itself. If a fetch fails or returns a too-small response without the results table, the Actor drops that connection, retries up to 5 times total, waiting min(2 × attempt, 8) seconds between attempts, and switches to Apify Proxy (default group RESIDENTIAL, or the group/country you set) for the retry. Every response is checked for a minimum size and a results-table marker before being parsed, so a blocked or interstitial page is never mistaken for "no results."
If all attempts for a page fail, the Actor logs a warning, stops paging that search line, and moves on to the next one — it does not crash the whole run. No CAPTCHA-solving is performed.
⬇️ Input
| Parameter | Required | Type | Description | Example value |
|---|---|---|---|---|
urls | Yes | array (stringList) | One entry per line. A plain phrase (e.g. mystery novels) is searched on Goodreads; a full Goodreads search URL is followed as given, page by page. At least one entry is required. | ["python programming"] |
resultsPerQuery | No | integer (min 1, max 10000, default 10) | How many books to collect for each entry in urls. Paging continues until this many books are saved or the search runs out of results. | 10 |
maxItems | No | integer (min 1, max 100000) | Hard cap on the total number of books saved across every search line in one run. Leave empty for no overall cap. | 100 |
delayMs | No | integer (min 0, max 60000, default 1000) | Milliseconds to wait after each results page before asking for the next one. A larger pause makes a long run gentler on the source; 0 disables the pause. | 1000 |
proxyConfiguration | No | object (proxy editor) | Choose whether the run should go through Apify Proxy, and optionally pick a group and a country. The Actor manages the connection for you either way. | {"useApifyProxy": true} |
Example input
{"urls": ["python programming","https://www.goodreads.com/search?q=science+fiction&search_type=books"],"resultsPerQuery": 20,"maxItems": 200,"delayMs": 1000,"proxyConfiguration": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"],"apifyProxyCountry": "US"}}
⬆️ Output
Every book is pushed to the dataset as a typed, normalized JSON record the moment it's parsed — the schema is identical across every run. Export it from the Apify Console as JSON, CSV, Excel, XML, RSS, or HTML, or pull it with the API or apify_client. Each pushed row is billed under the row_result charged event — there are no separate uncharged error or accounting rows to filter out; if a book row didn't parse cleanly, it's simply not pushed.
Example output
{"title": "Fluent Python: Clear, Concise, and Effective Programming","author": "Luciano Ramalho","rating": "4.53","ratingValue": 4.53,"ratingsCount": "3,224","ratingsCountValue": 3224,"published": "2015","publishedYear": 2015,"editions": "12","editionsCount": 12,"bookId": "22800567","url": "https://www.goodreads.com/book/show/22800567-fluent-python","coverUrl": "https://images-na.ssl-images-amazon.com/images/S/compressed.photo.goodreads.com/books/1440227587i/22800567.jpg","searchRank": 1,"sourceQuery": "python programming","scrapedAt": "2026-08-15T10:12:03Z"}
How does it work?
Goodreads Book Scraper sends HTTP requests to Goodreads' public search pages — either a search phrase turned into a Goodreads search URL, or a search URL you supply directly, paged forward one page at a time. Requests can route through Apify Proxy (residential IPs by default), and every retry opens a new connection rather than reusing one that just failed. Before parsing, each response is checked against a minimum size and a marker confirming the results table is present, so an interstitial or blocked page is never read as "zero results." Parsing itself is anchored on Goodreads' own labels (avg rating, ratings, published, edition(s)) with BeautifulSoup, rather than fixed HTML positions, so the output field names stay the same even if Goodreads adjusts its markup. Only what's visible on the public search-results page is ever returned.
Integrations
Goodreads Book Scraper runs on Apify, so it works with anything that can call the Apify API or use the apify-client SDK.
Calling Goodreads Book Scraper programmatically
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_API_TOKEN>")run = client.actor("scraper-engine/goodreads-book-scraper").call(run_input={"urls": ["python programming"],"resultsPerQuery": 20,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["title"], item["ratingValue"])
Works in Go, Ruby, Node.js, cURL — any language that can make an HTTP request.
No-code tools (n8n, Make, LangChain)
In n8n, use the Apify node (or an HTTP Request node against the Apify API) to start a run and read back the dataset. In Make, the Apify app's "Run an Actor" module does the same, with the output fed straight into downstream modules. In LangChain or any agent framework, wrap the apify-client call above as a tool so an agent can request fresh Goodreads search results on demand.
Is it legal to scrape Goodreads books?
Scraping publicly available web data, such as Goodreads' public book search results, is generally legal — this is book and publication metadata, not personal data about a private individual. Goodreads Book Scraper only returns what's already visible on a public search-results page. Because the output is business/product-style catalogue data (titles, ratings, edition counts) rather than personal data, GDPR does not apply to it; the relevant considerations instead are Goodreads' own terms of service and database-rights protections that may apply to how the underlying data was compiled. Consult legal counsel if your use case involves bulk storage or redistribution of this data.
Frequently asked questions
What Goodreads book fields does Goodreads Book Scraper return?
The top fields are title, author, ratingValue, ratingsCountValue, and publishedYear — see the full field table above for all 16.
Does Goodreads Book Scraper require a Goodreads account or login?
No. The Actor reads Goodreads' public search pages over plain HTTP and never authenticates — no account, login, or API key is used anywhere in its code.
How many books can I extract in one run?
As many as resultsPerQuery allows per search line (up to 10,000) times the number of lines in urls, capped overall by maxItems if you set one. Each search line also stops after 500 result pages as an internal safety limit, whichever comes first.
What happens if a search returns zero results?
Goodreads Book Scraper stops paging that search line as soon as a page comes back with no book rows, logs it, and moves on to the next line in urls. No row is pushed for that line, and the run continues normally.
Can I scrape multiple Goodreads searches at once?
Yes. urls accepts a list — put each search phrase or search URL on its own line and the Actor works through all of them in one run, applying resultsPerQuery to each and maxItems across the total.
Does Goodreads Book Scraper work with Claude, ChatGPT, and other AI agent tools?
It's callable as a standard HTTP endpoint through the Apify API, so any agent framework that can make an HTTP request — including Claude tool use, LangChain, or a custom agent — can call it and consume the resulting JSON directly.
How does Goodreads Book Scraper compare to other Goodreads book scrapers?
We don't have verified, dated data on other Goodreads scrapers to compare against here. What we can state about this Actor: it returns both the raw text and a parsed numeric value for every rating, ratings-count, publication and edition field, and streams rows to the dataset as each page is read rather than only at the end of the run.
Does Goodreads Book Scraper return data in a format LLMs can use directly?
Yes. Every run returns typed, normalized JSON with consistent field names — no HTML, no selectors to write. Pass it directly to an LLM prompt, index it into a vector store, or feed it to an agent tool.
What happens when Goodreads changes its layout or anti-bot system?
The Actor's parsing is anchored on Goodreads' own labels rather than fixed HTML positions, and the output schema is kept stable across updates. No specific turnaround time for fixes is published or promised.
Can I use Goodreads Book Scraper without managing proxies or browser infrastructure?
Yes for proxies — Apify Proxy routing and connection retries are handled internally; you only need to opt in through proxyConfiguration if you want a specific group or country. ⚠️ Note this Actor makes plain HTTP requests and does not render JavaScript with a browser — it parses the HTML Goodreads' search page returns directly, so there's no browser to manage either way.
Which Goodreads book fields work best for AI training data and RAG indexing?
For RAG context, title, author, and published/publishedYear give the descriptive text an LLM needs to identify a book correctly. For structured training features, ratingValue, ratingsCountValue, and editionsCount are consistently typed numbers across every record, ready to use without further parsing.
Related scrapers
| Scraper name | What it extracts |
|---|---|
| Google Scholar Scraper | Publication and citation data from Google Scholar |
| Udemy Course Reviews Scraper | Course ratings and review text from Udemy |
| Walmart Reviews Scraper | Product reviews and ratings from Walmart listings |
| Airbnb Review Scraper | Guest reviews and ratings for Airbnb listings |
| Google Play Scraper | App listings and ratings from the Google Play Store |
💬 Your feedback
Found a bug, or a Goodreads field this Actor should return but doesn't? Let us know through the Issues tab on the Actor's Apify Store page, or via the Apify Console's built-in support chat. Reports like this keep the parser working as Goodreads' markup changes.