# CruiseMapper Cruise Itineraries Scraper (`automation-lab/cruisemapper-cruise-itineraries-scraper`) Actor

Search CruiseMapper ships and export voyage dates, durations, embarkation ports, ordered itinerary calls, call times, prices, and source URLs.

- **URL**: https://apify.com/automation-lab/cruisemapper-cruise-itineraries-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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 web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## CruiseMapper Cruise Itineraries Scraper

Search CruiseMapper ships and export complete cruise voyages as structured data.
Each result combines voyage identity, departure date, duration, embarkation port,
visible starting price, ordered itinerary calls, local call times when published,
and canonical CruiseMapper source URLs.

Use the Actor for cruise-market research, travel-content planning, itinerary
comparison, and repeatable voyage monitoring. It supports ship-name discovery
and exact CruiseMapper ship pages without requiring a CruiseMapper account.

### What does this CruiseMapper scraper do?

The Actor turns public CruiseMapper itinerary pages into one typed record per
cruise voyage.

It can:

- search ships by name, such as `Arvia`, `Iona`, or `Brilliance of the Seas`;
- target one or more exact CruiseMapper ship URLs;
- filter voyages by inclusive departure-date range;
- preserve each voyage's ordered departure, port-call, and arrival events;
- include port countries and canonical port URLs where CruiseMapper provides them;
- include local arrival and departure times when they are shown by the source;
- stop at a global result limit across all selected ships;
- use an optional sticky Apify Proxy session for scheduled or larger jobs.

The default dataset contains voyage records, not separate port-schedule rows.
For port-centric monthly call data, see our related Port Schedules Actor below.

### Who is it for?

#### Cruise-market analysts

Compare advertised voyage calendars, durations, embarkation markets, and port
coverage across ships.

#### Travel publishers

Create structured source feeds for destination guides, sailing calendars, and
editorial planning.

#### Travel agencies and cruise specialists

Export selected ships' upcoming itineraries into spreadsheets, databases, or
internal research tools.

#### Data and automation teams

Schedule repeat runs, compare records by `cruiseId`, and send changed voyages to
a downstream workflow.

### Why use this Actor?

CruiseMapper ship pages contain voyage summary rows, while each complete call
sequence is loaded separately. The Actor handles both layers and returns one
integration-ready object.

Key differentiators include:

- ship-name search and exact URL inputs in the same run;
- complete ordered calls nested under each voyage;
- stable CruiseMapper cruise and ship identifiers;
- date filters applied consistently to searched and explicit ships;
- canonical ship and port source URLs for traceability;
- direct HTTP extraction instead of a resource-heavy browser;
- bounded retries and coherent cookie sessions for itinerary details.

### What CruiseMapper data can I extract?

| Field | Meaning |
| --- | --- |
| `cruiseId` | Stable CruiseMapper voyage identifier |
| `shipId` | Stable CruiseMapper ship identifier |
| `shipName` | Displayed ship name |
| `shipUrl` | Canonical CruiseMapper ship page |
| `departureDate` | Voyage departure date in `YYYY-MM-DD` |
| `durationDays` | Advertised duration when available |
| `itineraryTitle` | CruiseMapper route summary |
| `embarkationPort` | Displayed departure port |
| `embarkationCountry` | Departure country when available |
| `startingPriceUsd` | Visible starting price, or `null` |
| `calls` | Ordered departure, port-call, and arrival events |
| `callCount` | Number of events in `calls` |
| `sourceUrl` | Source ship itinerary page |
| `scrapedAt` | Collection timestamp |

Each object in `calls` includes sequence, call type, date, arrival time,
departure time, port name, country, and port URL. Missing source values are
returned as `null`; the Actor does not invent call times or prices.

### How to scrape CruiseMapper cruise itineraries

1. Open the Actor input page.
2. Enter one or more ship names in **Ship names to search**.
3. Optionally add exact CruiseMapper ship URLs.
4. Optionally set the earliest and latest departure dates.
5. Choose the maximum number of voyage records.
6. Run the Actor.
7. Open **Dataset** to download JSON, CSV, Excel, XML, or another supported format.

