Goodreads Book Scraper
Pricing
from $2.00 / 1,000 results
Goodreads Book Scraper
Extract book data from Goodreads: title, author, rating, review count, genres, pages, publication date, ISBN, description. Search by keyword, browse by genre, or scrape list URLs. Perfect for publishing research, book recommendation engines.
Pricing
from $2.00 / 1,000 results
Rating
0.0
(0)
Developer
cloud9
Maintained by CommunityActor stats
0
Bookmarked
9
Total users
0
Monthly active users
a day ago
Last modified
Categories
Share
Extract book data from Goodreads: title, author, rating, review count, genres, pages, publication date, ISBN, description. Search by keyword, browse by genre, or scrape list URLs. Perfect for publishing research, book recommendation engines.
reviewsCount,genres,isbn,pageCount,publishDateanddescriptionare only filled in when you setenrichWithDetails: true, which fetches each book's own page (slower, and one extra request per book). Search results alone carry title, author, rating, ratings count, cover image and URL.
Use cases
- Research a genre's rating and review distribution before publishing
- Build a book recommendation dataset
- Track competitor titles' rating and review growth
- Source metadata for a reading-list or catalogue app
- Analyse what makes bestsellers in a category
Input
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
searchUrl | string | No | — | Custom Goodreads URL to scrape (overrides other parameters) |
query | string | No | "fiction" | Search term to find books on Goodreads |
genre | string | No | — | Browse books by genre slug (e.g., 'fiction', 'mystery', 'romance') |
listUrl | string | No | — | Goodreads list URL to scrape (e.g., https://www.goodreads.com/list/show/1.Best_Books_Ever) |
maxResults | integer | No | 20 | Maximum number of books to scrape |
enrichWithDetails | boolean | No | false | Fetch each book's detail page for extra data (genres, ISBN, description, page count). Slower but provides richer data. |
Example input
{"query": "fiction","maxResults": 20,"enrichWithDetails": false}
Output
Each dataset item looks like this — real output from an actual run of this Actor:
{"title": "Never Whistle at Night: An Indigenous Dark Fiction Anthology (Never Whistle at Night, #1)","author": "Shane Hawk","rating": 3.83,"ratingsCount": 35340,"reviewsCount": null,"description": "","pageCount": null,"publishDate": null,"isbn": null,"genres": [],"imageUrl": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1685990593i/75293507._SX300_.jpg","goodreadsUrl": "https://www.goodreads.com/book/show/75293507-never-whistle-at-night","series": "Never Whistle at Night","seriesNumber": 1}
| Field | Type |
|---|---|
title | string |
author | string |
rating | number |
ratingsCount | number |
reviewsCount | null |
description | string |
pageCount | null |
publishDate | null |
isbn | null |
genres | array |
imageUrl | string |
goodreadsUrl | string |
series | string |
seriesNumber | number |
The dataset also ships a preset table view (Books), so the key columns are readable straight away in Apify Console, and exportable to JSON, CSV, Excel, or XML.
How to run it
In Apify Console — open the Actor, fill in the input form, click Start, then download the results from the Dataset tab.
With the JavaScript client
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });const run = await client.actor('cloud9_ai/goodreads-book-scraper').call({"query": "fiction","maxResults": 20,"enrichWithDetails": false});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
With the Python client
from apify_client import ApifyClientclient = ApifyClient('YOUR_APIFY_TOKEN')run = client.actor('cloud9_ai/goodreads-book-scraper').call(run_input={"query": "fiction","maxResults": 20,"enrichWithDetails": False})for item in client.dataset(run['defaultDatasetId']).iterate_items():print(item)
With the API — POST https://api.apify.com/v2/acts/cloud9_ai~goodreads-book-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN with the input JSON as the body.
Notes and limits
- No API key, account, or login is needed — just the input above.
maxResultscaps how much a single run collects, which is also what caps the run's cost.- Requests are paced and failed requests are retried automatically, so runs stay inside the source's rate limits.
- Only publicly available data is collected. How you use the output is your responsibility, including the source's terms of use and any applicable data-protection law.
Support
Found a bug, or need a field that isn't in the output? Open an issue on the Issues tab of this Actor in Apify Console. Issues there are read and answered.
License
Apache-2.0