# Kayak Reviews Scraper (`stealth_mode/kayak-reviews-scraper`) Actor

Scrape hotel reviews from KAYAK.com/hotelscombined.com effortlessly. Collect scores, reviewer comments, ratings, author info, and source details — up to 200 reviews per hotel URL. Perfect for hospitality analysts, OTA researchers, and reputation managers.

- **URL**: https://apify.com/stealth\_mode/kayak-reviews-scraper.md
- **Developed by:** [Stealth mode](https://apify.com/stealth_mode) (community)
- **Categories:** Automation, Developer tools, Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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 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

## KAYAK.com Reviews Scraper: Extract Hotel Reviews at Scale

---

### What Is KAYAK.com/hotelscombined.com?

KAYAK.com is one of the world's most visited travel metasearch platforms, aggregating hotel listings, flight deals, and car rentals from hundreds of booking sites. Its hotel review system compiles ratings from multiple sources — including internal KAYAK reviews and third-party platforms — into a single, unified view. For hotels, analysts, and researchers, this aggregated review data is highly valuable but difficult to collect manually at scale.

The **KAYAK Reviews Scraper** automates this process, turning hotel detail pages into structured review datasets ready for analysis.

---

### Overview

This scraper targets KAYAK hotel detail pages and extracts every available review record, including scores, sentiment comments, reviewer identity, and the originating review platform. It supports keyword filtering and flexible sorting, making it suitable for:

- **Hotel managers** monitoring guest sentiment and reputation
- **OTA analysts** benchmarking properties across review sources
- **Travel researchers** studying rating patterns across markets
- **Data engineers** building hospitality intelligence pipelines

---

### Input Format

```json
{
  "ignore_url_failures": true,
  "max_items_per_url": 200,
  "offset": 10,
  "urls": [
    "https://www.kayak.com/hotels/Hotel-La-Comtesse,Paris-p37687-h35830-details/2026-05-27/2026-05-28/2adults?psid=sMGEBt7Vjb&pm=nightly-total",
    "https://www.hotelscombined.com/hotels/Hotel-Pas-de-Calais,Paris-p37687-h10778-details/2026-05-27/2026-05-28/2adults?psid=sXGkC_TjUj&pm=nightly-base"
  ],
  "sort_by": "scoreDesc",
  "keyword": "hotel"
}
````

| Field | Type | Description |
|---|---|---|
| `urls` | `array` | KAYAK/hotelscombined hotel detail page URLs. Paste one per line or use Bulk edit. Include check-in/check-out dates in the URL as shown in the example. |
| `max_items_per_url` | `integer` | Maximum reviews to collect per URL. Default: `20`. Set up to `200` for comprehensive coverage. |
| `offset` | `integer` | Number of reviews to skip before collecting. Default: `0`. Useful for pagination or resuming partial runs. |
| `sort_by` | `string` | Sort order for reviews. Options: `recent` (newest first), `scoreDesc` (highest rating), `scoreAsc` (lowest rating), `oldest` (oldest first). |
| `keyword` | `string` | Filter reviews containing a specific keyword (e.g., `"breakfast"`, `"pool"`, `"staff"`). Leave empty to collect all reviews. |
| `ignore_url_failures` | `boolean` | If `true`, skips failed URLs and continues the run instead of stopping. Recommended for bulk runs. |

> **Tip:** The URL must be a hotel *detail* page (`/details/` path), not a search results page. Include valid dates to ensure the page loads correctly.

***

### Output Format

#### Sample Record

```json
{
  "id": "YFQxUZ4BP7687hA130ww",
  "localized_month_year": "May 2026",
  "score": 100,
  "localized_rating_category": "Excellent",
  "positive_comment": "A lovely stay at Hôtel La Comtesse in Cluny. The location is central, quiet, and ideal, especially as we were close to friends. The room was very clean, the bed was excellent, and check‑in/out was simple. Francois was incredibly helpful with clear information throughout. A perfect base for discovering the beautiful, historic village of Cluny.",
  "negative_comment": null,
  "author": "Etienne",
  "site_link": "https://www.kayak.com/out?url=http%3A%2F%2Fwww.booking.com%2Fhotel%2Ffr%2Fhotel-la-comtesse-by-elegancia.en.html%3Ftab%3D4%26aid%3D351149%26utm_source%3Dmetakayak%26utm_medium%3Ddsk-review%26utm_campaign%3Dus%26utm_term%3Dhotel-53978%26utm_content%3Dlos-02_nrm-01_gst-02%26label%3Dmetakayak-linkdsk-reviewus-hotel-53978_xqdz-ffffffffffffffffffffff_los-02_bw-030_curr-USD_nrm-01_gst-02_lang-en-us_clkid-xxxxxx&trackClickOut=true&h=TM1EypPo-FswCGEnuUnMaLl9AwY&hid=35830&prv=booking&type=review",
  "site_name": "Booking.com",
  "site_logo": "/provider-logos/hotels/reviews/h/bookingLogo.png",
  "internal": false,
  "localized_score": "100.0",
  "from_url": "https://www.kayak.com/hotels/Hotel-La-Comtesse,Paris-p37687-h35830-details/2026-05-27/2026-05-28/2adults?psid=sMGEBt7Vjb&pm=nightly-total"
}
```

Each review record contains the following fields:

#### Review Identity & Score

| Field | Meaning |
|---|---|
| `ID` | Unique identifier for the review record |
| `Score` | Numeric rating given by the reviewer (e.g., `8.5`) |
| `Localized Score` | Score formatted for the listing's locale (e.g., `"8.5/10"`) |
| `Localized Rating Category` | Text label corresponding to the score (e.g., `"Very Good"`, `"Excellent"`) |
| `Localized Month Year` | Display-formatted date of the review (e.g., `"May 2026"`) |

#### Review Content

| Field | Meaning |
|---|---|
| `Positive Comment` | Reviewer's positive feedback text |
| `Negative Comment` | Reviewer's criticism or suggestions for improvement |

> Both comment fields may be empty depending on the review source or reviewer input.

#### Reviewer & Source

| Field | Meaning |
|---|---|
| `Author` | Display name of the reviewer |
| `Site Name` | Name of the platform that originally published the review (e.g., `"Booking.com"`, `"KAYAK"`) |
| `Site Logo` | URL of the source platform's logo image |
| `Site Link` | Direct link back to the original review on the source platform |
| `Internal` | Boolean — `true` if the review was submitted directly on KAYAK, `false` if aggregated from a third-party source |

***

### How to Use

1. **Get the hotel URL** — Open a hotel detail page on KAYAK.com (URL must contain `/details/`). Include check-in and check-out dates.
2. **Configure the input** — Paste the URL into `urls`. Set `max_items_per_url` to your desired limit.
3. **Apply filters (optional)** — Use `keyword` to target specific topics (e.g., `"wifi"`, `"cleanliness"`), and `sort_by` to prioritize relevant reviews.
4. **Set offset if resuming** — Use `offset` to skip already-collected reviews when continuing a previous run.
5. **Run and export** — Download results as JSON, CSV, or Excel.

**Common issues:**

- A URL returning no results usually means it is a search/listing page, not a detail page.
- If dates in the URL are in the past, the page may not load reviews — use future or current dates.

***

### Use Cases & Business Value

- **Reputation management:** Aggregate multi-source reviews for a property into one dataset
- **Sentiment analysis:** Feed `Positive Comment` and `Negative Comment` fields into NLP pipelines
- **Competitive benchmarking:** Compare scores across hotels in the same market
- **Review sourcing audit:** Use the `Internal` flag and `Site Name` to understand where ratings originate

***

### Conclusion

The **KAYAK Reviews Scraper** delivers structured, multi-source hotel review data with minimal setup. With keyword filtering, sort control, and 12 output fields per review, it provides everything needed for serious hospitality research and reputation analysis. Run it against any KAYAK hotel detail page and export results instantly.

# Actor input Schema

## `urls` (type: `array`):

Add the URLs of the hotels details urls you want to scrape. You can paste URLs one by one, or use the Bulk edit section to add a prepared list.

## `keyword` (type: `string`):

Enter keyword to search for reviews

## `sort_by` (type: `string`):

Select your option to sort reviews

## `offset` (type: `integer`):

The offset to start from

## `ignore_url_failures` (type: `boolean`):

If true, the scraper will continue running even if some URLs fail to be scraped.

## `max_items_per_url` (type: `integer`):

The maximum number of items to scrape per URL.

## `proxy` (type: `object`):

Select proxies to be used by your scraper.

## Actor input object example

```json
{
  "urls": [
    "https://www.kayak.com/hotels/Hotel-La-Comtesse,Paris-p37687-h35830-details/2026-05-27/2026-05-28/2adults?psid=sMGEBt7Vjb&pm=nightly-total"
  ],
  "ignore_url_failures": true,
  "max_items_per_url": 20,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "NL"
  }
}
```

# 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 = {
    "urls": [
        "https://www.kayak.com/hotels/Hotel-La-Comtesse,Paris-p37687-h35830-details/2026-05-27/2026-05-28/2adults?psid=sMGEBt7Vjb&pm=nightly-total"
    ],
    "keyword": "",
    "offset": 0,
    "ignore_url_failures": true,
    "max_items_per_url": 20,
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "NL"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("stealth_mode/kayak-reviews-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 = {
    "urls": ["https://www.kayak.com/hotels/Hotel-La-Comtesse,Paris-p37687-h35830-details/2026-05-27/2026-05-28/2adults?psid=sMGEBt7Vjb&pm=nightly-total"],
    "keyword": "",
    "offset": 0,
    "ignore_url_failures": True,
    "max_items_per_url": 20,
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "NL",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("stealth_mode/kayak-reviews-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 '{
  "urls": [
    "https://www.kayak.com/hotels/Hotel-La-Comtesse,Paris-p37687-h35830-details/2026-05-27/2026-05-28/2adults?psid=sMGEBt7Vjb&pm=nightly-total"
  ],
  "keyword": "",
  "offset": 0,
  "ignore_url_failures": true,
  "max_items_per_url": 20,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "NL"
  }
}' |
apify call stealth_mode/kayak-reviews-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Kayak Reviews Scraper",
        "description": "Scrape hotel reviews from KAYAK.com/hotelscombined.com effortlessly. Collect scores, reviewer comments, ratings, author info, and source details — up to 200 reviews per hotel URL. Perfect for hospitality analysts, OTA researchers, and reputation managers.",
        "version": "0.0",
        "x-build-id": "qbkA8mzrEy8UWpUgM"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/stealth_mode~kayak-reviews-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-stealth_mode-kayak-reviews-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/stealth_mode~kayak-reviews-scraper/runs": {
            "post": {
                "operationId": "runs-sync-stealth_mode-kayak-reviews-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/stealth_mode~kayak-reviews-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-stealth_mode-kayak-reviews-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": {
                    "urls": {
                        "title": "URLs of the hotels details urls to scrape",
                        "type": "array",
                        "description": "Add the URLs of the hotels details urls you want to scrape. You can paste URLs one by one, or use the Bulk edit section to add a prepared list.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "keyword": {
                        "title": "Keyword to search for reviews",
                        "type": "string",
                        "description": "Enter keyword to search for reviews"
                    },
                    "sort_by": {
                        "title": "Sort by",
                        "enum": [
                            "recent",
                            "scoreDesc",
                            "scoreAsc",
                            "oldest"
                        ],
                        "type": "string",
                        "description": "Select your option to sort reviews"
                    },
                    "offset": {
                        "title": "Offset",
                        "type": "integer",
                        "description": "The offset to start from"
                    },
                    "ignore_url_failures": {
                        "title": "Continue running even if some URLs fail to be scraped",
                        "type": "boolean",
                        "description": "If true, the scraper will continue running even if some URLs fail to be scraped."
                    },
                    "max_items_per_url": {
                        "title": "Max items per URL",
                        "type": "integer",
                        "description": "The maximum number of items to scrape per URL."
                    },
                    "proxy": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Select proxies to be used by your scraper."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
