# AbeBooks Book Listings Scraper (`automation-lab/abebooks-book-search-listings`) Actor

Search AbeBooks by title, author, ISBN, keyword, or URL and export offer-level book, condition, seller, price, shipping, availability, and listing data.

- **URL**: https://apify.com/automation-lab/abebooks-book-search-listings.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.08 / 1,000 book listing extracteds

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

## AbeBooks Book Listings Scraper

Search public **AbeBooks book listings** and export structured offer data for rare-book sourcing, used-book comparison, and recurring inventory checks.

The Actor searches by keyword, title, author, ISBN, or a public AbeBooks search URL. Each result represents one seller offer—not just a generic book edition—so price, shipping, condition, seller, quantity, and listing URL stay together.

### What does this AbeBooks scraper do?

AbeBooks Book Listings Scraper turns public search result pages into integration-ready dataset rows.

Use it to:

- compare offers for one ISBN;
- find books by title or author;
- source signed copies and first editions;
- filter by condition, binding, year, and price;
- capture item price and shipping separately;
- monitor seller offers with scheduled Actor runs;
- export results to CSV, Excel, JSON, or an API pipeline.

The Actor uses AbeBooks' public US storefront. It does not log in, add books to a basket, contact sellers, or place orders.

### Who is it for?

#### Rare-book dealers

Collect comparable offers with condition descriptions, edition clues, seller identity, and delivered-cost components.

#### Collectors and researchers

Find copies for a title, author, ISBN, signed-book search, or first-edition search without manually copying result cards.

#### Resale and sourcing teams

Schedule repeatable searches and compare current public inventory in spreadsheets or databases.

#### Catalog and pricing analysts

Join ISBN, publisher, publication year, condition, seller, item price, and shipping into a consistent record.

### Why use this Actor?

- **Offer-level output:** one row maps to one AbeBooks seller listing.
- **Several search modes:** keyword, title, author, ISBN, and public search URLs.
- **Collectible filters:** signed, first edition, dust jacket, condition, and binding.
- **Transparent costs:** item price and shipping are separate numeric fields when available.
- **Bounded extraction:** `maxItems` and `maxPagesPerSearch` prevent accidental open-ended runs.
- **Typed results:** dataset fields are ready for spreadsheets, code, and database ingestion.
- **No browser overhead:** public server-rendered search results are fetched directly.

### What data can you extract?

| Field | Meaning |
| --- | --- |
| `listingId` | Stable AbeBooks offer identifier |
| `title` | Seller's listing title |
| `author` | Author or contributor byline |
| `isbn10`, `isbn13` | ISBN values when shown |
| `publisher` | Publisher shown on the result card |
| `publishYear` | Publication year when shown |
| `language` | Listing language |
| `binding` | Binding inferred from the description |
| `edition` | Edition statement when present |
| `condition` | AbeBooks condition label |
| `conditionDescription` | Seller-supplied copy description |
| `sellerName` | Public bookseller name |
| `sellerLocation` | Public seller location |
| `sellerRating` | Seller star rating when shown |
| `price` | Item price, excluding separate shipping |
| `currency` | ISO currency code for the displayed price |
| `shippingPrice` | Shipping amount, or `0` when marked free |
| `shippingText` | Shipping label shown by AbeBooks |
| `availability` | Derived offer availability |
| `quantityAvailable` | Number of copies when displayed |
| `imageUrl` | Public cover or seller image |
| `listingUrl` | Canonical AbeBooks offer URL |
| `sellerUrl` | Public AbeBooks seller page |
| `searchUrl` | Search page where the offer was found |
| `position` | One-based position on that result page |
| `scrapedAt` | UTC extraction timestamp |

Optional fields are omitted when AbeBooks or the seller does not expose them on the search card.

### How to get started

1. Open the Actor in Apify Console.
2. Add one or more objects under **Book searches**.
3. Enter a keyword, title, author, ISBN, or a supported AbeBooks search URL.
4. Choose any shared filters.
5. Set the maximum listings and pages.
6. Click **Start**.
7. Open the default dataset to preview or export results.

A practical first run is:

