# Booking.com Reviews Scraper - No Login, Dates and Replies (`benthepythondev/booking-reviews-scraper`) Actor

Returns Booking.com guest reviews: score, date, title, liked and disliked text, property reply, guest name and country, traveler type, room, nights, stay dates, photos and hotel name. Hotel links, ids or names; newest first with an exact cutoff date, language and keyword filters. No login.

- **URL**: https://apify.com/benthepythondev/booking-reviews-scraper.md
- **Developed by:** [Ben](https://apify.com/benthepythondev) (community)
- **Categories:** Travel, Lead generation, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## 🏨 Booking.com Reviews Scraper - No Login, Exact Dates and Property Replies

Export guest reviews from any Booking.com hotel, apartment, hostel or other property: score, review date, title, what the guest liked and disliked, the property's reply, guest name and country, traveler type, room, nights, check-in and check-out dates, guest photos and helpful votes, with the hotel's name, overall score and category scores on every row. Give hotel links, Booking.com ids or plain hotel names. Export to JSON/CSV/Excel, run on a schedule, call via API, or connect to Make, Zapier or n8n.

**Price:** $0.0012 per review on the Free plan, $0.00113 on Bronze, $0.00106 on Silver and $0.001 from Gold up ($1.20 to $1.00 per 1,000 reviews), plus $0.00005 per run start. A property without reviews, a link that leads nowhere and a filter that matches nothing cost nothing beyond the start.

### 🧭 What users of other Booking review scrapers report, and what this Actor does

| Reported in the issue tabs of the most used Booking reviews Actors | This Actor |
|---|---|
| Runs fail with "202 blocks" after many retries | It never loads hotel or search pages, which sit behind Booking.com's browser check. It reads the review list from the data service Booking.com's own pages call. In tests it took 450 requests in a row from one address without a refusal; if a request is refused, the run moves to an Apify datacenter and then a residential connection by itself. |
| The cutoff date is ignored, reviews older than the date are delivered and charged | Newest first, it saves only reviews written on or after the cutoff and stops reading the property at the first page that lies entirely before it. In a test with cutoff 2026-09-01 the oldest of 140 saved reviews was from 2026-09-01 06:15 UTC. |
| The most recent review is missing | Newest first starts at Booking.com's newest review; the default run's first row was 15 hours old. |
| No hotel name in the output | Every row carries `hotelName`, `hotelUrl`, `hotelId`, the hotel's overall score, review count and category scores. |
| The property's reply to a review is wanted | `propertyResponse` holds the reply when there is one (28% of 3,781 reviews of one Berlin hotel). |
| Missing review title | `reviewTitle` is filled when the guest wrote one (about 30% of reviews); it is left empty instead of being made up from the score. |

### 🔎 What is the Booking.com Reviews Scraper?

Booking.com shows every property's reviews in pages of 25. This Actor reads those pages directly, newest first or in any of Booking.com's other orders, and saves one row per review. It reads up to six pages of a property at once, so 1,000 reviews take about 4 seconds and a whole property with 12,156 reviews about 20 seconds (measured from a server in Germany).

#### What data does it extract?

- **Review:** id, score (1-10), date and time (UTC), title, liked text, disliked text, language, helpful votes, guest photos
- **Property reply:** the text the hotel wrote under the review
- **Guest:** name (as shown), country and country code, avatar, traveler type (Couple, Family, Solo traveler, Group) and Booking.com's guest group (`customerType`, which also marks business travelers), anonymous flag
- **Stay:** room type and room id, check-in and check-out date, number of nights, stay status (`stayed`, or not stayed and cancelled, about 0.4% of reviews)
- **Hotel:** name, Booking.com id, link, overall score, total review count, category scores (cleanliness, comfort, facilities, location, staff, value for money, free WiFi)

### ⬇️ Input

| Field | What it does |
|---|---|
| `startUrls` | Booking.com property links, any language version, with or without query parameters |
| `hotelIds` | Numeric Booking.com property ids, for example `1377073` |
| `hotelNames` | Names to look up, best with the city: `Hotel Adlon Kempinski Berlin`. The first property Booking.com suggests is used, and the log names it |
| `maxReviewsPerHotel` | Reviews saved per property (default 50) |
| `sortBy` | `NEWEST_FIRST` (default), `OLDEST_FIRST`, `MOST_RELEVANT`, `SCORE_DESC`, `SCORE_ASC` |
| `cutoffDate` | `2026-01-31` or a span like `3 months`. Newest first: only reviews on or after the date. Oldest first: only reviews before it |
| `languages` | Two-letter codes such as `en`, `de`; empty means all languages |
| `keyword` | Booking.com's own review search, for example `breakfast` |
| `travelerType` | `FAMILIES`, `COUPLES`, `GROUP_OF_FRIENDS`, `SOLO_TRAVELLERS`, `BUSINESS_TRAVELLERS` |

An empty input reads 20 reviews of a sample hotel in Berlin.

#### Example input

```json
{
  "startUrls": [{ "url": "https://www.booking.com/hotel/de/riu-plaza-berlin.html" }],
  "hotelNames": ["Hotel Adlon Kempinski Berlin"],
  "maxReviewsPerHotel": 500,
  "sortBy": "NEWEST_FIRST",
  "cutoffDate": "3 months",
  "languages": ["en", "de"]
}
```

Saved inputs of the most used Booking reviews Actor also work: `startUrls`, `maxReviewsPerHotel`, `cutoffDate` and `sortReviewsBy` (`f_recent_desc` and the other `f_…` values) are read.

### ⬆️ Output

One row per review. A real row:

```json
{
  "id": "771c3c6cd0e6e2a9",
  "hotelId": 1377073,
  "hotelName": "Riu Plaza Berlin",
  "hotelUrl": "https://www.booking.com/hotel/de/riu-plaza-berlin.html",
  "hotelRating": 8.6,
  "hotelReviews": 12156,
  "hotelRatingScores": [
    { "name": "Cleanliness", "score": 8.84, "codeName": "hotel_clean" },
    { "name": "Location", "score": 9.19, "codeName": "hotel_location" }
  ],
  "rating": 10.0,
  "reviewDate": "2026-10-20T21:37:43Z",
  "reviewTitle": "Sehr zufrieden, komme gerne wieder",
  "likedText": "Sehr gute Lage, mitten in Berlin. Alles gut erreichbar",
  "reviewLanguage": "de",
  "userName": "Klaus",
  "userLocation": "Germany",
  "userCountryCode": "de",
  "userAvatar": "https://xx.bstatic.com/static/img/review/avatars/ava-k.png",
  "isAnonymous": false,
  "travelerType": "Solo traveler",
  "customerType": "SOLO_TRAVELLERS",
  "roomInfo": "Deluxe Double Room",
  "stayRoomId": 137707302,
  "checkInDate": "2026-10-18",
  "checkOutDate": "2026-10-20",
  "numberOfNights": 2,
  "stayStatus": "stayed",
  "helpfulVotes": 0,
  "images": [],
  "reviewPage": 1,
  "startUrl": "https://www.booking.com/hotel/de/riu-plaza-berlin.html",
  "scrapedAt": "2026-10-20T22:35:39+00:00"
}
```

Fields without a value (no disliked text, no reply) are left out of that row. `propertyResponse` and `images` appear when the review has them.

### 🤖 For AI agents

No login, no cookies and no API key of Booking.com are needed. One input to copy:

```json
{ "hotelNames": ["Riu Plaza Berlin"], "maxReviewsPerHotel": 25, "sortBy": "NEWEST_FIRST" }
```

Every input is optional; the result is a flat list of review rows with the field names above.

### 💡 Use cases

- 🏨 **Hotel reputation monitoring:** a daily schedule with `cutoffDate: "1 day"` delivers only the new reviews and the replies to them.
- 📊 **Competitor benchmarking:** compare scores, category scores and complaints of the hotels around yours.
- 🧠 **Sentiment and topic analysis:** liked and disliked text come separately, which makes them easy to feed into a language model or a dashboard.
- 🧳 **Travel and market research:** where guests come from, how long they stay and which rooms they book, per property and per season.

### 📏 Limits, stated plainly

- Booking.com lists the reviews of roughly the last three years. Older reviews are not shown to anyone, so an `OLDEST_FIRST` run starts there.
- The keyword search is Booking.com's own and is loose: it also returns reviews that match by meaning or in another field (87 of 263 English reviews found for "breakfast" contained the word itself). Booking.com also limits keyword searches per address to about one every three seconds, so the Actor paces them: a keyword run reads about 500 reviews a minute instead of several thousand.
- A hotel name returns Booking.com's first suggestion. Check the log line `'<name>' -> <property>` when names are ambiguous, or use the link.
- Guest names are what Booking.com shows (usually a first name); anonymous reviews have `isAnonymous: true` and no name (52 of 15,937 in a test).
- Review texts come in the language the guest wrote them in. Booking.com's machine translation is not included.

### ❓ FAQ

**Do I need a Booking.com account or proxies?** No. The Actor uses no login and picks its connection by itself.

**How many reviews can I get per hotel?** All that Booking.com shows. A test read 12,156 of 12,156 reviews of one Berlin hotel with no repeats.

**Can it watch a hotel for new reviews?** Yes: schedule it with sort order newest first and a cutoff such as `1 day` or `1 week`. It stops reading as soon as it reaches older reviews, so such a run costs only the new reviews.

**What happens with a wrong link or a hotel without reviews?** The run ends successfully, the status message names the entry, and nothing is charged for it.

**Can I give several hotels at once?** Yes, as many as you like, mixed links, ids and names. The same property given twice is read once.

**Does it work for apartments, hostels and holiday homes?** Yes, for every property type that has a page under `booking.com/hotel/…`.

**What if a run is stopped or moved to another server?** It continues where it stopped and does not save or charge a review twice. Close to its timeout it stops on its own and says how far it got.

**How do I keep costs under control?** Set `maxReviewsPerHotel`, a cutoff date, or a maximum charge for the run; the Actor stops exactly there.

**Is it legal to scrape Booking.com reviews?** The Actor reads reviews that Booking.com shows to every visitor without login. Reviews contain names and opinions of private people: under GDPR and similar laws you need a lawful purpose, should keep only what you need and must not use the data to contact guests. Check Booking.com's terms for your use case.

### 🔗 You might also like

- [Tripadvisor Reviews Scraper](https://apify.com/benthepythondev/tripadvisor-reviews-scraper) - reviews of hotels, restaurants and attractions
- [Google Hotels Scraper](https://apify.com/benthepythondev/google-hotels-scraper) - hotel prices and booking sites
- [Google Maps Scraper](https://apify.com/benthepythondev/google-maps-business-scraper) - hotels and businesses with contacts and ratings
- [Google Maps Reviews Scraper](https://apify.com/benthepythondev/google-maps-reviews-scraper) - review snippets from Google Maps
- [Google Flights Scraper](https://apify.com/benthepythondev/google-flights-scraper) - fares and price history

**Keywords:** booking.com reviews scraper, booking reviews scraper, scrape booking.com reviews, booking.com review export, hotel reviews scraper, hotel review api, booking.com api reviews, guest reviews dataset, hotel reputation monitoring, booking.com scraper no login, hotel sentiment analysis, booking.com reviews csv, competitor hotel reviews, owner response reviews, travel reviews data, booking review cutoff date

# Actor input Schema

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

Booking.com property links such as https://www.booking.com/hotel/de/riu-plaza-berlin.html (any language version, query parameters are ignored). Hotels, apartments, hostels and other properties all work. You can also use hotel ids or names below.

## `hotelIds` (type: `array`):

Numeric Booking.com property ids, for example 1377073. Use this when you already have ids from another export.

## `hotelNames` (type: `array`):

Property names to look up on Booking.com, ideally with the city, for example 'Hotel Adlon Kempinski Berlin'. The first property Booking suggests is used; the log names the match.

## `maxReviewsPerHotel` (type: `integer`):

Maximum number of reviews saved for each property. Each review is one charged result. Booking.com lists every review of a property, so large numbers work (12,156 of 12,156 in one test).

## `sortBy` (type: `string`):

Order in which Booking.com lists the reviews. With a limit, this decides which reviews you get.

## `cutoffDate` (type: `string`):

Newest first: only reviews written on or after this date (UTC), and the run stops reading a property once it passes it. Oldest first: only reviews written before this date. A date like 2026-01-31 or a span like '3 months'. Other sort orders switch to newest first.

## `languages` (type: `array`):

Only reviews written in these languages, as two-letter codes such as en, de, fr. Leave empty for all languages.

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

Only reviews that mention this word, using Booking.com's own review search, for example 'breakfast' or 'noise'.

## `travelerType` (type: `string`):

Only reviews from this kind of guest, as Booking.com groups them.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.booking.com/hotel/de/riu-plaza-berlin.html"
    }
  ],
  "maxReviewsPerHotel": 50,
  "sortBy": "NEWEST_FIRST",
  "travelerType": "ALL"
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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.booking.com/hotel/de/riu-plaza-berlin.html"
        }
    ],
    "maxReviewsPerHotel": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("benthepythondev/booking-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 = {
    "startUrls": [{ "url": "https://www.booking.com/hotel/de/riu-plaza-berlin.html" }],
    "maxReviewsPerHotel": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("benthepythondev/booking-reviews-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 '{
  "startUrls": [
    {
      "url": "https://www.booking.com/hotel/de/riu-plaza-berlin.html"
    }
  ],
  "maxReviewsPerHotel": 50
}' |
apify call benthepythondev/booking-reviews-scraper --silent --output-dataset

```

## MCP server setup

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