# Goodreads Books & Reviews Scraper (`fetch_cat/goodreads-books-reviews-scraper`) Actor

Extract public Goodreads book metadata, ratings, and reader reviews from book URLs or search queries for research and book marketing workflows.

- **URL**: https://apify.com/fetch\_cat/goodreads-books-reviews-scraper.md
- **Developed by:** [Hanna Nosova](https://apify.com/fetch_cat) (community)
- **Categories:** Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.60 / 1,000 book or review items

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Goodreads Books & Reviews Scraper

Extract public Goodreads book metadata, aggregate ratings, and reader reviews from Goodreads book URLs or search queries.

### What does Goodreads Books & Reviews Scraper do?

Goodreads Books & Reviews Scraper collects structured data from public Goodreads book pages.

It can save book metadata rows and public review rows in the same dataset.

Use it when you need book-market signals without manually copying Goodreads pages.

### Who is it for?

📚 Publishers can monitor reader reaction to backlist and frontlist titles.

✍️ Authors can analyze public review themes around comparable books.

🏫 Libraries can enrich catalog analysis with ratings and public reader feedback.

📈 Market researchers can compare reader sentiment across genres and authors.

🛒 Book marketers can build review exports for campaign planning.

### Why use this Goodreads scraper?

It accepts direct Goodreads book URLs for precise targeting.

It also accepts search queries and resolves matching public book pages.

It returns clean fields such as title, authors, ratings, review counts, reviewer names, review text, and visible engagement counts.

It is designed with low default limits so first test runs stay inexpensive.

### What Goodreads data can you extract?

| Category | Example fields |
| --- | --- |
| Book identity | `bookId`, `bookUrl`, `title` |
| Author data | `authors`, `authorUrls` |
| Metadata | `description`, `genres`, `coverUrl`, `bookFormat`, `numberOfPages`, `inLanguage` |
| Ratings | `averageRating`, `ratingsCount`, `reviewsCount` |
| Reviews | `reviewId`, `reviewUrl`, `reviewerName`, `reviewerUrl`, `rating`, `reviewText` |
| Engagement | `likesCount`, `commentsCount` |

### How much does it cost to scrape Goodreads books and reviews?

This actor uses pay-per-event pricing.

There is a small start event per run.

Each saved book metadata row or review row is charged as one item.

With the default input, the run is intentionally small: one book plus a limited number of reviews.

Increase `maxReviewsPerBook` only after confirming the output matches your needs.

### Quick start

1. Open the actor on Apify.

2. Add one or more Goodreads book URLs.

3. Optionally add search queries such as `the great gatsby`.

4. Choose whether to include reviews.

5. Set `maxReviewsPerBook`.

6. Run the actor.

7. Download the dataset as JSON, CSV, Excel, or through the API.

### Input: Goodreads book URLs

Use `bookUrls` when you already know the exact Goodreads pages.

Example:

```json
{
  "bookUrls": [
    { "url": "https://www.goodreads.com/book/show/41733839-the-great-gatsby" }
  ],
  "includeReviews": true,
  "maxReviewsPerBook": 10
}
````

### Input: search queries

Use `queries` when you want the actor to find matching public Goodreads books first.

Example:

```json
{
  "queries": ["the great gatsby"],
  "includeReviews": true,
  "maxReviewsPerBook": 5
}
```

### Input options

| Field | Type | Description |
| --- | --- | --- |
| `bookUrls` | array | Goodreads book pages to scrape |
| `queries` | array | Goodreads book searches to resolve |
| `includeReviews` | boolean | Save public review rows |
| `maxReviewsPerBook` | integer | Review cap per book page |
| `proxyConfiguration` | object | Optional Apify Proxy settings |

### Output example

```json
{
  "itemType": "book",
  "bookId": "41733839",
  "bookUrl": "https://www.goodreads.com/book/show/41733839-the-great-gatsby",
  "title": "The Great Gatsby",
  "authors": ["F. Scott Fitzgerald"],
  "averageRating": 3.93,
  "ratingsCount": 6067294,
  "reviewsCount": 136391
}
```

### Review output example

```json
{
  "itemType": "review",
  "bookId": "41733839",
  "bookTitle": "The Great Gatsby",
  "reviewerName": "Nataliya",
  "rating": 5,
  "reviewText": "Public review text visible on Goodreads..."
}
```

### Tips for better results

Use direct Goodreads book URLs when accuracy matters most.

Keep `maxReviewsPerBook` low while testing.

Run several smaller jobs instead of one very large exploratory job.

Use query mode for discovery, then re-run with selected direct URLs.

Disable reviews when you only need metadata and aggregate ratings.

### Integrations

Send exported Goodreads review data to Google Sheets for editorial review.

Load CSV exports into Airtable to tag books by genre, rating, and sentiment.

Push JSON results into a warehouse for trend dashboards.

Connect the actor to Make or Zapier through Apify webhooks.

Use Apify API clients to schedule recurring monitoring of selected titles.

### API usage with Node.js

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/goodreads-books-reviews-scraper').call({
  bookUrls: [{ url: 'https://www.goodreads.com/book/show/41733839-the-great-gatsby' }],
  includeReviews: true,
  maxReviewsPerBook: 5,
});
console.log(run.defaultDatasetId);
```

### API usage with Python

```python
from apify_client import ApifyClient
import os

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('fetch_cat/goodreads-books-reviews-scraper').call(run_input={
    'queries': ['the great gatsby'],
    'includeReviews': True,
    'maxReviewsPerBook': 5,
})
print(run['defaultDatasetId'])
```

### API usage with cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/fetch_cat~goodreads-books-reviews-scraper/runs?token=APIFY_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"queries":["the great gatsby"],"includeReviews":true,"maxReviewsPerBook":5}'
```

### MCP usage

Use this actor from Claude Desktop or Claude Code through the Apify MCP server.

MCP URL pattern:

```text
https://mcp.apify.com/?tools=fetch_cat/goodreads-books-reviews-scraper
```

Claude Code setup:

```bash
claude mcp add apify-goodreads-books-reviews --url "https://mcp.apify.com/?tools=fetch_cat/goodreads-books-reviews-scraper"
```

Claude Desktop JSON config:

```json
{
  "mcpServers": {
    "apify-goodreads-books-reviews": {
      "url": "https://mcp.apify.com/?tools=fetch_cat/goodreads-books-reviews-scraper"
    }
  }
}
```

Example prompt:

```text
Run the Goodreads Books & Reviews Scraper for The Great Gatsby and summarize recurring reader complaints from the first 20 reviews.
```

### Data quality notes

Goodreads page layouts can vary by book.

Some fields may be null when Goodreads does not show them publicly.

Review dates and engagement counts are saved only when visible on the public page.

Search queries may return several matching editions.

### Legality and ethical use

This actor extracts publicly available Goodreads pages.

You are responsible for using the results in line with applicable laws, Goodreads terms, and privacy rules.

Do not use scraped data for spam, harassment, or invasive profiling.

Respect reasonable limits and avoid unnecessary high-volume runs.

### Troubleshooting: no results

Check that the Goodreads URL is public and starts with `/book/show/`.

Try a direct book URL instead of a broad query.

Lower the review cap and run again.

If your network is blocked, enable Apify Proxy in the input.

### Troubleshooting: missing reviews

Some books show fewer public review cards than their aggregate review count.

Goodreads may personalize, paginate, or hide parts of the review list.

The actor saves public review cards visible in the fetched page.

### FAQ

#### Can I scrape private Goodreads shelves?

No. This actor is for public book pages and public review content only.

#### Can I scrape every review for a popular book?

The first version focuses on visible public review cards with a per-book cap. Use reasonable caps for cost control.

#### Can I search by ISBN?

If Goodreads autocomplete resolves the ISBN query to a public book page, the actor can scrape that page.

#### Does it require a Goodreads account?

No account is required for the public data targeted by this actor.

### Related scrapers

Explore other Apify actors from our catalog for book, review, and web data workflows.

Use actor combinations to enrich Goodreads exports with website metadata, sentiment scoring, or notification workflows.

### Changelog

Initial version: direct Goodreads book URL scraping, query resolution, book metadata rows, and public review rows.

### Support

If a run does not produce the expected public book data, share the run URL and the input so we can investigate.

# Actor input Schema

## `bookUrls` (type: `array`):

Public Goodreads book pages to scrape. Add one or more /book/show/ URLs.

## `queries` (type: `array`):

Optional Goodreads book searches. The actor uses Goodreads autocomplete and scrapes the top public book pages for each query.

## `includeReviews` (type: `boolean`):

Save public reader reviews visible on the book page in addition to the book metadata row.

## `maxReviewsPerBook` (type: `integer`):

Maximum number of public reviews to save from each book page.

## `proxyConfiguration` (type: `object`):

Optional Apify Proxy settings. Start without proxies; enable Apify Proxy only if Goodreads blocks your network.

## Actor input object example

```json
{
  "bookUrls": [
    {
      "url": "https://www.goodreads.com/book/show/41733839-the-great-gatsby"
    }
  ],
  "queries": [
    "the great gatsby"
  ],
  "includeReviews": true,
  "maxReviewsPerBook": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "bookUrls": [
        {
            "url": "https://www.goodreads.com/book/show/41733839-the-great-gatsby"
        }
    ],
    "queries": [
        "the great gatsby"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fetch_cat/goodreads-books-reviews-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "bookUrls": [{ "url": "https://www.goodreads.com/book/show/41733839-the-great-gatsby" }],
    "queries": ["the great gatsby"],
}

# Run the Actor and wait for it to finish
run = client.actor("fetch_cat/goodreads-books-reviews-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "bookUrls": [
    {
      "url": "https://www.goodreads.com/book/show/41733839-the-great-gatsby"
    }
  ],
  "queries": [
    "the great gatsby"
  ]
}' |
apify call fetch_cat/goodreads-books-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=fetch_cat/goodreads-books-reviews-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Goodreads Books & Reviews Scraper",
        "description": "Extract public Goodreads book metadata, ratings, and reader reviews from book URLs or search queries for research and book marketing workflows.",
        "version": "0.1",
        "x-build-id": "6x29WMNnIIlFUYL2q"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/fetch_cat~goodreads-books-reviews-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-fetch_cat-goodreads-books-reviews-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/fetch_cat~goodreads-books-reviews-scraper/runs": {
            "post": {
                "operationId": "runs-sync-fetch_cat-goodreads-books-reviews-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/fetch_cat~goodreads-books-reviews-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-fetch_cat-goodreads-books-reviews-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "bookUrls": {
                        "title": "Goodreads book URLs",
                        "type": "array",
                        "description": "Public Goodreads book pages to scrape. Add one or more /book/show/ URLs.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "queries": {
                        "title": "Search queries",
                        "type": "array",
                        "description": "Optional Goodreads book searches. The actor uses Goodreads autocomplete and scrapes the top public book pages for each query.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "includeReviews": {
                        "title": "Include reviews",
                        "type": "boolean",
                        "description": "Save public reader reviews visible on the book page in addition to the book metadata row.",
                        "default": true
                    },
                    "maxReviewsPerBook": {
                        "title": "Maximum reviews per book",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Maximum number of public reviews to save from each book page.",
                        "default": 10
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Optional Apify Proxy settings. Start without proxies; enable Apify Proxy only if Goodreads blocks your network.",
                        "default": {
                            "useApifyProxy": false
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