```json
{
  "searches": [{ "isbn": "9780441172719" }],
  "condition": "used",
  "sortBy": "lowest-price",
  "maxItems": 20,
  "maxPagesPerSearch": 1
}
```

### Input parameters

#### `searches`

An array of search objects. A row can contain:

- `keyword` for words anywhere in the listing;
- `title` for title words;
- `author` for an author name;
- `isbn` for an ISBN-10 or ISBN-13.

Combine fields in one object to narrow a search. Add separate objects to run several searches in one task.

#### `startUrls`

Optional public `https://www.abebooks.com/servlet/SearchResults...` or `/book-search/...` URLs.

The Actor rejects other hosts and non-search paths. Shared filters apply to start URLs as well as generated searches.

#### Offer filters

- `condition`: any, new, used, fine, very good, good, or fair/poor;
- `binding`: any, hardcover, or softcover;
- `firstEdition`: first-edition offers only;
- `signed`: signed offers only;
- `dustJacket`: offers marked with a dust jacket;
- `freeShipping`: free-shipping offers on the US storefront;
- `minPrice`, `maxPrice`: item-price range;
- `minPublishYear`, `maxPublishYear`: publication-year range;
- `sortBy`: relevance, lowest price, highest price, newest, or oldest.

#### Run limits

- `maxItems` defaults to 50 and applies across all searches.
- `maxPagesPerSearch` defaults to 5 and applies separately to each search.

AbeBooks usually exposes 30 offers per page. The Actor stops early when it reaches `maxItems`, runs out of pages, or sees an empty result page.

### Output example

A current ISBN search returns records shaped like this:

```json
{
  "listingId": "30101086817",
  "title": "Dune",
  "author": "Herbert, Frank",
  "isbn10": "0441172717",
  "isbn13": "9780441172719",
  "publisher": "Ace",
  "publishYear": 1990,
  "language": "English",
  "condition": "Used - Good",
  "sellerName": "medimops",
  "sellerLocation": "Berlin, Germany",
  "sellerRating": 5,
  "price": 9.44,
  "currency": "USD",
  "shippingPrice": 0,
  "shippingText": "Free Shipping",
  "availability": "in_stock",
  "quantityAvailable": 20,
  "listingUrl": "https://www.abebooks.com/Dune-Herbert-Frank-Ace/30101086817/bd",
  "searchUrl": "https://www.abebooks.com/servlet/SearchResults?isbn=9780441172719",
  "position": 1,
  "scrapedAt": "2026-09-19T06:09:03.840Z"
}
```

Prices, availability, seller data, and descriptions can change after extraction. Use `scrapedAt` to identify the observation time.

### How much does it cost to search AbeBooks book listings?

The Actor uses pay-per-event pricing:

- **$0.005** when a run starts;
- one `item` event for each unique offer saved.

Item prices decrease by Apify pricing tier:

| Tier | Price per saved offer |
| --- | ---: |
| FREE | $0.0039836 |
| BRONZE | $0.003464 |
| SILVER | $0.0027019 |
| GOLD | $0.0020784 |
| PLATINUM | $0.0020784 |
| DIAMOND | $0.0020784 |

At the FREE tier, 20 saved offers cost about **$0.084672**, 100 cost about **$0.40336**, and 1,000 cost about **$3.9886**, including one start event.

At the BRONZE tier, the same examples cost about **$0.07428**, **$0.3514**, and **$3.469**.

Failed requests and duplicate or rejected rows do not create item events. Apify displays the applicable tier and total charge before or after each run.

Cost examples are estimates, not payout or invoice guarantees. Final billing can be affected by Apify plan rules, refunds, fraud, disputes, taxes, corrections, or clawbacks.

### ISBN price comparison workflow

Use one exact ISBN, select `lowest-price`, and keep `shippingPrice` separate from `price`.

For an estimated delivered cost in a spreadsheet:

```text
price + shippingPrice
```

Do not interpret item price alone as delivered cost. Tax, customs charges, or destination-specific shipping changes may not appear on the public search card.

### Signed and first-edition sourcing workflow

A repeat sourcing task can combine author searches with collectible filters:

```json
{
  "searches": [
    { "author": "Stephen King" },
    { "author": "Ursula K. Le Guin" }
  ],
  "condition": "used",
  "firstEdition": true,
  "signed": true,
  "sortBy": "newest",
  "maxItems": 100,
  "maxPagesPerSearch": 3
}
```

