# Viator Reviews Scraper (`stealth_mode/viator-reviews-scraper`) Actor

Extract customer reviews from Viator.com tours and activities. Gather ratings, review text, traveler photos, helpful votes, and reviewer details. Ideal for travel agencies, tour operators, and tourism market research analyzing customer sentiment and experience quality.

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

## Pricing

from $2.00 / 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/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

## Viator Reviews Scraper: Extract Tour and Activity Customer Feedback

### Understanding Viator Reviews and Their Business Value

Viator, a TripAdvisor company, hosts millions of reviews for tours, activities, and experiences worldwide. These reviews contain authentic customer feedback about tour quality, guide performance, value for money, and overall experience—critical intelligence for tour operators, travel agencies, and destination marketers.

Reviews reveal what truly matters to travelers: timing issues, accessibility concerns, guide expertise, group sizes, and unexpected highlights. For businesses, this data powers competitive analysis, service improvement, and reputation management. The Viator Reviews Scraper automates collecting this valuable feedback into structured datasets ready for sentiment analysis, trend identification, or quality monitoring.

### What This Scraper Extracts

The scraper processes individual tour/activity URLs from Viator, extracting all customer reviews from each listing. Unlike manual collection, it captures complete review metadata including ratings, helpful votes, reviewer profiles, and response data.

**Key Data Fields:**

**Rating:** Numerical score (typically 1-5 stars) showing overall satisfaction. Essential for calculating average ratings and identifying satisfaction trends.

**Title & Review Body:** Review headline and full text content. The body contains detailed experiences, specific praise, complaints, and recommendations. Critical for sentiment analysis and identifying recurring themes.

**Published:** Review publication date enabling trend analysis over time, seasonal pattern identification, and freshness assessment.

**Helpful Votes:** Number of users who found the review helpful. High helpful votes indicate particularly valuable feedback worth prioritizing in analysis.

**Is Helpful:** Boolean flag possibly indicating algorithmic helpfulness assessment beyond user votes.

**Reviewer:** User profile information including username, location, and contribution history. Helps assess reviewer credibility and analyze demographic patterns.

**Party Type:** Travel group composition (solo, couple, family, friends). Crucial for segmenting feedback by traveler type and tailoring services accordingly.

**Photos:** Customer-uploaded images providing visual evidence of experiences. Useful for quality verification and marketing content.

**Owner Response:** Tour operator's reply to review. Tracks engagement levels and resolution of complaints, indicating customer service quality.

**Machine Translated & Machine Translation Provider:** Flags indicating auto-translated content. Important for understanding original language and considering translation accuracy in analysis.

**Is Provided by TripAdvisor:** Indicates cross-posted reviews from TripAdvisor platform.

**ID & Search Meta:** Unique identifiers and metadata for database integration and deduplication.

### Input Configuration

The scraper targets individual Viator tour/activity pages containing reviews.

**Example Configuration:**

