Skip to content

September 24, 2026 · 14 min read

Goodreads Book Scraper: 846 of 903 Runs Succeeded (2026)

By Crawlerbros Engineering Team

Each book record carries 18 fields, including the title, ISBN, publisher, and average rating. A thousand results cost $2.00 on the free plan, which covers metadata for local catalogs or recommendation engines. The scraper provides 9 modes for looking up books by ISBN, for author pages, or for Listopia lists. It is designed for researchers building bibliographic databases or reading apps. It does not return individual review text or user-specific shelves, so those needing qualitative sentiment analysis or private user data should look elsewhere.

Try it before you read further. Apify's free plan includes $5.00 of usage every month with no credit card, enough for up to 2,500 results at $0.002 each before platform usage. Open Goodreads Book Scraper on Apify and run the prefilled example.

How reliable is Goodreads Book Scraper in production?

Across the last 30 days of public runs on the Apify platform, Goodreads Book Scraper recorded 903 runs with the following outcomes.

Outcome Runs Share
Succeeded 846 93.7%
Failed 22 2.4%
Aborted by the user 2 0.2%
Timed out 33 3.7%
Total 903 100.0%

In the last 30 days, 6.1% of runs failed or timed out, which means about 6 in a hundred runs may require attention. You should build retries or alerting around scheduled tasks to handle these instances. Aborted runs were stopped by the user and do not impact the measured reliability of the collector.

What does it cost to run Goodreads Book Scraper?

Each result costs $0.002 on Apify's free plan, which is $2.00 per 1,000 results. Starting a run is charged separately at $0.005 per GB of Actor memory. Apify also bills the platform usage each run consumes, at the rates of your Apify plan, on top of these charges.

Apify plan Per result Per 1,000 results
FREE $0.002 $2.00
BRONZE $0.00167 $1.67
SILVER $0.00133 $1.33
GOLD $0.001 $1.00
PLATINUM $0.001 $1.00
DIAMOND $0.001 $1.00

Worked example: collecting 10,000 results costs $20.00 in result charges before run-start fees and platform usage. With 6.1% of runs failing or timing out in the last 30 days, budget for re-running a portion of those batches rather than assuming every run completes.

The maxItems control has the largest effect on the bill because result charges apply to each record written to the dataset. To find out if the output fits your needs, use the example input which caps results at 5 and costs at most $0.01 in result charges.

How do you run Goodreads Book Scraper from the API?

The schema marks 1 of its 20 controls as required: mode. Nothing in the payload below is illustrative. Those are the schema's prefilled defaults for Goodreads Book Scraper, so the request works once your token is in place.

Call the synchronous endpoint to start a run and receive dataset items in one request:

curl -X POST "https://api.apify.com/v2/acts/crawlerbros~goodreads-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"auto","bookUrls":["https://www.goodreads.com/book/show/4671.The_Great_Gatsby"],"searchQueries":["sapiens"],"maxItems":5}'

The same run from Python, using the official client:

from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")

run_input = {
  "mode": "auto",
  "bookUrls": [
    "https://www.goodreads.com/book/show/4671.The_Great_Gatsby"
  ],
  "searchQueries": [
    "sapiens"
  ],
  "maxItems": 5
}

run = client.actor("crawlerbros~goodreads-scraper").call(run_input=run_input)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

And from Node.js:

import { ApifyClient } from 'apify-client'

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' })

const input = {
  "mode": "auto",
  "bookUrls": [
    "https://www.goodreads.com/book/show/4671.The_Great_Gatsby"
  ],
  "searchQueries": [
    "sapiens"
  ],
  "maxItems": 5
}

const run = await client.actor('crawlerbros~goodreads-scraper').call(input)
const { items } = await client.dataset(run.defaultDatasetId).listItems()
console.log(items)

Because the call is synchronous, your client waits for the whole run. Keep it for exploration. For scheduled work, start the run without waiting and collect the dataset afterwards, so network trouble costs you a retry rather than the results.

Which Goodreads Book Scraper inputs matter, and which can you skip?

