# Hotels.com Reviews Scraper (`shahidirfan/hotels-com-reviews-scraper`) Actor

Extract hotel reviews from Hotels.com, including guest ratings, review text, traveler feedback, stay dates, hotel names, and locations. Perfect for hotel reputation monitoring, sentiment analysis, hospitality market research, competitor insights, and AI training datasets.

- **URL**: https://apify.com/shahidirfan/hotels-com-reviews-scraper.md
- **Developed by:** [Shahid Irfan](https://apify.com/shahidirfan) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.80 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
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

### What does Hotels.com Reviews Scraper do?

Hotels.com Reviews Scraper collects publicly available hotel reviews from Hotels.com and saves them as a structured dataset. Add one or more hotel URLs, choose a review order, and set how many reviews you want. The Actor returns review text, ratings, reviewer names, review dates, themes, management responses, photos, and direct hotel links.

Use it for hotel reputation research, competitor review tracking, destination analysis, guest sentiment datasets, and AI or RAG workflows that need real review text.

### Why use Hotels.com Reviews Scraper?

- **Structured review datasets** - Get clean fields instead of copying review pages by hand.
- **Multiple hotels in one run** - Add several hotel URLs and collect them together.
- **Flexible review order** - Sort by newest, highest rated, lowest rated, or relevance.
- **Useful context** - Capture management responses, traveler types, themes, and photos when Hotels.com publishes them.
- **Dataset exports** - Download JSON, CSV, Excel, or XML, or connect the dataset to other tools.
- **Scheduled monitoring** - Refresh hotel review data daily, weekly, or monthly with Apify schedules.

### What data can you extract from Hotels.com?

| Field                      | Description                                                 |
| -------------------------- | ----------------------------------------------------------- |
| `review_id`                | Hotels.com review identifier                                |
| `hotel_id`                 | Hotel identifier from the supplied hotel URL when available |
| `property_id`              | Hotels.com property identifier used for the review request  |
| `hotel_name`               | Hotel name returned by Hotels.com                           |
| `hotel_url`                | Hotel URL supplied in the input                             |
| `review_url`               | Hotel URL with a review anchor                              |
| `title`                    | Review title when the reviewer added one                    |
| `text`                     | Full review text                                            |
| `rating`                   | Numeric rating parsed from the review score                 |
| `rating_text`              | Rating as displayed by Hotels.com                           |
| `author`                   | Reviewer display name                                       |
| `date`                     | Review submission date as displayed by Hotels.com           |
| `locale`                   | Review language locale                                      |
| `traveler_types`           | Traveler types when available                               |
| `themes`                   | Review themes such as cleanliness or location               |
| `management_response`      | Hotel management response text                              |
| `management_response_date` | Management response date label                              |
| `photos`                   | Reviewer photo URLs and descriptions                        |
| `sort_by`                  | Review order used for the run                               |
| `scraped_at`               | ISO timestamp for when the review was collected             |
| `source`                   | Source website, always `hotels.com`                         |

### How to use Hotels.com Reviews Scraper

1. Open the Actor on Apify Store.
2. Paste one or more Hotels.com hotel URLs into **Hotel URLs**.
3. Choose a review order.
4. Set the maximum reviews and maximum pages per hotel.
5. Run the Actor.
6. Open the dataset to preview, filter, or download the reviews.

You can use full hotel URLs, hotel URLs without a slug, compact hotel IDs, or global property URLs. Examples:

- `https://www.hotels.com/ho218450/hyatt-regency-london-blackfriars-london-united-kingdom/`
- `https://www.hotels.com/ho218450/`
- `ho218450`
- `218450`
- `https://www.hotels.com/h1038731.Hotel-Information`

Tracking parameters, HTML entities such as `&amp;`, escaped slashes, and extra whitespace are cleaned automatically.

### Input Parameters

| Parameter            | Type    | Required | Default                        | Description                                                                                                                      |
| -------------------- | ------- | -------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| `startUrls`          | Array   | No       | `h1038731.Hotel-Information`   | Hotel URLs or IDs to collect reviews from                                                                                        |
| `sortBy`             | String  | No       | `NEWEST_TO_OLDEST_BY_LANGUAGE` | Review order: newest by language, highest rated, lowest rated, newest, or most relevant                                          |
| `results_wanted`     | Integer | No       | `100`                          | Maximum reviews to save across all hotels. Use `0` for all available reviews                                                     |
| `max_pages`          | Integer | No       | `20`                           | Maximum review pages requested per hotel                                                                                         |
| `proxyConfiguration` | Object  | No       | Residential Apify Proxy        | Apify Proxy or custom proxy settings. Residential proxies are enabled by default because Hotels.com limits shared datacenter IPs |

### Output Data

| Field                      | Type   | Description                    |
| -------------------------- | ------ | ------------------------------ |
| `review_id`                | String | Review identifier              |
| `hotel_id`                 | String | Hotel ID from the input URL    |
| `property_id`              | String | Property ID used by Hotels.com |
| `hotel_name`               | String | Hotel name                     |
| `hotel_url`                | String | Hotel URL from the input       |
| `review_url`               | String | Hotel URL with a review anchor |
| `title`                    | String | Review title                   |
| `text`                     | String | Review body                    |
| `rating`                   | Number | Numeric rating                 |
| `rating_text`              | String | Rating label                   |
| `author`                   | String | Reviewer name                  |
| `date`                     | String | Review date                    |
| `locale`                   | String | Review locale                  |
| `traveler_types`           | Array  | Traveler types                 |
| `themes`                   | Array  | Review themes                  |
| `management_response`      | String | Management response            |
| `management_response_date` | String | Management response date       |
| `photos`                   | Array  | Reviewer photos                |
| `sort_by`                  | String | Review order used              |
| `scraped_at`               | String | Collection timestamp           |
| `source`                   | String | Source website                 |

Fields that are not published for a review are removed from the record instead of being saved as null.

### Usage Examples

#### Collect recent reviews from one hotel

Use one hotel URL and keep the default newest-first order.

```json
{
    "startUrls": ["https://www.hotels.com/ho218450/hyatt-regency-london-blackfriars-london-united-kingdom/"],
    "sortBy": "NEWEST_TO_OLDEST_BY_LANGUAGE",
    "results_wanted": 100,
    "max_pages": 5
}
```

#### Collect highly rated reviews from several hotels

Add multiple hotel URLs and sort by rating.

```json
{
    "startUrls": [
        "https://www.hotels.com/ho218450/hyatt-regency-london-blackfriars-london-united-kingdom/",
        "https://www.hotels.com/ho113320/the-royal-horseguards-london-united-kingdom/"
    ],
    "sortBy": "HIGHEST_TO_LOWEST_RATED",
    "results_wanted": 250,
    "max_pages": 10
}
```

#### Collect all available reviews with a residential proxy

Set the review limit to `0` and keep the default residential proxy for a larger run. The example sets it explicitly.

```json
{
    "startUrls": ["https://www.hotels.com/ho218450/hyatt-regency-london-blackfriars-london-united-kingdom/"],
    "sortBy": "NEWEST_TO_OLDEST",
    "results_wanted": 0,
    "max_pages": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": ["RESIDENTIAL"]
    }
}
```

### Sample Output

```json
{
    "review_id": "6a4a6bd40e56584730850ea9",
    "hotel_id": "218450",
    "property_id": "1038731",
    "hotel_name": "Hyatt Regency London Blackfriars",
    "hotel_url": "https://www.hotels.com/ho218450/hyatt-regency-london-blackfriars-london-united-kingdom/",
    "review_url": "https://www.hotels.com/ho218450/hyatt-regency-london-blackfriars-london-united-kingdom/#review-6a4a6bd40e56584730850ea9",
    "text": "Great location, clean room",
    "rating": 10,
    "rating_text": "10/10 Exceptional",
    "author": "Chiawen",
    "date": "Jul 5, 2026",
    "locale": "en_US",
    "management_response": "Thank you for taking the time to share your wonderful feedback.",
    "management_response_date": "Response from Management on Jul 17, 2026",
    "sort_by": "NEWEST_TO_OLDEST_BY_LANGUAGE",
    "scraped_at": "2026-10-23T10:30:00.000Z",
    "source": "hotels.com"
}
```

The management response is shortened for readability.

### Tips for Best Results

- Use complete hotel URLs when possible. They are easier to verify and keep in your records.
- Start with a small `results_wanted` value to check the output before running a large job.
- Use `max_pages` as a safety limit. One page contains up to 50 reviews.
- Residential Apify Proxy is enabled by default. Keep it for large runs or repeated schedules because Hotels.com limits shared datacenter IPs.
- If a hotel has no published reviews, the run can finish with an empty dataset for that hotel. Check the hotel page before assuming the Actor failed.
- Review text and management responses can be long. Use the dataset table for a quick preview and download CSV or JSON for full analysis.

### Integrations

- **Google Sheets** - Send review datasets to a spreadsheet for filtering and reporting.
- **Webhooks** - Trigger a workflow after a run finishes.
- **Make or Zapier** - Connect review data to no-code automations.
- **Apify API** - Fetch datasets programmatically from your own application.
- **CSV, Excel, JSON, XML** - Download results in the format your team already uses.

### Frequently Asked Questions

#### Can I export Hotels.com reviews to CSV or Excel?

Yes. Apify datasets can be downloaded as CSV, Excel, JSON, XML, and other supported formats from the run page.

#### Can I collect reviews from more than one hotel?

Yes. Add multiple hotel URLs to `startUrls`. The Actor processes them in one run and combines the reviews in the default dataset.

#### Can I run this Actor on a schedule?

Yes. Create an Apify schedule for daily, weekly, or monthly runs. Keep the residential proxy enabled for recurring jobs.

#### How many reviews can I collect?

The Actor can collect up to the total number of reviews Hotels.com publishes for a hotel. Use `results_wanted` to cap the dataset and `max_pages` to cap requests per hotel.

#### Why are some review fields missing?

Hotels.com does not publish every field for every review. Empty titles, missing themes, missing photos, and missing management responses are normal. The Actor removes fields that have no value.

#### Why did a hotel return no reviews?

The hotel may have no published reviews, the URL may point to a different property, or Hotels.com may have limited the request. Check the hotel page and run logs, then retry with a new residential proxy session.

#### Does this Actor support hotel IDs?

Yes. You can use full hotel URLs, URLs without a slug, compact IDs such as `ho218450`, or global property URLs such as `h1038731.Hotel-Information`.

#### Is it legal to scrape Hotels.com reviews?

Scraping public web data can be legal, but rules vary by location and use case. You are responsible for complying with applicable laws, website terms, and privacy rules.

### Support

For issues, feature requests, or custom Actor work, use the Issues tab on the Actor page or contact the developer through Apify.

### Legal Notice

This Actor is designed for legitimate collection of publicly available review data. Users are responsible for using the data responsibly and complying with applicable laws and website terms.

# Actor input Schema

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

Hotels.com hotel URLs or IDs. Tracking parameters, HTML entities such as &, and extra whitespace are cleaned automatically. Examples: https://www.hotels.com/ho218450/..., https://www.hotels.com/h1038731.Hotel-Information, ho218450, or 218450.

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

Order in which reviews are collected.

## `results_wanted` (type: `integer`):

Maximum number of reviews to save across all hotels. Set to 0 to collect every available review.

## `max_pages` (type: `integer`):

Safety limit on the number of review pages requested for each hotel.

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

Residential Apify Proxy is enabled by default because Hotels.com limits shared datacenter IPs. Change or disable it if you use your own proxies.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.hotels.com/h1038731.Hotel-Information"
  ],
  "sortBy": "NEWEST_TO_OLDEST_BY_LANGUAGE",
  "results_wanted": 100,
  "max_pages": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `overview` (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": [
        "https://www.hotels.com/h1038731.Hotel-Information"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("shahidirfan/hotels-com-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": ["https://www.hotels.com/h1038731.Hotel-Information"] }

# Run the Actor and wait for it to finish
run = client.actor("shahidirfan/hotels-com-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": [
    "https://www.hotels.com/h1038731.Hotel-Information"
  ]
}' |
apify call shahidirfan/hotels-com-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,shahidirfan/hotels-com-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/1MUY0rZb8f9zbkjQi/builds/Wlg3ZJaDmBgRZGpgU/openapi.json
