# HAL Cruises Scraper - Complete Cruise Data Extractor (`sercul/hal-cruises-scraper`) Actor

Why Choose This Scraper?
✅ Extract from 7 Holland America markets (US, GB, AU, CA, IT, NL, DE)
✅ Complete cruise data with cabin-level pricing (8 cabin types)
✅ Filter by 12 destination regions\
✅ Apify RESIDENTIAL proxy with geo-matched country codes

- **URL**: https://apify.com/sercul/hal-cruises-scraper.md
- **Developed by:** [Jeremy G](https://apify.com/sercul) (community)
- **Categories:** Travel, Other
- **Stats:** 14 total users, 1 monthly users, 96.9% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 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.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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

## Holland America Line Scraper — Complete Cruise Data Extractor

Extract **cruise listings, itineraries, and cabin-level pricing** from Holland America Line across 8 international markets. Built for travel agencies, price comparison sites, affiliate marketers, and cruise-industry analysts.

### Updates

- **2026-06-11** — New markets added: Spain (`es_ES`, EUR).

### Why Choose This Scraper?

- ✅ Extract from **8 Holland America markets** (US, GB, AU, CA, IT, NL, DE, ES) with local-currency pricing
- ✅ Complete cruise data with **cabin-level pricing** across 6+ cabin types (Inside, Ocean View, Verandah, Signature/Vista/Neptune Suites)
- ✅ Filter by **12 destination regions** (Alaska, Caribbean, Europe, Asia, World Cruises, and more)
- ✅ **2,000+ sailings per market**
- ✅ **Direct booking/source URLs** on every sailing — ready for affiliate monetization
- ✅ Works with Apify Residential or your own residential proxy

### Use Cases

- **Travel agencies & OTAs** — monitor HAL pricing across 8 markets
- **Premium/luxury travel affiliates** — Holland America is a premium brand; ideal inventory
- **Cruise analysts** — rich historical pricing (Inside → Neptune Suite range) for trend research
- **Hotel/travel comparison sites** — integrate ocean-cruise vertical with deep links

### Supported Markets

| Region | Currency | API Country |
|--------|----------|-------------|
| `en_US` | USD | us |
| `en_GB` | GBP | gb |
| `en_AU` | AUD | au |
| `en_CA` | CAD | ca |
| `it_IT` | EUR | eu |
| `nl_NL` | EUR | eu |
| `de_DE` | EUR | eu |
| `es_ES` | EUR | eu |

### Input

| Parameter | Type | Description | Default |
|-----------|------|-------------|---------|
| `region`\* | string | Market to scrape | `en_US` |
| `maxRows` | number | Maximum sailing results | `500` |
| `destinations` | string\[] | Filter by destination code | All |
| `pageSize` | number | Results fetched per request | `100` |
| `maxRequestRetries` | number | Retries for failed requests | `5` |
| `requestHandlerTimeoutSecs` | number | Request timeout (seconds) | `30` |
| `useApifyProxy` | boolean | Use Apify Residential proxy (**required**) | `true` |
| `apifyProxyGroups` | string | Proxy tier | `RESIDENTIAL` |
| `apifyProxyCountryCode` | string | Override proxy country | Auto |
| `proxyUrl` | string | Custom proxy URL | — |

**⚠️ Proxy required:** this Actor needs a residential proxy. Enable Apify Proxy with the `RESIDENTIAL` group, or supply your own residential `proxyUrl`.

### Destination Codes

| Code | Destination |
|------|-------------|
| `A` | Alaska |
| `O` | Asia |
| `P` | Australia & South Pacific |
| `N` | Canada & New England |
| `C` | Caribbean |
| `E` | Europe |
| `W` | Grand Voyages & World Cruises |
| `H` | Hawaii & Tahiti |
| `M` | Mexico |
| `L` | Pacific Coast |
| `T` | Panama Canal |
| `S` | South America & Antarctica |

### Cabin Codes

| Code | Cabin Type |
|------|------------|
| `IN` | Inside (Interior) |
| `OV` | Ocean View |
| `VN` | Verandah (balcony) |
| `SS` | Signature Suite |
| `VS` | Vista Suite |
| `NS` | Neptune Suite (top-tier) |
| `LA` | Lanai |
| `PH` | Penthouse |

### Output

Each record is a single sailing with:

- Cruise and itinerary identifiers (`cruise_id`, `itinerary_id`)
- Ship name (parsed from `#@#` delimited composite fields)
- Departure/arrival ports, sailing dates, duration in nights
- Lowest available per-person price with currency
- Ports of call with day numbers
- Dynamic cabin-price fields: `price_{CURRENCY}_{CABIN}_anonymous_d` (e.g., `price_USD_VN_anonymous_d`)
- `source_url` — direct booking link
- `platform`, `company`, `locale`

**Price sentinels:**

- `0.0` = sold out
- `-1.0` = unavailable / not offered on this sailing

#### Sample Output

```json
{
  "cruise_id": "HAL_NS250815_2026-08-15",
  "itinerary_id": "HAL_7N_ALASKA_INSIDE_PASSAGE",
  "company": "holland-america-line",
  "locale": "en_US",
  "platform": "holland-america-line-en_US",
  "title": "7-Day Alaska Inside Passage",
  "ship_name": "Nieuw Statendam",
  "departure_date": "2026-08-15",
  "duration": 7,
  "price": 1299,
  "currency": "USD",
  "price_USD_IN_anonymous_d": 1299,
  "price_USD_OV_anonymous_d": 1599,
  "price_USD_VN_anonymous_d": 1899,
  "price_USD_SS_anonymous_d": 2999,
  "price_USD_NS_anonymous_d": 5499,
  "destinations": ["A"],
  "ports_list": ["Vancouver", "Juneau", "Skagway", "Glacier Bay", "Ketchikan", "Vancouver"],
  "source_url": "https://www.hollandamerica.com/..."
}
```

### Runtime & Cost

- **Typical run:** ~3-5 minutes for 500 rows
- **Full market sweep:** ~10-20 minutes for 2,000+ sailings
- **Memory:** 1 GB default
- **Proxy usage:** ~1-2 GB residential proxy bandwidth per 500 rows

### Usage

```json
{
  "region": "en_US",
  "maxRows": 500,
  "destinations": ["A", "E"],
  "useApifyProxy": true,
  "apifyProxyGroups": "RESIDENTIAL"
}
```

### Notes

- Prices are **per-person, double-occupancy**
- EU markets (`it_IT`, `nl_NL`, `de_DE`, `es_ES`) all share EUR pricing, differentiated by localized text (port and region names)
- Each output record represents **one sailing** (one departure date)

### Related Actors

Looking to build a full cruise pricing dataset? Pair this with:

- **Royal Caribbean Scraper** — 6 markets, per-cabin pricing
- **Princess Cruises Scraper** — per-cabin availability counts
- **Celebrity Cruises Scraper** — 6 markets, service charges included
- **Disney / MSC / Carnival / Costa / NCL Scrapers** — full coverage

### Support

Issues or custom requests? Email **support@track.cruises**.

# Actor input Schema

## `region` (type: `string`):

Market/locale to scrape

## `maxRows` (type: `integer`):

Maximum number of sailing results to fetch

## `destinations` (type: `array`):

Filter by destination code

## `pageSize` (type: `integer`):

Number of results per API page (each result is ~400KB of JSON — keep small when using slow proxies)

## `maxRequestRetries` (type: `integer`):

Maximum number of retries for failed requests

## `requestHandlerTimeoutSecs` (type: `integer`):

Timeout for HTTP requests in seconds (responses are large; residential proxies need 120+)

## `useApifyProxy` (type: `boolean`):

Use Apify Proxy with RESIDENTIAL group (a residential proxy is required)

## `apifyProxyCountryCode` (type: `string`):

Two-letter country code for proxy geo-matching

## `apifyProxyGroups` (type: `string`):

Proxy group tier, e.g., RESIDENTIAL

## `proxyUrl` (type: `string`):

Alternative proxy URL. Format: http\[s]://user:pass@host:port

## Actor input object example

```json
{
  "region": "en_US",
  "maxRows": 25,
  "pageSize": 25,
  "maxRequestRetries": 5,
  "requestHandlerTimeoutSecs": 120,
  "useApifyProxy": true
}
```

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("sercul/hal-cruises-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("sercul/hal-cruises-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 '{}' |
apify call sercul/hal-cruises-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sercul/hal-cruises-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/f4iukiC7ZKKGbV5Oh/builds/p55N6MVoE1iPJHve9/openapi.json
