# Scandlines Scraper — Germany-Denmark Ferry Routes & Prices (`studio-amba/scandlines-scraper`) Actor

Extract ferry route data from Scandlines.com — routes between Germany and Denmark (Puttgarden-Rodby, Rostock-Gedser). Prices, schedules, and crossing times.

- **URL**: https://apify.com/studio-amba/scandlines-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** Travel
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 1,000 result scrapeds

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/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

## Scandlines Scraper -- Ferry Routes, Schedules & Prices Between Denmark and Germany

Extract ferry route information, crossing times, departure schedules, and prices from [Scandlines.com](https://www.scandlines.com) -- the major ferry operator connecting Denmark and Germany across the Baltic Sea, carrying millions of passengers and vehicles annually.

### What is Scandlines Scraper?

Scandlines operates two of Northern Europe's busiest ferry corridors: the Puttgarden-Rodby crossing (45 minutes, connecting Germany's Fehmarn island to Denmark's Lolland) and the Rostock-Gedser route (2 hours, linking the German coast to southern Denmark). Together, these routes form a critical transport link between Scandinavia and continental Europe.

This actor scrapes route information from the Scandlines website, extracting structured data about routes, departure/arrival ports, crossing durations, frequency, pricing, and descriptions. What people build with it:

- **Travel planning applications** -- developers integrate ferry schedules into multimodal route planners that combine road, rail, and sea crossings for trips between Scandinavia and mainland Europe.
- **Logistics cost modelling** -- freight companies and supply chain analysts track Scandlines pricing to optimise their Denmark-Germany transport budgets.
- **Tourism content** -- travel agencies and bloggers pull route data and descriptions to populate their Scandinavian travel guides with accurate ferry crossing information.
- **Competitive monitoring** -- transport operators and the upcoming Fehmarn Belt tunnel project track Scandlines' pricing, frequency, and service offerings.
- **Price tracking** -- regular travellers and commuter groups monitor fare changes on routes they use frequently.
- **Mobility research** -- transport economists study the competitive dynamics between the Scandlines ferry corridor and the upcoming Fehmarn Belt fixed link (tunnel) to model traffic diversion scenarios.

### What data does Scandlines Scraper extract?

Each route entry contains:

- :ferry: **Route name** -- the crossing identification (e.g., "Puttgarden - Rodby")
- :anchor: **Departure and arrival ports** -- origin and destination harbours
- :clock1: **Departure and arrival times** -- scheduled crossing times
- :hourglass: **Duration** -- crossing time in minutes
- :repeat: **Frequency** -- departures per day
- :euro: **Price** -- fare amount and currency (EUR or DKK)
- :car: **Vehicle type** -- what the pricing applies to (car, motorcycle, camper, etc.)
- :scroll: **Description** -- route description and facilities information
- :camera: **Image** -- route hero image from the website
- :link: **URL** -- direct link to the route page on scandlines.com

### How to scrape Scandlines

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `startUrls` | Array | No | Scandlines pages to scrape (default: routes overview page) |
| `searchQuery` | String | No | Search by keyword: `"Puttgarden"`, `"Rostock"`, `"Gedser"` |
| `maxResults` | Integer | No | Maximum routes/departures to return (default: 100) |
| `proxyConfiguration` | Object | No | Proxy settings for reliability |

**Tips:**

- Leave all inputs empty to scrape the complete routes overview from scandlines.com/routes.
- Use `searchQuery` to find specific route information by port name.
- The actor follows route links from listing pages, then extracts detailed information from each route's detail page.

### Output

```json
{
    "routeName": "Puttgarden - Rodby",
    "departure": "Puttgarden",
    "arrival": "Rodby",
    "departureTime": "Every 30 minutes",
    "arrivalTime": "",
    "duration": "45 min",
    "frequency": "Up to 46 departures daily",
    "price": 49,
    "currency": "EUR",
    "vehicleType": "",
    "description": "The Puttgarden-Rodby route is the fastest connection between Germany and Denmark. With a crossing time of just 45 minutes and departures every 30 minutes, it is the preferred choice for travellers on the E47 motorway corridor...",
    "imageUrl": "https://www.scandlines.com/media/puttgarden-rodby-hero.jpg",
    "url": "https://www.scandlines.com/routes/puttgarden-rodby",
    "scrapedAt": "2026-04-03T11:30:00.000Z"
}
````

### How much does it cost?

Scandlines Scraper uses lightweight CheerioCrawler:

| Volume | Estimated CUs | Estimated Cost |
|--------|--------------|----------------|
| All routes (2-4) | ~0.01 | ~$0.005 |
| All route details + sub-pages | ~0.05 | ~$0.025 |

Scandlines has a small number of routes, so even a complete scrape is very cheap.

### Can I integrate?

Feed ferry data into your applications:

- **Google Sheets** -- maintain a fare comparison sheet updated weekly
- **Slack** -- get notified about price changes on your regular route
- **Zapier / Make** -- trigger travel booking workflows based on fare thresholds
- **Webhooks** -- pipe route data into your own travel planning application
- **PostgreSQL** -- build a historical fare tracking database

### Can I use it as an API?

Yes. Perfect for travel planning integrations:

**Python:**

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

run = client.actor("studio-amba/scandlines-scraper").call(run_input={
    "maxResults": 20,
})

for route in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{route['routeName']} | {route.get('duration', '?')} | EUR {route.get('price', '?')}")
```

**JavaScript:**

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

const client = new ApifyClient({ token: "YOUR_API_TOKEN" });

const run = await client.actor("studio-amba/scandlines-scraper").call({
    maxResults: 20,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((route) => {
    console.log(`${route.routeName} | ${route.duration || "?"} | EUR ${route.price || "?"}`);
});
```

### FAQ

**What routes does Scandlines operate?**
Two main corridors: Puttgarden (Germany) to Rodby (Denmark) and Rostock (Germany) to Gedser (Denmark). The Puttgarden-Rodby route has the most frequent departures.

**Does this include real-time departure schedules?**
The actor extracts published route information and pricing. For real-time departure status, the Scandlines website may provide additional live data not captured here.

**Can I get prices for specific vehicle types?**
The actor extracts pricing information as displayed on the website. Detailed per-vehicle-type pricing may require visiting the booking flow, which this actor does not access.

**Does it cover the Fehmarn Belt tunnel?**
No. The Fehmarn Belt tunnel is a future fixed link that will compete with the Puttgarden-Rodby ferry when completed. This actor only covers existing Scandlines ferry services.

**Is pricing in EUR or DKK?**
Scandlines displays prices in both currencies depending on the departure country and page context. The actor captures whichever currency is shown.

**How frequent are departures on the Puttgarden-Rodby route?**
Puttgarden-Rodby is one of Europe's busiest ferry corridors, with departures roughly every 30 minutes during peak season. That translates to up to 46 daily crossings. The 45-minute crossing time makes it faster than driving around through Jutland for most Danish-German travel.

**Can I use this for freight and logistics planning?**
The actor captures route-level information (schedule, duration, pricing). For freight-specific booking, capacity availability, and dangerous goods restrictions, you would need to access Scandlines' commercial freight portal directly.

**Does Scandlines operate hybrid/electric ferries?**
Yes. Scandlines has invested heavily in hybrid-electric ferries, especially on the Puttgarden-Rodby route. The actor does not capture vessel specifications, but the route data itself is accurate regardless of which specific ferry operates a given crossing.

**What about the Helsingborg-Helsingor route?**
That crossing is operated by ForSea (formerly HH Ferries), not Scandlines. This actor only covers Scandlines routes.

### Limitations

- Scandlines has a small number of routes (2 main corridors), so the dataset is naturally limited in size.
- Dynamic pricing (prices that vary by date, time, vehicle type, and booking lead time) requires the booking flow. This actor captures advertised/starting prices.
- The website structure may change seasonally as Scandlines updates promotional content.
- Some route information pages use JavaScript-rendered content that CheerioCrawler cannot access. The actor extracts what is available in the initial HTML.
- Sub-pages about onboard services, facilities, and restaurants may be included in results alongside route data.

### Related transport and travel scrapers

- [NMBS Scraper](https://apify.com/studio-amba/nmbs-scraper) -- Belgian train connections and live departure boards
- [Touring Scraper](https://apify.com/studio-amba/touring-scraper) -- Belgian automobile club travel guides and border crossing info
- [Prisjakt Scraper](https://apify.com/studio-amba/prisjakt-scraper) -- Nordic price comparison (for shopping in Denmark/Sweden)
- [AutoVlan Scraper](https://apify.com/studio-amba/autovlan-scraper) -- Belgian used cars (for the road trip to catch the ferry)

### Your feedback

Need real-time departure data, seasonal pricing tracking, or support for other ferry operators? Open an issue on GitHub or contact us through Apify. We build based on what users need.

# Actor input Schema

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

Scandlines pages to scrape. Example: https://www.scandlines.com/routes

## `searchQuery` (type: `string`):

Search for routes by keyword (e.g., 'Puttgarden', 'Rostock', 'Gedser').

## `maxResults` (type: `integer`):

Maximum number of routes/departures to return.

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

Proxy settings for reliability.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.scandlines.com/routes"
    }
  ],
  "maxResults": 100
}
```

# 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 = {
    "startUrls": [
        {
            "url": "https://www.scandlines.com/routes"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/scandlines-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 = { "startUrls": [{ "url": "https://www.scandlines.com/routes" }] }

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/scandlines-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 '{
  "startUrls": [
    {
      "url": "https://www.scandlines.com/routes"
    }
  ]
}' |
apify call studio-amba/scandlines-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Scandlines Scraper — Germany-Denmark Ferry Routes & Prices",
        "description": "Extract ferry route data from Scandlines.com — routes between Germany and Denmark (Puttgarden-Rodby, Rostock-Gedser). Prices, schedules, and crossing times.",
        "version": "0.1",
        "x-build-id": "qt15CAspRJh8S0BY9"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/studio-amba~scandlines-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-studio-amba-scandlines-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/studio-amba~scandlines-scraper/runs": {
            "post": {
                "operationId": "runs-sync-studio-amba-scandlines-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/studio-amba~scandlines-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-studio-amba-scandlines-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": {
                    "startUrls": {
                        "title": "Start URLs",
                        "type": "array",
                        "description": "Scandlines pages to scrape. Example: https://www.scandlines.com/routes",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "searchQuery": {
                        "title": "Search Query",
                        "type": "string",
                        "description": "Search for routes by keyword (e.g., 'Puttgarden', 'Rostock', 'Gedser')."
                    },
                    "maxResults": {
                        "title": "Max Results",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum number of routes/departures to return.",
                        "default": 100
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Proxy settings for reliability."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