A small first run is recommended before expanding the date range or ship list.

### Input parameters

#### `searchTerms`

An array of public ship names. CruiseMapper's ship search resolves each term.
`maxShipsPerSearch` bounds partial-name matches.

#### `shipUrls`

Canonical URLs matching:

```text
https://www.cruisemapper.com/ships/<ship-slug>-<numeric-id>
```

URLs from another host or a non-ship CruiseMapper path fail validation.

#### `startDate` and `endDate`

Optional inclusive filters in `YYYY-MM-DD` format. If both are supplied,
`startDate` must not be later than `endDate`.

#### `maxShipsPerSearch`

The maximum accepted matches per search term, from 1 to 50. Use 1 for precise
ship names and a higher value for broader discovery.

#### `maxItems`

The global voyage-record limit, from 1 to 10,000. The Actor stops requesting
new itinerary details when the limit is reached.

#### `requestDelaySecs`

A polite delay between accepted itinerary-detail requests. The default is 0.25
seconds and the maximum is 30 seconds.

#### `proxyConfiguration`

Optional Apify Proxy settings. Direct HTTP is the default proven route. When a
proxy is enabled, the Actor keeps one sticky identity for each ship page and
its detail requests.

### Example input

```json
{
  "searchTerms": ["Arvia", "Iona"],
  "startDate": "2026-08-01",
  "endDate": "2027-03-31",
  "maxShipsPerSearch": 1,
  "maxItems": 25,
  "requestDelaySecs": 0.25,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

To target one source directly:

```json
{
  "shipUrls": [
    {
      "url": "https://www.cruisemapper.com/ships/Brilliance-Of-The-Seas-720"
    }
  ],
  "startDate": "2026-08-01",
  "endDate": "2026-10-31",
  "maxItems": 10
}
```

### Output example

```json
{
  "cruiseId": "5149833",
  "shipId": "720",
  "shipName": "Brilliance Of The Seas",
  "shipUrl": "https://www.cruisemapper.com/ships/Brilliance-Of-The-Seas-720",
  "departureDate": "2026-08-03",
  "durationDays": 8,
  "itineraryTitle": "8 days, one-way from Barcelona to Trieste",
  "embarkationPort": "Barcelona",
  "embarkationCountry": "Spain",
  "startingPriceUsd": null,
  "calls": [
    {
      "sequence": 1,
      "callType": "departure",
      "date": "2026-08-03",
      "arrivalTime": null,
      "departureTime": "17:00",
      "portName": "Barcelona, Spain",
      "country": "Spain",
      "portUrl": "https://www.cruisemapper.com/ports/barcelona-port-82"
    },
    {
      "sequence": 2,
      "callType": "port_call",
      "date": "2026-08-04",
      "arrivalTime": "08:00",
      "departureTime": "17:00",
      "portName": "Toulon, France Riviera, La Seyne-sur-Mer",
      "country": "France",
      "portUrl": "https://www.cruisemapper.com/ports/toulon-port-221"
    }
  ],
  "callCount": 9,
  "sourceUrl": "https://www.cruisemapper.com/ships/Brilliance-Of-The-Seas-720#itinerary",
  "scrapedAt": "2026-08-16T12:00:00.000Z"
}
```

### How much does it cost to extract CruiseMapper cruise itineraries?

Pricing uses one small Actor-start event plus one event for each saved cruise
voyage. Complete nested itinerary calls do not incur separate event charges.

The BRONZE item price is **$0.00144 per voyage**, plus **$0.00005 per run**.
Higher-volume tiers automatically reduce the item price.

BRONZE examples use this calculation:

```text
run event charge = $0.00005
voyage event charge = saved voyages × $0.00144
```

For example, a 10-voyage result uses one run event and ten voyage events;
a 100-voyage result uses one run event and one hundred voyage events. Higher
subscription tiers apply their active discounted item rate automatically.

Platform compute and optional proxy usage can also contribute to total run cost.
The Apify Console shows the final charge for each run.

### Scheduling CruiseMapper monitoring

Create an Apify Schedule for daily, weekly, or monthly collection. Keep a stable
input and compare records by `cruiseId`.

A practical workflow is:

1. run the Actor on a schedule;
2. export the default dataset;
3. upsert records into a database keyed by `cruiseId`;
4. compare departure date, title, price, and `calls` with the prior version;
5. notify an analyst only when a tracked field changes.

The Actor emits snapshots. It does not maintain cross-run history or send alerts
by itself.

### Export to spreadsheets and data pipelines

Dataset results can be downloaded as JSON, CSV, Excel, XML, or RSS through
Apify's dataset endpoints. Nested `calls` are most naturally preserved in JSON.
For a flat spreadsheet, transform each call into its own row downstream.

Common integrations include:

- Google Sheets through Make;
- Airtable through Zapier;
- BigQuery or Snowflake through an ETL job;
- PostgreSQL keyed by `cruiseId`;
- webhooks for newly observed voyages;
- LLM workflows that draft destination summaries from verified source fields.

### Run through the Apify API with cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~cruisemapper-cruise-itineraries-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchTerms": ["Arvia"],
    "startDate": "2026-08-01",
    "endDate": "2026-12-31",
    "maxItems": 10
  }'
```

