# Agoda Reviews Scraper (`plowdata/agoda-reviews-scraper`) Actor

🏨 Scrape guest reviews from Agoda hotel listings — plus mirrored Booking.com reviews from the same listing, normalized into one schema. Includes ratings, review text, room/stay details, and reviewer trust signals. Exportable as JSON, CSV, Excel, or HTML for structured analysis.

- **URL**: https://apify.com/plowdata/agoda-reviews-scraper.md
- **Developed by:** [Frederic](https://apify.com/plowdata) (community)
- **Categories:** Travel, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 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/platform/actors/running/actors-in-store#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

## 🌐 Agoda Reviews Scraper

Extract guest reviews from any Agoda hotel listing - **and the mirrored Booking.com reviews shown on the same page** - normalized into one clean, pay-per-result dataset 🚀

Just enter one (or many) Agoda hotel URLs and click **"Save & Start"**.

Great for:

- 🧬 Market research & trend analysis across two review pools at once
- 📈 Competitor monitoring (your hotel, or theirs)
- 🤝 Reviewer trust analysis - expert reviewers, review history, and vote counts
- 🤖 Feeding clean, structured review data into apps or ML pipelines

### 🔍 What makes this different?

Most Agoda hotel pages quietly show reviews from **two sources**: Agoda's own guests, and a mirrored set of Booking.com reviews for the same property. This scraper pulls both - tagged with a `provider` field - so you get full review coverage from a single run instead of needing two separate scrapers.

### 🔋 Why use this scraper?

- 🔌 **Fast**: HTTP-first architecture, no browser automation
- 🔍 **Dual-source**: Agoda + mirrored Booking.com reviews, one unified schema
- 🤝 **Reviewer trust signals**: expert reviewer flag, reviewer's total review count, and *both* helpful and unhelpful vote counts - most competing scrapers only expose one vote direction, if any
- 🧹 **Strictly deduplicated**: every review is tracked by ID per hotel, so re-runs or overlapping pages never produce duplicate rows - you only ever pay for unique reviews
- ⏱️ **Smart pagination cutoff**: Agoda's reviews start repeating themselves past a certain depth per hotel. We detect that point and stop automatically, so you're never billed for fetching the same reviews twice
- 💸 **Datacenter-proxy friendly**: built with careful cookie and session handling, so you don't need to pay for expensive residential proxies to get reliable results
- ⚙️ **Typed output**: schema-validated for consistency & integration ease
- 🚀 **Multi-format export**: CSV, JSON, Excel, XML, etc.

### ✏️ Input fields

- `urls` (required) – List of Agoda hotel URLs
- `allowBookingReviews` (optional, default `true`) – Also include mirrored Booking.com reviews for the same listing
- `maxReviews` (optional) – Max number of reviews per hotel (unlimited by default)
- `maxReviewsPerSource` (optional) – Max number of reviews per hotel and provider (unlimited by default)
- `sorting` (optional) – Most helpful | Most recent | Score high-to-low | Score low-to-high
- `customerType` (optional) – Filter by reviewer group: business, couples, solo, family, groups, etc.

When multiple limits are set, the one that's hit first takes precedence, e.g. in a situation where a hotel has `100` reviews from
Agoda and `400` from booking.com, the number of results is determined like this:

- `maxReviews=200` - scrapes the first `100` reviews from Agoda, then the first `100` from booking.com
- `maxReviewsPerSource=50` - scrapes the first `50` reviews from Agoda, then the first `50` from booking.com
- `maxReviews=80` and `maxReviewsPerSource=50` - scrapes the first `50` reviews from Agoda, then the first `30` from booking.com

### 🔧 Output format

Each record is a single review, normalized across both providers:

```json
{
  "reviewId": 123456789,
  "provider": "agoda",
  "hotelId": 987654,
  "hotelName": "Wombat's The City Hostel Munich",
  "hotelUrl": "https://www.agoda.com/wombat-s-the-city-hostel-munich-werksviertel/hotel/munich-de.html",

  "rating": 8.6,
  "ratingLabel": "Excellent",

  "title": "Great location and friendly staff",
  "review": "Overall a really pleasant stay...",
  "positiveText": "Staff were super helpful, clean rooms",
  "negativeText": "Breakfast options were limited",

  "date": "2025-02-23T17:50:44.000Z",
  "checkInDate": "2025-02-20T00:00:00.000Z",
  "checkOutDate": "2025-02-21T00:00:00.000Z",
  "numNights": 1,
  "roomTypeName": "Standard Double Room",
  "customerType": "solo",

  "username": "Guest",
  "countryName": "Poland",
  "isExpertReviewer": true,
  "reviewerReviewedCount": 14,

  "helpfulVotes": 3,
  "unhelpfulVotes": 0,

  "scrapedAt": "2025-06-21T10:00:00.000Z"
}
```

### 👤 Who is it for?

- 🔬 **Data scientists & analysts** – Sentiment analysis and trend tracking across two review sources
- 🧱 **Researchers** – Monitor competitors or markets in bulk
- 💻 **Developers** – Integrate clean, deduplicated review data into your systems
- 💼 **Business owners** – Keep an eye on guest feedback across both Agoda and Booking.com audiences

### 💬 Support

Questions, edge cases, or feature requests? Open a support ticket or attach a failing run log - we'll take care of it.

# Actor input Schema

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

URLs of the Hotels to scrape reviews from

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

Customer type to fetch reviews for

## `sorting` (type: `string`):

Sorting order for reviews

## `allowBookingReviews` (type: `boolean`):

Whether to fetch reviews from Booking.com (if available) in addition to Agoda reviews

## `maxReviews` (type: `number`):

Max reviews to fetch per hotel (-1 for unlimited)

## `maxReviewsPerSource` (type: `integer`):

Limits the number of reviews per provider, set to -1 to disable.

## `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.agoda.com/de-de/vi-vadi-hotel-downtown-munich/hotel/munich-de.html"
    }
  ],
  "customerType": "all",
  "sorting": "most-helpful",
  "allowBookingReviews": true,
  "maxReviews": -1,
  "maxReviewsPerSource": -1,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Array of review objects with details like reviewer name, rating, review text, date, etc.

# 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.agoda.com/de-de/vi-vadi-hotel-downtown-munich/hotel/munich-de.html"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("plowdata/agoda-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": [{ "url": "https://www.agoda.com/de-de/vi-vadi-hotel-downtown-munich/hotel/munich-de.html" }] }

# Run the Actor and wait for it to finish
run = client.actor("plowdata/agoda-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": [
    {
      "url": "https://www.agoda.com/de-de/vi-vadi-hotel-downtown-munich/hotel/munich-de.html"
    }
  ]
}' |
apify call plowdata/agoda-reviews-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/kvx3pibWKvngsDJ4O/builds/bC29bIJSXXsdLLAv8/openapi.json