Schedule the task, export each run, and compare by `listingId`. The Actor returns current snapshots; it does not itself store history, send alerts, or label listings as newly added.

### Scheduling and monitoring

Apify Schedules can run a saved task hourly, daily, weekly, or with a cron expression.

A typical monitoring pipeline is:

1. save a Task with stable searches and filters;
2. schedule repeated runs;
3. export each default dataset;
4. upsert by `listingId` in your database;
5. compare `price`, `shippingPrice`, `condition`, and `availability` over time;
6. send alerts from your own automation when values change.

Keep timestamps because an offer may disappear, be relisted, or change after a run.

### Export and integrations

The default dataset supports Apify exports such as:

- JSON and JSONL;
- CSV and Excel;
- XML and RSS;
- direct dataset API access.

You can connect runs to Google Sheets, Make, Zapier, webhooks, cloud storage, or your own ETL system.

### Run with the Apify API

Replace `<APIFY_TOKEN>` with your token.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~abebooks-book-search-listings/runs?token=<APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"searches":[{"isbn":"9780441172719"}],"maxItems":20}'
```

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/abebooks-book-search-listings').call({
  searches: [{ author: 'Ursula K. Le Guin' }],
  firstEdition: true,
  maxItems: 50,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient
import os

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/abebooks-book-search-listings').call(run_input={
    'searches': [{'keyword': 'antiquarian astronomy'}],
    'condition': 'used',
    'maxItems': 50,
})

items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### Use with MCP and AI agents

Add the Apify MCP server in Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/abebooks-book-search-listings"
```

#### Claude Desktop, Cursor, and VS Code

