# OpenLibrary Books Scraper — ISBN, Author & Metadata (`haketa/openlibrary-books-scraper`) Actor

Search books by title, author or subject, or look up ISBNs in bulk, and get authors, year, ISBNs, publishers, subjects, languages, ratings, editions, pages and cover. Powered by Open Library. Keyless, no anti-bot.

- **URL**: https://apify.com/haketa/openlibrary-books-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 results

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## OpenLibrary Books Scraper — ISBN, Author & Metadata

Search **books by title, author or subject** — or look up **ISBNs in bulk** — and get rich, structured metadata for each: authors, first publish year, **ISBNs, publishers, subjects, languages, ratings, edition count, page count and cover image**. Powered by Open Library, as clean JSON/CSV/Excel.

**Keyless**, no anti-bot — built for book catalogs, library and bookstore data, reading apps, and metadata enrichment.

***

### What this Actor does

Give it search queries and/or ISBNs, and for every matching book it returns:

- **Core** — title, author(s), first publish year.
- **Identifiers** — primary ISBN and how many ISBNs/editions exist.
- **Publishing** — publishers, languages, edition count, median page count.
- **Discovery** — subjects/genres, average rating and rating count, opening sentence.
- **Media & links** — cover image URL, Open Library work key and page, and whether a free full-text read is available on the Internet Archive.

Search plain text, or target a field with a prefix: `title:`, `author:`, `subject:`.

***

### Why use it

- **Rich, free book metadata.** A clean, structured alternative to paid book APIs and to scraping Goodreads/Amazon — no key, no anti-bot.
- **Bulk ISBN lookup.** Paste a list of ISBNs and get full metadata back for each.
- **Catalog & enrichment.** Build or enrich a book catalog with authors, subjects, ratings, editions and covers.
- **Discovery by subject or author.** Pull every book for an author or a subject to power recommendations, reading lists and research.
- **Covers included.** Ready-to-use cover image URLs for every book.

***

### Who it's for

- **Bookstores, libraries & publishers** building or cleaning catalog data.
- **Reading & book-app developers** needing a free, structured book API.
- **Data & research teams** assembling datasets by author, subject or era.
- **Content & recommendation builders** powering reading lists and discovery.

***

### Quick start

#### Run it in the console (no code)

1. In **Search queries**, add one per line — plain text or with a prefix:

   ```
   the lord of the rings
   author:agatha christie
   subject:machine learning
   ```

2. *(Optional)* In **ISBNs**, paste ISBN-10/13 codes to look up specific books.

3. Set **Max books per query**, click **Start**, export as **JSON, CSV, Excel or HTML**.

Leave everything empty to run a **demo**.

#### Run it via API (Python)

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run_input = {
    "queries": ["author:brandon sanderson", "subject:fantasy"],
    "isbns": ["9780441013593"],
    "maxItemsPerQuery": 100,
}

run = client.actor("YOUR_USERNAME/openlibrary-books-scraper").call(run_input=run_input)

for b in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{b['title']} — {b['authors']} ({b['firstPublishYear']}) ⭐{b['ratingsAverage']}")
```

#### Run it via API (JavaScript)

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

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

const run = await client.actor('YOUR_USERNAME/openlibrary-books-scraper').call({
    queries: ['the lord of the rings'],
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((b) => console.log(`${b.title} — ${b.authors} — ISBN ${b.isbn}`));
```

***

### Input

| Field | Type | Description |
|---|---|---|
| **Search queries** | array | One per line. Plain text or `title:` / `author:` / `subject:` prefixes. Empty = demo. |
| **ISBNs** | array | ISBN-10/13 (hyphens ok) to look up specific books. |
| **Max books per query** | integer | Paginates in blocks of 100. Default 100. |
| **Speed (parallel queries)** | integer | How many queries at once. Default 4. |
| **Proxy configuration** | object | Apify Proxy. On by default. |

#### Query tips

- `title:dune` — match the title.
- `author:ursula k le guin` — all books by an author.
- `subject:artificial intelligence` — all books on a subject.
- Plain text (e.g. `the hobbit`) searches across everything.

***

### Output

One record per book:

```json
{
  "query": "author:agatha christie",
  "title": "Murder on the Orient Express",
  "authors": "Agatha Christie",
  "firstPublishYear": "1933",
  "isbn": "9780007119318",
  "isbnCount": "248",
  "publishers": "HarperCollins; Collins Crime Club; ...",
  "subjects": "Detective and mystery stories; Hercule Poirot; ...",
  "languages": "eng; fre; spa; ...",
  "ratingsAverage": "4.15",
  "ratingsCount": "212",
  "editionCount": "248",
  "pageCount": "256",
  "firstSentence": "The Taurus Express...",
  "coverUrl": "https://covers.openlibrary.org/b/id/12345-L.jpg",
  "workKey": "/works/OL471576W",
  "openLibraryUrl": "https://openlibrary.org/works/OL471576W",
  "hasFreeRead": "true",
  "scrapedAt": "2026-10-08T14:00:00.000Z"
}
```