Keep API tokens in environment variables or a secret manager.

### Run with JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });

const run = await client.actor(
  'automation-lab/cruisemapper-cruise-itineraries-scraper'
).call({
  searchTerms: ['Arvia'],
  startDate: '2026-08-01',
  endDate: '2026-12-31',
  maxItems: 10,
});

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

### Run with Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor(
    "automation-lab/cruisemapper-cruise-itineraries-scraper"
).call(run_input={
    "searchTerms": ["Arvia"],
    "startDate": "2026-08-01",
    "endDate": "2026-12-31",
    "maxItems": 10,
})

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

### Use through MCP and AI assistants

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/cruisemapper-cruise-itineraries-scraper"
```

#### Claude Desktop setup

Use this JSON in Claude Desktop's MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/cruisemapper-cruise-itineraries-scraper"
    }
  }
}
```

#### Cursor setup

Add the same server URL under **Settings → Tools & MCP → New MCP Server**.
Name it `apify` and use the HTTP URL shown in the JSON above.

#### VS Code setup

Add the same `apify` HTTP server to your workspace or user MCP configuration,
then enable it from VS Code's MCP servers view.

Example prompts:

- “Search CruiseMapper for Arvia voyages departing from August through December 2026.”
- “Export ten Brilliance of the Seas voyages and summarize their embarkation ports.”
- “Compare the ordered port calls for the next Arvia and Iona cruises.”

Review generated conclusions against the returned source URLs.

### Reliability and limits

The Actor uses public server-rendered ship pages and CruiseMapper's own public
itinerary-detail request. It does not launch a browser or download media.

Reliability behavior:

- transient network, HTTP 429, and temporary 5xx responses receive bounded retries;
- malformed inputs and unsupported URLs fail immediately;
- a missing itinerary table is treated as an upstream error, not a valid empty result;
- duplicate ship URLs and cruise IDs are removed within a run;
- no search matches produce a successful empty dataset with an explanatory log;
- the result limit stops additional detail requests.

CruiseMapper can change its HTML or public endpoints. If a previously working
input fails, retry a small run and inspect the Actor log.

### Troubleshooting

#### Why did my search return no records?

Check spelling and try the ship's exact current name. Remove date filters to
confirm the ship has visible voyage rows, then add a narrower valid range.

#### Why are some prices or call times null?

CruiseMapper does not publish those values for every voyage or call. The Actor
returns `null` rather than guessing.

#### Why was my ship URL rejected?

Use a canonical public URL under `www.cruisemapper.com/ships/` ending with the
numeric ship ID. Port, deck-plan, tracker, and search pages are not ship inputs.

#### Should I enable a proxy?

Direct HTTP is the normal route. Consider an Apify Proxy for scheduled or larger
runs if your environment experiences temporary access failures. Proxy transfer
may increase the run's infrastructure cost.

### Responsible use and legality

This Actor extracts publicly visible CruiseMapper information. Use it in
accordance with applicable laws, CruiseMapper's terms, database rights, and
Apify's policies.