The mode control determines which input arrays, such as isbns or searchQueries, the scraper will process. Goodreads is accessible from datacenter IPs without a proxy; only enable proxyConfiguration if you hit sustained 429s.

  • mode (string): What to scrape. Use 'auto' (default) to run any non-empty inputs you provide. Or pick a specific mode to run only that one. Default: "auto".
  • bookUrls (array): Direct Goodreads book URLs. (mode=auto, books) Default: [].
  • searchQueries (array): Free-text search terms (titles, authors, keywords). (mode=auto, search) Default: [].
  • maxItems (integer): Hard cap on total records emitted across all inputs. Books, search results, and listing-page results all count toward this. Default: 50.
  • isbns (array): ISBN-10 or ISBN-13 codes. Goodreads' search redirects ISBN queries to the matching book. (mode=auto, isbns) Default: [].
  • authorUrls (array): Goodreads author URLs (e.g. https://www.goodreads.com/author/show/1077326). The actor walks /author/list/?page=N for all books. (mode=auto, authors) Default: [].
  • seriesUrls (array): Goodreads series URLs (e.g. https://www.goodreads.com/series/49075-harry-potter). All books in the series are scraped. (mode=auto, series) Default: [].
  • listUrls (array): Goodreads /list/show/ URLs (e.g. Best Books Ever). Paginated. (mode=auto, lists) Default: [].
  • shelfNames (array): Popular shelf names like 'mystery', 'fantasy', 'historical-fiction'. Paginated. (mode=auto, shelves) Default: [].
  • genreNames (array): Genre names like 'fiction', 'romance', 'mystery'. (mode=auto, genres) Default: [].
  • minRating (integer): Drop books with averageRating below this integer threshold (0-5). For finer thresholds (e.g. 4.5), use a higher minRatingsCount filter to surface highly-rated books.
  • minRatingsCount (integer): Drop books with fewer than N ratings.

The other 8 controls, with their defaults, are listed in the input schema on Goodreads Book Scraper on Apify.

Fixed-choice controls: mode accepts 9 values (default auto), including auto (run all non-empty inputs), books (Book URLs (direct /book/show/ links)), search (Search queries (text)), isbns (ISBN lookup (ISBN-10 or ISBN-13)).

What does Goodreads Book Scraper return?

The returned records contain rich book metadata suitable for library systems or for tracking publication years across a book series. They do not contain individual user review comments or data from award pages.

Book record (recordType: "book")

  • title: Book title
  • url: Goodreads book URL
  • bookId: Goodreads numeric book ID
  • authors[]: Author names
  • primaryAuthor: First author
  • authorUrls[]: Goodreads author profile URLs
  • description: Plain-text description (HTML stripped)
  • isbn, isbn10, isbn13: ISBN identifiers (when known)
  • averageRating: Average rating, 0-5
  • ratingsCount: Total number of ratings
  • reviewsCount: Total number of text reviews
  • pagesCount: Page count
  • publishedYear: Year of original publication
  • publisher: Publisher name
  • language: Language (varies - sometimes ISO code, sometimes name)
  • format: Paperback, Hardcover, Kindle, etc.
  • genres[]: List of genre tags
  • coverImage: Cover image URL on Goodreads CDN

Author record (recordType: "author", only when includeMetadata: true)

  • authorId, authorUrl: Goodreads identifiers
  • photoUrl: Author photo on Goodreads CDN
  • description: "About the author" text
  • born, died: Birth/death info (when public)
  • genres[]: Top author genres
  • website: External author website (when listed)

Series record (recordType: "series", only when includeMetadata: true)

  • seriesId, seriesUrl: Goodreads identifiers
  • description: Series description
  • primaryAuthor: First author of the series
  • bookCount: Number of books in the series page

List record (recordType: "list", only when includeMetadata: true)

  • listId, listUrl: Goodreads identifiers
  • description: List description
  • bookCount: Total books in the list
  • voterCount: Total voters

These are the documented fields. Optional ones can be empty on a given record, so measure how often each field your deliverable depends on is populated across a real sample before automating the handoff.

How do you build the workflow end to end?

Open Goodreads Book Scraper and work through these in order. Each step ends with something to check, so a bad configuration surfaces on a small run rather than a scheduled one.

  1. Set the mode to isbns or search and provide identifiers or text queries to define the search space.
  2. Configure maxItems to set a hard cap on results, as result charges are billed per record written to the dataset.
  3. Apply minRating or publishYearMin filters to restrict the dataset to books that meet specific quality or chronological criteria.
  4. Enable includeMetadata if you require a dedicated author or series summary record alongside the individual book items.
  5. Inspect the recordType field in the first few records to distinguish between author, series, list, and book objects.
  6. Check that isbn13 or isbn10 are present in the output for book records where global identifiers are required for your library system.
  7. Monitor the scrapedAt timestamp in the dataset to ensure the run is capturing fresh data from the public Goodreads pages.
  8. Download the final dataset in CSV or JSON format once the run status reaches the SUCCEEDED state.

How do you apply it? Three worked playbooks

These are Goodreads Book Scraper's own documented use cases, each worked through as an operating pattern rather than a description.

Use case 1: Library systems

Outcome: Bulk-import metadata from Goodreads by ISBN.

Configure: mode: "isbns", isbns: ["9780743273565", "0747532699"], maxItems: 100

Working method: Input a list of identifiers in the isbns array and use the isbns mode to trigger direct redirects to book pages.

Deliverable: A collection of book records containing title, primaryAuthor, publisher, and ISBN-13 identifiers.

Stop condition: The run fails to return a book record for a valid ISBN input.

Use case 2: Reading recommendation

Outcome: Feed Goodreads genre + rating data into your recommender.

Configure: mode: "genres", genreNames: ["mystery", "fantasy"], minRating: 4

Working method: Provide genre names and set the minRating filter to extract highly-rated books for recommendation engine training.

Deliverable: A dataset of highly-rated book records including genres, averageRating, and ratingsCount.

Stop condition: The dataset contains books with an averageRating below the specified integer threshold.

Use case 3: Series tracking

Outcome: Pull all books in a series with publication years and ratings.

Configure: mode: "series", seriesUrls: ["https://www.goodreads.com/series/49075-harry-potter"], includeMetadata: true

Working method: Input a series URL and enable metadata records to capture the overall series description before the individual book list.

Deliverable: A chronological list of books in a series with recordType markers for the series summary and individual titles.

Stop condition: The scraper returns book records but fails to emit the requested series metadata record.

What breaks, and how do you design around it?

  • Over the last 30 days, 2.4% of public runs failed and 3.7% timed out. Build retries and alerting around those rates rather than assuming every run completes.

When you hit the ~50 book cap in shelves mode, switch to the lists mode for deeper pagination. If you require review text, you must wait for future updates as individual review text is not captured; it is planned for v2.

When should you not use Goodreads Book Scraper?

Do not use this Actor if your project requires the full text of individual reader reviews, as individual review text is not captured, only the total reviewsCount. If you need to scrape rare or antiquarian book listings with specific seller condition details, use AbeBooks Scraper instead. For projects requiring reader-tagged mood data and content warnings, Hardcover Book Data Scraper is the better choice for those specific metadata points. If you are specifically tracking used book marketplace prices and availability across different sellers, ThriftBooks Scraper provides more direct inventory data than Goodreads.

What should you check before trusting the output?

  • Verify that averageRating is a number between 0 and 5 for every book record type.
  • Confirm that primaryAuthor is present and matches the expected contributor for the provided book URLs.
  • Check that isbn13 contains only digits after the scraper normalizes hyphens and spaces from the input.
  • Validate that recordType is author when includeMetadata is enabled and an author profile URL was provided.
  • Stop the run if the bookCount field in a series metadata record differs significantly from the number of book items returned.
  • Alert if more than 10 percent of items are missing the description field for a known popular genre.

None of this proves a record is correct. It gives a scheduled Goodreads Book Scraper run defined points where it should stop instead of quietly passing bad data downstream.

Frequently asked questions

What is the cost for 1,000 results on the free plan?

On Apify's free plan, 1,000 results cost $2.00. This is the free-plan price, and paid plans pay less per result. Note that there is also a run-start fee charged every time a run starts. Total billing also includes platform usage consumed by the run, though per-result charges only apply to items written to the dataset.

How often do runs fail or time out?

Based on 903 runs in the last 30 days, 6.1% of runs failed or timed out, which is about 6 in a hundred. This success rate of 93.7% is high, but practitioners should still monitor large batches. If you encounter errors, consider splitting large inputs into smaller, more manageable runs.

Can I look up books using ISBN-13?

Yes, the isbns mode accepts both ISBN-10 and ISBN-13 strings. The scraper handles hyphens and spaces in your input by stripping non-alphanumeric characters automatically. Since Goodreads redirects ISBN queries directly to the matching book, this is an efficient way to get metadata for specific editions without extra navigation.

Why do some cover image URLs return a 404?

Goodreads sometimes references book covers that are no longer available on their CDN, which is a known issue for old or rare books. The Actor returns the exact coverImage URL published by the site. It cannot ensure that the external host still serves the file at the time you access it.

Do I need to use a proxy for Goodreads?

No, Goodreads is reachable from datacenter IPs without a proxy. The default configuration has proxy usage disabled. You should only enable the proxyConfiguration if you hit sustained 429 rate-limit errors, but for most standard runs, the built-in polite delays and retry layer are sufficient.

Where to go next

When you are ready to run it, open Goodreads Book Scraper on Apify; the free plan covers up to 2,500 results a month.

Start with the Goodreads Book Scraper Actor page for the current input schema, pricing tier, and run history.

If you are comparing approaches rather than committing to one Actor, these category pages list every option we publish:

Readers running Goodreads Book Scraper commonly pair it with:

Related guides:

Resources

  • Actor documentation, input schema, and pricing: verified against the published Actor on 2026-09-24.

  • Actor last updated by its maintainers on 2026-05-06.

  • Run outcome figures cover the 30 day public window ending 2026-09-24.

  • Goodreads Book Scraper on Apify

● Featured actors

Goodreads Book Scraper

Extract book data from Goodreads: titles, authors, ratings, reviews, genres, ISBN, publisher, and more. HTTP-based, no proxy required.

Run on Apify ↗