# Booking.com Review Scraper (`plowdata/booking-com-review-scraper`) Actor

🏨 Scrape detailed reviews from hotels, apartments, and other listings on Booking.com  — including review text, star ratings, guest details, room info, stay dates, and more. All data is schema-validated and exportable as JSON, CSV, Excel, or HTML for reliable and structured analysis.

- **URL**: https://apify.com/plowdata/booking-com-review-scraper.md
- **Developed by:** [Frederic](https://apify.com/plowdata) (community)
- **Categories:** Travel, SEO tools, Lead generation
- **Stats:** 417 total users, 38 monthly users, 100.0% runs succeeded, 8 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.85 / 1,000 reviews

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

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

🌐 Booking.com Reviews Scraper

Extract deep insights from Booking.com listings – reviews, scores, guest details, and more, all through a fast and robust API-first architecture 🚀
This scraper is a powerful tool designed to extract detailed reviews from Booking.com listings. You can get reviews from any hotel, apartment, or accommodation listed on [booking.com](https://www.booking.com/). Just enter one (or many) hotel URLs and click **"Save & Start"**.

Great for:

- 🧬 Market research & trend analysis
- 📈 Competitor monitoring
- 👩‍🏫 Review tracking for your own listings
- 🤖 Feeding clean review data into your apps or ML models

### 🔍 What data do you get?

| Data type       | Description                                                                                                                   |
|:---------------:|:-----------------------------------------------------------------------------------------------------------------------------:|
| User-Review     | Title, positive & negative text, score, date, upvotes, language, and attached photos 										  |
| Booking info    | Room type, number of nights, customer type (e.g. family, solo, business) 								    				  |
| Reply    		  | Hotel reply (if available)                                                                                 				  	  |
| Guest details   | Username, country, avatar (if not anonymous)                                                   			    				  |

### 🔋 Why use this scraper?

- 🔌 **Fast**: Designed from the ground up to be fast. No browser automation = blazing speed (~30-50 reviews/sec)
- 🔍 **Powerful filters**: Sort by score, language, season, customer type & more
- 🤝 **Reliable**: Resumes where it left off, deduplicates reviews, handles most errors gracefully
- ⚙️ **Typed output**: Schema-validated for consistency & integration ease
- 🛠️ **Debug-friendly**: Built-in logs for catching edge cases quickly
- 🚀 **Multi-format export**: CSV, JSON, Excel, XML, etc.
- 🚑 **Support**: We actively maintain and improve the scraper. Found a bug? Just send logs & inputs.

### ✏️ Input fields

- `urls` (required) – List of Booking.com hotel URLs
- `sort` (optional) – Most relevant | Newest | Oldest | Score desc | Score asc
- `maxReviews` (optional) – Max number of reviews per hotel (-1 for all)
- `timeOfYear` (optional) – ALL, or specific season (Mar-May, Jun-Aug, etc.)
- `scoreRange` (optional) – ALL, or by rating bucket (Poor, Good, Wonderful, etc.)
- `languages` (optional) – List of review languages to include (e.g. en, de)
- `customerType` (optional) – Filter by reviewer group: families, business, solo, etc.

### 🔧 Output format

You get two datasets:

📃 **Reviews**
Each record includes:

- Hotel name, hotel ID
- Score, date, review title + texts
- Room type, stay duration, customer type
- Guest info (country, avatar, username)
- Photos (if available)
- Hotel reply (if available)

📊 **Scores**

- Per-hotel average scores:
- Category (location, cleanliness, etc.)
- Display name / translation
- Value + confidence interval

These are internal Booking.com metrics not always visible in the UI ✨

#### Reviews

```json

{
	"hotelId": 10221458, // Unique? ID of the hotel
	"hotelName": "Premier Inn Köln City Süd", // Name of the hotel
	
    "score": 9, // The score given by the guest
	"url": "bac28cd69950aefc", // The unique ID of the review
	"date": "2025-02-23T17:50:44.000Z", // The ISO-date when the review was written
	"helpfulVotesCount": 0, // The number of upvotes the review received
	"isApproved": true, // Whether the review was approved by booking.com
	"title": "A great choice for a stay in Cologne!", // The title of the review
	"positiveText": "I really enjoyed my ...", // The positive text of the review (cut off here, for brevity, but will be complete in the output)
	"negativeText": "The only thing missing ...", // The negative text of the review (cut off here, for brevity, but will be complete in the output)
	"lang": "en", // The original language in which the review was written
	"roomTypeId": "1022145801",
	"roomTypeName": "Standard Double Room", // The type of room the guest booked
	"numNights": 1, // How many nights the guest stayed
	"stayStatus": "stayed", // Whether the guest stayed at the hotel or if they just planned to
	"customerType": "Group of friends", // The type of customer, e.g. families, couples, business travellers, etc.
	"checkinDate": "2025-02-20T00:00:00.000Z", // The date when the guest checked in
	"checkoutDate": "2025-02-21T00:00:00.000Z", // The date when the guest checked out
	"partnerReplyText": "", // The review-reply from the hotel, if available
	"anonymous": false, // Whether the review was written anonymously or not
	"showCountryFlag": true,
	"countryCode": "pl", // The country code of the guest
	"countryName": "Poland", // The country name of the guest
	"avatarColor": "",
	"avatarUrl": "https://.../", // The URL of the avatar of the guest
	"username": "Guest", // The username of the guest
	"photos": [ // The photos attached to the review (if any)
        {
            "kind": "PROPERTY", // What the photo is about, e.g. property, room, etc.
            "urls": [ // The URLs of the photos
                "https://url-a/",
                "https://url-b/",
                ...
            ],
            "id": 464616631, // The ID of the photo
        },
		...
	]
}
```

#### Scores

This dataset contains per-hotel scores, generated internally by booking.com, as such there's only one list of scores per hotel, which contain the following properties:

```json
{
	"hotelId": 10221458, // ID of the hotel (same as in the reviews dataset)
	"hotelName": "Premier Inn Köln City Süd", // Name of the hotel (same as in the reviews dataset)

	"name": "hotel_services", // What the score is about, e.g. hotel_services, location, etc.
	"translation": "Facilities", // The translation of the score
	"lowerBound": 6.76627492904663, // The lower bound of the score
	"higherBound": 9.10307502746582, // The upper bound of the score
	"value": 8.26360607147217 // The (most likely) average score
}
```

### 👤 Who is it for?

- 🔬 **Data scientists & analysts** – For sentiment analysis, trend tracking, and training models
- 🧱 **Researchers** – Monitor competitors or markets in bulk
- 💻 **Developers** – Integrate clean review data into your systems
- 💼 **Business owners** – Keep an eye on customer feedback over time

### 🚪 Proxy setup

Booking.com blocks shared Apify proxies. Use your own datacenter or residential proxies.
Good news: this scraper is optimized to work even with **cheap datacenter** proxies, thanks to smart cookie handling and retry logic.
If you want to use your own, residential, or special proxies, you can do so by changing the `proxyConfiguration` field in the input.

***

Built with love ❤️ and way too many late-night debug logs.
Have ideas or need help? Let us know!

# Actor input Schema

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

URLs of the Hotels to scrape reviews from

## `sort` (type: `string`):

Sort the reviews, optional. Defaults to Most relevant.

## `maxReviews` (type: `integer`):

Limits the number of reviews scraped per hotel, optional. Leaving this emtpy or setting it to -1 disables filtering by this property.

## `timeOfYear` (type: `string`):

Filters the reviews by time of year, optional. ALL and leaving this emtpy disables filtering by this property.

## `scoreRange` (type: `string`):

Filters the reviews by score range, optional. ALL and leaving this emtpy disables filtering by this property.

## `language` (type: `array`):

Filters the reviews by language, optional. ALL and leaving this emtpy disables filtering by this property.

## `customerType` (type: `string`):

Filters the reviews by customer type, optional. ALL and leaving this emtpy disables filtering by this property.

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

Select proxies to be used by the scraper, defaults to the Apify Datacenter proxy.

## Actor input object example

```json
{
  "urls": [
    {
      "url": "https://www.booking.com/hotel/de/premier-inn-koln-city-sud.html"
    }
  ],
  "sort": "Most relevant",
  "maxReviews": 1000,
  "timeOfYear": "ALL",
  "scoreRange": "ALL",
  "language": [
    "ALL"
  ],
  "customerType": "ALL",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `reviews` (type: `string`):

Individual guest reviews with text, score, stay details, and guest metadata

# 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": [
        {
            "url": "https://www.booking.com/hotel/de/premier-inn-koln-city-sud.html"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("plowdata/booking-com-review-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": [{ "url": "https://www.booking.com/hotel/de/premier-inn-koln-city-sud.html" }] }

# Run the Actor and wait for it to finish
run = client.actor("plowdata/booking-com-review-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 '{
  "urls": [
    {
      "url": "https://www.booking.com/hotel/de/premier-inn-koln-city-sud.html"
    }
  ]
}' |
apify call plowdata/booking-com-review-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,plowdata/booking-com-review-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/tTRAuL9PrLC9FqWkJ/builds/e9lxT2k0qgKGOO8gV/openapi.json