| Field | Description |
|---|---|
| `title` / `authors` / `firstPublishYear` | Core bibliographic fields. |
| `isbn` / `isbnCount` | Primary ISBN and number of ISBNs/editions. |
| `publishers` / `languages` | Publishers and languages across editions. |
| `subjects` | Subjects/genres (great for classification & discovery). |
| `ratingsAverage` / `ratingsCount` | Open Library community ratings. |
| `editionCount` / `pageCount` | Number of editions and median page count. |
| `firstSentence` | Opening sentence, when available. |
| `coverUrl` | Cover image URL (large). |
| `workKey` / `openLibraryUrl` | Open Library identifiers and page. |
| `hasFreeRead` | `true` if a full-text copy is on the Internet Archive. |
| `scrapedAt` | ISO timestamp. |

***

### Tips & notes

- **Author & subject sweeps.** `author:` and `subject:` are the fastest way to pull a complete set — raise *Max books per query* to go deep.
- **ISBN enrichment.** Feed a column of ISBNs to turn a bare list into a full catalog with covers and subjects.
- **Ratings vary.** Open Library ratings are community-sourced; popular titles have them, obscure ones may not.
- **Covers.** `coverUrl` is a ready `-L` (large) image; swap `-L` for `-M`/`-S` for smaller sizes.
- **Be kind.** Open Library is a non-profit — keep concurrency modest for large jobs.

***

### Frequently asked questions

**Do I need an API key?**
No. It uses Open Library's public search API — no key, no account.

**Can I look up specific ISBNs?**
Yes — paste them into the **ISBNs** field and each is resolved to full metadata.

**How do I get all books by an author or on a subject?**
Use `author:name` or `subject:topic` as a query and raise *Max books per query*.

**Are cover images included?**
Yes — every book with a cover gets a ready-to-use `coverUrl`.

**Is this a good alternative to Goodreads/Amazon book data?**
Yes — Open Library is open, keyless and anti-bot-free, with authors, subjects, editions, ratings and covers for millions of books.

**Can I tell if a book is free to read?**
`hasFreeRead` is `true` when a full-text copy is available on the Internet Archive.

***

### Export & integrate

Results are available as **JSON, CSV, Excel, HTML** and via the **Apify API**. Push to **Google Sheets**, a **webhook**, **Make**, **Zapier** or your database — and **schedule** runs to keep a catalog fresh.

*Data from Open Library, a project of the Internet Archive.*

# Actor input Schema

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

One search per line. Plain text searches everything, or use prefixes: `title:dune`, `author:tolkien`, `subject:fantasy`. Examples: `the lord of the rings`, `author:brandon sanderson`, `subject:machine learning`. Leave empty for a demo.

## `isbns` (type: `array`):

One ISBN per line (ISBN-10 or ISBN-13, hyphens ok) to look up specific books directly.

## `maxItemsPerQuery` (type: `integer`):

How many books to return per query (paginates in blocks of 100).

## `maxConcurrency` (type: `integer`):

How many queries to run at once. Open Library is community-run — keep this modest.

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

Apify Proxy. On by default — the API is public, but rotation keeps large runs smooth.

## Actor input object example

```json
{
  "queries": [
    "the lord of the rings",
    "author:agatha christie"
  ],
  "isbns": [],
  "maxItemsPerQuery": 100,
  "maxConcurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `query` (type: `string`):

Search or ISBN

## `title` (type: `string`):

Book title

## `authors` (type: `string`):

Author(s)

## `firstPublishYear` (type: `string`):

First publish year

## `isbn` (type: `string`):

Primary ISBN

## `isbnCount` (type: `string`):

Number of ISBNs/editions

## `publishers` (type: `string`):

Publishers

## `subjects` (type: `string`):

Subjects/genres

## `languages` (type: `string`):

Languages

## `ratingsAverage` (type: `string`):

Average rating

## `ratingsCount` (type: `string`):

Rating count

## `editionCount` (type: `string`):

Edition count

## `pageCount` (type: `string`):

Median page count

## `firstSentence` (type: `string`):

Opening sentence

## `coverUrl` (type: `string`):

Cover image URL

## `workKey` (type: `string`):

Open Library work key

## `openLibraryUrl` (type: `string`):

Open Library page

## `hasFreeRead` (type: `string`):

Available on Internet Archive

## `scrapedAt` (type: `string`):

Timestamp

# 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 = {
    "queries": [
        "the lord of the rings",
        "author:agatha christie"
    ],
    "isbns": [],
    "maxItemsPerQuery": 100,
    "maxConcurrency": 4
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/openlibrary-books-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 = {
    "queries": [
        "the lord of the rings",
        "author:agatha christie",
    ],
    "isbns": [],
    "maxItemsPerQuery": 100,
    "maxConcurrency": 4,
}

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

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

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

```

## CLI example

```bash
echo '{
  "queries": [
    "the lord of the rings",
    "author:agatha christie"
  ],
  "isbns": [],
  "maxItemsPerQuery": 100,
  "maxConcurrency": 4
}' |
apify call haketa/openlibrary-books-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,haketa/openlibrary-books-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/zIaf17dm26AjtlHXC/builds/NGPX9WMuqM12P3wjZ/openapi.json