Use this equivalent MCP configuration in Claude Desktop, Cursor, or VS Code:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/abebooks-book-search-listings"
    }
  }
}
```

Example prompts:

- “Find 20 used offers for ISBN 9780441172719 and rank them by item plus shipping price.”
- “Export signed first-edition Stephen King offers with seller and condition details.”
- “Run my saved AbeBooks rare-book sourcing task and summarize the least expensive available copies.”

### Reliability and failure behavior

The Actor validates input before making requests.

It fails with a non-zero status when:

- an ISBN has an invalid shape;
- a start URL is outside supported AbeBooks search pages;
- price or year ranges are reversed;
- AbeBooks returns a challenge instead of listings;
- AbeBooks returns a non-success HTTP response after bounded retries.

A natural no-result search succeeds with zero dataset rows. It is different from a blocked or malformed response.

The Actor deduplicates offers by `listingId` within one run. It does not deduplicate against previous runs.

### Limits and practical tips

- Search cards may not contain every detail found on an individual book page.
- `binding` and `edition` are inferred from seller descriptions when present.
- Seller descriptions can be long, multilingual, or inconsistently formatted.
- Shipping is the displayed storefront value and can vary by destination.
- Currency reflects the displayed search result, not a converted accounting currency.
- Search ranking and counts can change between pages or runs.
- Start with one page while tuning filters, then increase limits.
- Use ISBN for edition-specific comparison and title/author for broader discovery.
- Avoid overlapping searches when you do not need duplicate discovery work.

### Legality and responsible use

Public marketplace data can still be subject to terms, database rights, copyright, privacy rules, and local law.

Use the Actor for legitimate research, sourcing, catalog, and monitoring purposes. Collect only what you need, respect applicable rules, avoid attempting to identify private individuals, and do not republish copyrighted seller descriptions without an appropriate basis.

This Actor is independent and is not endorsed by AbeBooks or Amazon.

### Troubleshooting

#### Why did my run return no rows?

Check that the source search returns offers in a normal browser. Then loosen condition, edition, signed, price, or year filters. A valid search can naturally have no matching inventory.

#### Why is shipping missing?

Some cards do not expose a numeric shipping amount for the current storefront context. Inspect `shippingText`; destination-specific checkout costs may differ.

#### Why does `edition` look incomplete?

AbeBooks search cards do not expose a universal structured edition field. The Actor reports recognizable edition text from the seller description when present.

#### Can I scrape one individual product URL?

No. `startUrls` accepts public AbeBooks search URLs, not arbitrary detail pages. The product is designed for offer discovery and comparison.

#### Does the Actor track changes or send alerts?

It produces current snapshots. Use Apify Schedules plus your spreadsheet, database, webhook, or automation platform to compare runs and alert on changes.

### Related Actors

- [ThriftBooks Used Book Listings Scraper](https://apify.com/automation-lab/thriftbooks-used-book-listings-scraper) for a second used-book marketplace.

Use related sources as separate datasets. Marketplace offer condition, shipping, and availability are source-specific and should not be treated as interchangeable.

### FAQ

#### Is an AbeBooks account required?

No. The Actor searches public listing pages without login.

#### Are the prices historical?

No. Each row is a current public observation at `scrapedAt`.

#### Can one run search multiple books?

Yes. Add multiple `searches` objects. `maxItems` is shared across them, while `maxPagesPerSearch` applies to each search.

#### Are duplicate offers charged twice?

No. Within one run, the Actor deduplicates offers before they are saved. Each saved unique offer creates one `item` event.

#### Does the Actor download cover images?

No. It records the public image URL when shown, avoiding unnecessary media transfer.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/abebooks-book-search-listings/changelog.md

# Actor input Schema

## `searches` (type: `array`):

One or more searches. Combine fields in one row to narrow a search, or add rows to monitor several books.

## `startUrls` (type: `array`):

Optional public abebooks.com SearchResults or book-search URLs. Shared filters below also apply to these URLs.

## `condition` (type: `string`):

Limit offers by AbeBooks condition group.

## `binding` (type: `string`):

Limit offers by binding.

## `firstEdition` (type: `boolean`):

Return offers marked as first editions.

## `signed` (type: `boolean`):

Return offers marked as signed.

## `dustJacket` (type: `boolean`):

Return offers marked as having a dust jacket.

## `freeShipping` (type: `boolean`):

Request AbeBooks offers marked for free shipping on the US storefront.

## `minPrice` (type: `number`):

Minimum item price in the storefront currency; shipping is separate.

## `maxPrice` (type: `number`):

Maximum item price in the storefront currency; shipping is separate.

## `minPublishYear` (type: `integer`):

Exclude offers published before this year.

## `maxPublishYear` (type: `integer`):

Exclude offers published after this year.

## `sortBy` (type: `string`):

Order each AbeBooks result set before extraction.

## `maxItems` (type: `integer`):

Stop after this many unique offers across all searches.

## `maxPagesPerSearch` (type: `integer`):

Safety cap for each query or start URL. AbeBooks usually exposes 30 offers per page.

## Actor input object example

```json
{
  "searches": [
    {
      "isbn": "9780441172719"
    }
  ],
  "startUrls": [
    {
      "url": "https://www.abebooks.com/servlet/SearchResults?kn=rare+books"
    }
  ],
  "condition": "any",
  "binding": "any",
  "firstEdition": false,
  "signed": false,
  "dustJacket": false,
  "freeShipping": false,
  "sortBy": "relevance",
  "maxItems": 20,
  "maxPagesPerSearch": 5
}
```

# Actor output Schema

## `dataset` (type: `string`):

Structured book offer records from the default dataset.

# 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 = {
    "searches": [
        {
            "isbn": "9780441172719"
        }
    ],
    "startUrls": [
        {
            "url": "https://www.abebooks.com/servlet/SearchResults?kn=rare+books"
        }
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/abebooks-book-search-listings").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 = {
    "searches": [{ "isbn": "9780441172719" }],
    "startUrls": [{ "url": "https://www.abebooks.com/servlet/SearchResults?kn=rare+books" }],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/abebooks-book-search-listings").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 '{
  "searches": [
    {
      "isbn": "9780441172719"
    }
  ],
  "startUrls": [
    {
      "url": "https://www.abebooks.com/servlet/SearchResults?kn=rare+books"
    }
  ],
  "maxItems": 20
}' |
apify call automation-lab/abebooks-book-search-listings --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/abebooks-book-search-listings"
        }
    }
}
```

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/xlGCRtQQqwyZo5heO/builds/D1kmGRaGVmmc4SVIG/openapi.json