```json
{
  "product_code": "6506LONHOHO",
  "sort_by": "DATE",
  "offset": 0,
  "ignore_url_failures": true,
  "max_items_per_url": 50
}
````

**Parameters:**

**product\_code:** Product code (product code on viator.com product review page url, e.g. tours/London/Big-Bus-London-Hop-On-Hop-Off-Tour-with-Optional-River-Cruise/d737-6506LONHOHO -> 6506LONHOHO)",

**sort\_by:** Review sorting method:

- `ML_SORTED` (Most insightful) - Algorithm-ranked helpful reviews
- `DATE` (Most recent) - Newest reviews first
- `RATING` (Highest rating) - Best ratings first

Choose `DATE` for trend monitoring, `ML_SORTED` for quality analysis, `RATING` for highlighting positive feedback.

**offset:** Starting position for pagination. Set `0` to start from beginning. Use higher values (50, 100) to continue from specific points when collecting large review sets.

**ignore\_url\_failures:** Set `true` to continue scraping remaining URLs if some fail. Essential for batch processing where some tours may be removed or have URL changes.

**max\_items\_per\_url:** Maximum reviews to extract per tour (default 20, in example 50). Higher values collect comprehensive datasets but increase runtime. Set 100+ for complete review histories.

### Output Structure and Field Definitions

**Sample Output:**

```json
{
  "helpful_votes": 0,
  "id": "1056159397",
  "is_helpful": false,
  "is_provided_by_tripadvisor": false,
  "machine_translated": false,
  "machine_translation_provider": null,
  "owner_response": {
    "__typename": "Review",
    "id": "1056489620",
    "machine_translated": false,
    "machine_translation_provider": null,
    "party_type": null,
    "published": "2026-04-13T00:00:00Z",
    "rating": 0,
    "review_body": {
      "__typename": "TextValue",
      "locale": "en",
      "text": "Hello Jennifer_! We want to express our gratitude for your feedback! It's great to know that our tour around London was absolutely fabulous! We look forward to seeing you again soon! Wishing you a wonderful day! Alexandru from Big Bus Tours"
    },
    "reviewer": {
      "__typename": "Reviewer",
      "user_identifier_value": "28E2FCF1F33A74F128110F075393BB95",
      "username": "Customer S"
    },
    "title": {
      "__typename": "TextValue",
      "text": "Owner response"
    }
  },
  "party_type": "FRIENDS",
  "photos": {
    "__typename": "TravellerReviewPhotoSet",
    "count": 0,
    "photos": []
  },
  "published": "2026-04-11T00:00:00Z",
  "rating": 5,
  "review_body": {
    "__typename": "TextValue",
    "locale": "en",
    "text": "The best tour around London was absolutely fabulous! The commentary was wonderful. The sites were amazing and we had the most wonderful day. I highly recommend this tour."
  },
  "reviewer": {
    "__typename": "Reviewer",
    "user_identifier_value": "120939817",
    "username": "Jennifer_G"
  },
  "search_meta": null,
  "title": {
    "__typename": "TextValue",
    "text": "Big Bus Tour!"
  }
}
```

**Field Purposes:**

**Helpful Votes:** Identifies most valuable reviews for prioritization. Reviews with 20+ votes often highlight critical issues or exceptional experiences worth immediate attention.

**Party Type:** Enables segmentation analysis—families may prioritize safety, couples value romance, solo travelers seek social opportunities. Tailor marketing and service improvements accordingly.

**Photos:** Visual validation of claims. Multiple photos in positive reviews provide marketing assets; photos in negative reviews require investigation.

**Owner Response:** Tracks customer service responsiveness. Response rate and quality correlate with business reputation. Lack of responses to negative reviews signals engagement issues.

**Machine Translated:** Identifies non-English reviews requiring careful interpretation. Translation quality affects sentiment analysis accuracy.

**Published Date:** Enables time-series analysis tracking quality improvements, seasonal variations, or impact of operational changes.

### Implementation Guide

**1. Collect Tour code:** Identify Viator tours to monitor—competitors, partners, or your own listings.

**2. Configure Parameters:** Set `sort_by` based on analysis goals (recent trends = DATE, quality assessment = ML\_SORTED). Set `max_items_per_url` to 50-100 for comprehensive data or 20 for quick sampling.

**3. Execute Scrape:** Run via Apify console. Processing 5 tours with 50 reviews each typically completes in 2-3 minutes. Monitor progress in real-time.

**4. Analyze Results:** Filter by rating to identify problems (1-2 stars) and successes (5 stars). Group by party\_type to understand different traveler needs. Track helpful\_votes to prioritize actionable feedback.

**5. Export Data:** JSON for databases and analysis tools, CSV for spreadsheets and reporting, Excel for business presentations.

**Best Practices:** Schedule weekly scraping for active monitoring. Store historical data to track improvement trends. Cross-reference reviews with booking data to calculate review-to-booking conversion rates.

### Strategic Applications

**Service Quality Monitoring:** Track rating trends over time. Sudden drops signal operational issues requiring immediate investigation. Consistent 4.5+ ratings validate quality standards.

**Competitive Benchmarking:** Compare your tour ratings, review volume, and common complaints against competitors. Identify service gaps and competitive advantages.

**Guide Performance Analysis:** Extract mentions of specific guides from review text. Identify top performers for recognition and training needs for coaching.

**Seasonal Optimization:** Analyze review patterns by month. Summer complaints about overcrowding suggest capacity limits; winter praise for personalized attention indicates off-season opportunities.

**Marketing Content Mining:** High-rated reviews with photos provide authentic testimonials and user-generated content for marketing campaigns.

**Response Strategy Development:** Study owner responses (yours and competitors) to identify effective complaint resolution patterns and service recovery techniques.

**Product Development:** Recurring suggestions in reviews ("wish it included lunch," "needed more time at each stop") guide tour enhancement decisions.

### Maximizing Data Value

**Sentiment Analysis Integration:** Use review text with NLP tools to quantify sentiment beyond star ratings. Detect emotional language patterns indicating strong satisfaction or frustration.

**Photo Quality Assessment:** Analyze customer photos for authenticity signals in marketing. Poor-quality photos in positive reviews may indicate fake reviews.

**Reviewer Credibility Scoring:** Weight feedback from users with high review counts and helpful votes more heavily than one-time reviewers.

**Multi-Language Intelligence:** Even if machine-translated, reviews in various languages reveal international market perceptions and cultural preferences.

**Response Rate KPIs:** Calculate percentage of reviews receiving owner responses. Industry benchmark is 60%+ for quality-focused operators.

**Temporal Trend Analysis:** Compare recent reviews (last 3 months) with historical averages to detect quality shifts before they impact bookings.

# Actor input Schema

## `product_code` (type: `string`):

Enter product code. For example, tours/London/Big-Bus-London-Hop-On-Hop-Off-Tour-with-Optional-River-Cruise/d737-6506LONHOHO -> 6506LONHOHO)

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

Sort items by options

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

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.

## Actor input object example

```json
{
  "product_code": "6506LONHOHO",
  "ignore_url_failures": true,
  "max_items_per_url": 20
}
```

# 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 = {
    "product_code": "6506LONHOHO",
    "offset": 0,
    "ignore_url_failures": true,
    "max_items_per_url": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("stealth_mode/viator-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 = {
    "product_code": "6506LONHOHO",
    "offset": 0,
    "ignore_url_failures": True,
    "max_items_per_url": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("stealth_mode/viator-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 '{
  "product_code": "6506LONHOHO",
  "offset": 0,
  "ignore_url_failures": true,
  "max_items_per_url": 20
}' |
apify call stealth_mode/viator-reviews-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Viator Reviews Scraper",
        "description": "Extract customer reviews from Viator.com tours and activities. Gather ratings, review text, traveler photos, helpful votes, and reviewer details. Ideal for travel agencies, tour operators, and tourism market research analyzing customer sentiment and experience quality.",
        "version": "0.0",
        "x-build-id": "pIxHbcuNKTfvcsX7d"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/stealth_mode~viator-reviews-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-stealth_mode-viator-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~viator-reviews-scraper/runs": {
            "post": {
                "operationId": "runs-sync-stealth_mode-viator-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~viator-reviews-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-stealth_mode-viator-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": {
                    "product_code": {
                        "title": "Product code (product code on viator.com product review page url, e.g. tours/London/Big-Bus-London-Hop-On-Hop-Off-Tour-with-Optional-River-Cruise/d737-6506LONHOHO -> 6506LONHOHO)",
                        "type": "string",
                        "description": "Enter product code. For example, tours/London/Big-Bus-London-Hop-On-Hop-Off-Tour-with-Optional-River-Cruise/d737-6506LONHOHO -> 6506LONHOHO)"
                    },
                    "sort_by": {
                        "title": "Sort Items by",
                        "enum": [
                            "ML_SORTED",
                            "DATE",
                            "RATING"
                        ],
                        "type": "string",
                        "description": "Sort items by options"
                    },
                    "offset": {
                        "title": "Offset",
                        "type": "integer",
                        "description": "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."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