Do not use the data to misrepresent availability, pricing, or official cruise
line information. Respect source attribution, reasonable request volumes, and
personal-data obligations. This Actor is not affiliated with CruiseMapper or a
cruise line.

### Related automation-lab Actors

- [CruiseMapper Port Schedules Scraper](https://apify.com/automation-lab/cruisemapper-port-schedules-scraper) — export port-centric monthly ship calls with arrival and departure times.

Use the Itineraries Actor for one record per ship voyage with a nested route.
Use the Port Schedules Actor when the buyer starts from a port and month.

### FAQ

#### Does this Actor require a CruiseMapper account?

No. It works with public ship and itinerary pages.

#### Can I search several ships in one run?

Yes. Add several `searchTerms`, several `shipUrls`, or both. `maxItems` applies
globally across all accepted ships.

#### Does it scrape live vessel positions?

No. It extracts scheduled cruise voyages and itinerary calls, not live AIS
positions.

#### Does it provide historical change tracking?

No. Each run is a current source snapshot. Schedule the Actor and compare stable
`cruiseId` records in your own datastore for change tracking.

#### Are call times converted to UTC?

No. Times are source-local display values. Dates are normalized to `YYYY-MM-DD`,
but times remain as shown by CruiseMapper.

#### Can I export one row per port call?

The primary dataset intentionally uses one voyage per row with nested `calls`.
Flatten the array downstream when a call-level table is required.

#### Is every visible voyage price available?

No. `startingPriceUsd` is `null` when CruiseMapper's voyage row does not show a
price.

#### How do I reduce runtime?

Use exact `shipUrls`, narrow departure dates, a smaller `maxItems`, and keep
`maxShipsPerSearch` at 1 for precise ship names.

# Actor input Schema

## `searchTerms` (type: `array`):

Cruise ship names such as Arvia, Iona, or Brilliance of the Seas.

## `shipUrls` (type: `array`):

Optional canonical CruiseMapper ship pages for exact source-specific extraction.

## `startDate` (type: `string`):

Optional inclusive departure-date filter in YYYY-MM-DD format.

## `endDate` (type: `string`):

Optional inclusive departure-date filter in YYYY-MM-DD format.

## `maxShipsPerSearch` (type: `integer`):

Maximum matching ships accepted for each ship-name search.

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

Stop after saving this many cruise-voyage records across all ships.

## `requestDelaySecs` (type: `number`):

Polite delay in seconds between accepted voyage-detail requests.

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

Optional Apify Proxy configuration for scheduled or higher-volume collection.

## Actor input object example

```json
{
  "searchTerms": [
    "Arvia"
  ],
  "shipUrls": [
    {
      "url": "https://www.cruisemapper.com/ships/Arvia-2158"
    }
  ],
  "maxShipsPerSearch": 5,
  "maxItems": 20,
  "requestDelaySecs": 0.25,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Dataset containing ship identity, departure details, route summaries, prices, and ordered port calls.

# 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 = {
    "searchTerms": [
        "Arvia"
    ],
    "shipUrls": [
        {
            "url": "https://www.cruisemapper.com/ships/Arvia-2158"
        }
    ],
    "maxShipsPerSearch": 5,
    "maxItems": 20,
    "requestDelaySecs": 0.25
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/cruisemapper-cruise-itineraries-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 = {
    "searchTerms": ["Arvia"],
    "shipUrls": [{ "url": "https://www.cruisemapper.com/ships/Arvia-2158" }],
    "maxShipsPerSearch": 5,
    "maxItems": 20,
    "requestDelaySecs": 0.25,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/cruisemapper-cruise-itineraries-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 '{
  "searchTerms": [
    "Arvia"
  ],
  "shipUrls": [
    {
      "url": "https://www.cruisemapper.com/ships/Arvia-2158"
    }
  ],
  "maxShipsPerSearch": 5,
  "maxItems": 20,
  "requestDelaySecs": 0.25
}' |
apify call automation-lab/cruisemapper-cruise-itineraries-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/cruisemapper-cruise-itineraries-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/V1NwXbm1B4kCoG3Pj/builds/6IIWCOZRmFlbrDWKI/openapi.json
