# TripAdvisor Scraper – Hotels, Restaurants & Reviews (`khadinakbar/tripadvisor-scraper`) Actor

Extract hotels, restaurants, and attractions from TripAdvisor — including ratings, contact info, amenities, and reviews — from search queries or direct URLs. MCP/API-ready.

- **URL**: https://apify.com/khadinakbar/tripadvisor-scraper.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** Travel, Lead generation, MCP servers
- **Stats:** 9 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 listing scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## TripAdvisor Scraper – Hotels, Restaurants & Reviews

TripAdvisor Scraper is an Apify Actor for travel, lead generation, and MCP workflows that accepts either search queries or direct TripAdvisor URLs. It returns one dataset record per scraped listing or review, so each item represents one hotel, restaurant, attraction, or review entry. Listing records can include name, category, address, city, country, phone, website, rating, review count, price range, ranking, amenities, cuisines, awards, coordinates, and TripAdvisor URLs. Review records can include the linked listing name and URL, review title, text, date of stay, travel type, reviewer details, helpful votes, owner response, published date, and source URL.

### Best fit and connected workflows

Use this Actor when you want TripAdvisor data in a structured dataset that is ready for analysis, enrichment, or automation.

It fits well when you want to:

- turn a destination search like "hotels in Miami" into a set of listing URLs and scraped records
- start from a known TripAdvisor Hotel\_Review, Restaurant\_Review, or Attraction\_Review URL and extract listing data
- collect review records for a specific property from provided TripAdvisor listing URLs
- feed structured travel data into CRM, enrichment, monitoring, or agent workflows
- use an Apify Actor through Apify MCP, with a consistent record shape that is easy to interpret

### Focused standalone workflow

This Actor is designed as a focused standalone workflow.

#### One practical scenario

A travel analyst opens Apify with the starting query "restaurants in Paris 1st arrondissement". They run the Actor in `listings_and_reviews` mode with a small result cap. The returned dataset includes restaurant names, ratings, review counts, price ranges, and TripAdvisor URLs. For restaurants with reviews enabled, the analyst also sees review title, text, travel type, reviewer name, and published date. Based on those fields, the analyst decides which venues to shortlist for deeper review analysis, then exports the dataset to compare reputation and contact details across the target area.

### Input fields

| Field | Type | Purpose | Default |
|---|---|---|---|
| `searchQueries` | array of strings | Search terms such as "hotels in Miami" or "restaurants in Paris" | `[]` |
| `startUrls` | array of request objects | Direct TripAdvisor listing URLs, including Hotel\_Review, Restaurant\_Review, and Attraction\_Review pages | `[]` |
| `scrapeMode` | string | `listings_and_reviews`, `listings_only`, or `reviews_only` | `listings_and_reviews` |
| `maxResults` | integer | Maximum number of listing pages to scrape | `10` |
| `maxReviewsPerListing` | integer | Maximum reviews collected per listing when reviews are included | `20` |
| `proxyConfiguration` | object | Apify Proxy configuration | Residential proxy preset |

#### Focused input example

```json
{
  "searchQueries": ["hotels in New York City"],
  "scrapeMode": "listings_and_reviews",
  "maxResults": 5,
  "maxReviewsPerListing": 10,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

### Output fields

TripAdvisor Scraper writes records to the default dataset. Use `record_type` to separate listing and review items.

| Field | Type | Meaning |
|---|---|---|
| `record_type` | string | `listing` or `review` |
| `name` | string or null | Name of the hotel, restaurant, or attraction |
| `category` | string or null | TripAdvisor top-level category |
| `subcategory` | string or null | More specific type within the category |
| `address` | string or null | Full street address |
| `city` | string or null | City |
| `country` | string or null | Country |
| `phone` | string or null | Listed phone number |
| `website` | string or null | External website URL |
| `rating` | number or null | TripAdvisor rating |
| `review_count` | integer or null | Total review count |
| `price_range` | string or null | `$`, `$$`, `$$$`, or `$$$$` |
| `price_level` | integer or null | Numeric price level |
| `ranking` | string or null | Ranking text |
| `ranking_position` | integer or null | Numeric ranking position |
| `ranking_total` | integer or null | Total in the category and location |
| `description` | string or null | TripAdvisor description |
| `amenities` | array | Listing amenities |
| `cuisines` | array | Restaurant cuisine types |
| `awards` | array | TripAdvisor awards |
| `latitude` | number or null | Latitude coordinate |
| `longitude` | number or null | Longitude coordinate |
| `photos_count` | integer or null | Total photos on the listing |
| `tripadvisor_id` | string or null | Location ID from the URL `d` parameter |
| `tripadvisor_url` | string | Direct TripAdvisor listing URL |
| `listing_name` | string or null | Property name on review records |
| `listing_url` | string or null | TripAdvisor URL for the reviewed property |
| `title` | string or null | Review title |
| `text` | string or null | Review text |
| `date_of_stay` | string or null | Date of stay |
| `travel_type` | string or null | Travel party type |
| `reviewer_name` | string or null | Reviewer username |
| `reviewer_location` | string or null | Reviewer home location |
| `helpful_votes` | integer or null | Helpful vote count |
| `owner_response` | string or null | Management response |
| `published_date` | string or null | Review publish date |
| `scraped_at` | string | ISO 8601 scrape timestamp |
| `source_url` | string | Exact URL used for the scrape |

#### Focused output example

```json
{
  "record_type": "listing",
  "name": "The Setai Miami Beach",
  "category": "Hotel",
  "subcategory": "Luxury Hotel",
  "city": "Miami Beach",
  "country": "United States",
  "rating": 4.5,
  "review_count": 2341,
  "price_range": "$$$$",
  "ranking": "#3 of 233 Hotels in Miami Beach",
  "phone": "+1-305-520-6000",
  "website": "https://www.thesetaihotel.com/",
  "tripadvisor_url": "https://www.tripadvisor.com/Hotel_Review-g294471-d234567-Reviews-The_Setai-Miami_Beach.html",
  "scraped_at": "2026-04-09T10:00:00.000Z",
  "source_url": "https://www.tripadvisor.com/Hotel_Review-g294471-d234567-Reviews-The_Setai-Miami_Beach.html"
}
```

### How it works

The Actor accepts either search queries or direct TripAdvisor listing URLs.

- `searchQueries` is used for destination or topic searches, such as "hotels in Miami" or "restaurants in Paris"
- `startUrls` is used for direct listing pages, including Hotel\_Review, Restaurant\_Review, and Attraction\_Review URLs
- `scrapeMode` controls whether the execution collects listings, reviews, or both
- `maxResults` sets the maximum number of listing pages to process
- `maxReviewsPerListing` controls how many reviews are collected from each listing when reviews are included
- `proxyConfiguration` uses Apify Proxy, with a residential preset in the input schema

The browser path uses bounded DataDome retries. Small listings-only probes use a SerpAPI public-index path first so automated tests do not spend five minutes on one blocked residential tunnel; richer jobs keep the browser as primary. The public-index path accepts only genuine TripAdvisor `Hotel_Review`, `Restaurant_Review`, and `Attraction_Review` pages. It returns their indexed listing metadata and rejects browse pages, third-party URLs, and synthetic diagnostic rows.

### Evergreen pricing

This Actor uses Pay per event pricing plus standard Apify platform usage. The live Pricing tab shows the current pricing details.

Charged events:

- `Listing Scraped`: $0.003 per hotel, restaurant, or attraction listing scraped
- `Review Scraped`: $0.001 per review scraped
- `Actor Start`: $0.00005 per start event, charged according to the Actor memory allocation, with one event per GB and a minimum of one event

For an example, 10 listings anda bounded number of reviews create 35 pay-per-event records, plus the Actor Start event for the run. For current usage details and any platform-level costs, check the live Pricing tab in Apify.

### Use with AI agents (MCP)

This Actor is usable through Apify MCP as a structured tool for retrieving TripAdvisor listings and reviews.

**Tool description:** retrieve TripAdvisor listing and review records in a predictable schema, with separate handling for destination searches, direct listing URLs, and review collection depth.

**Actor identity:** `khadinakbar/tripadvisor-scraper`

> Find TripAdvisor hotels in Lisbon, then return the listing records with rating, review count, price range, ranking, phone, website, and TripAdvisor URL. If reviews are included, summarize the review records separately by listing name and published date.

How to interpret the output:

- `record_type = listing` means the record describes a hotel, restaurant, attraction, or vacation rental
- `record_type = review` means the record describes one TripAdvisor review tied to a listing
- `tripadvisor_url` and `source_url` provide provenance for the scraped record
- `listing_name` and `listing_url` connect review records back to the parent listing
- `scraped_at` shows when the record was collected

Scope, pagination, and cost guidance:

- use `searchQueries` for topic or destination discovery
- use `startUrls` for known TripAdvisor pages
- set `maxResults` to keep discovery runs focused
- set `maxReviewsPerListing` to control review volume
- review records are charged per item, so review depth directly affects event count
- Apify platform usage still applies alongside Pay per event pricing

### Apify API example

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({
  token: process.env.APIFY_TOKEN,
});

const run = await client.actor('khadinakbar/tripadvisor-scraper').call({
  searchQueries: ['restaurants in Rome'],
  scrapeMode: 'listings_and_reviews',
  maxResults: 5,
  maxReviewsPerListing: 10,
});

const datasetItems = await client.dataset(run.defaultDatasetId).listItems();

const listings = datasetItems.items.filter((item) => item.record_type === 'listing');
const reviews = datasetItems.items.filter((item) => item.record_type === 'review');

console.log(`Listings: ${listings.length}`);
console.log(`Reviews: ${reviews.length}`);
console.log(`Dataset ID: ${run.defaultDatasetId}`);
```

### Best results and outcome guidance

- Use search queries when you want TripAdvisor to surface relevant listing URLs for a city or topic.
- Use direct URLs when you already have a specific hotel, restaurant, or attraction page.
- Use `listings_only` when you want listing metadata without review text.
- Use `reviews_only` when the source URLs already point to the listings you want to analyze.
- Start with a small `maxResults` value, then expand once the query shape looks right.
- Set `maxReviewsPerListing` to match the depth you actually need for analysis or enrichment.
- Filter the dataset by `record_type` before transforming records into downstream tables or agent prompts.

### Design note

I found that the dataset schema uses a single `record_type` discriminator with two values, `listing` and `review`, which makes it straightforward to separate venue data from individual review data in downstream processing.

### FAQ

#### When should I use `searchQueries` instead of `startUrls`?

Use `searchQueries` for destination-based requests like "hotels in Barcelona". Use `startUrls` when you already have a specific TripAdvisor Hotel\_Review, Restaurant\_Review, or Attraction\_Review page.

#### What kind of records does this Actor return?

It returns listing records, review records, or both, depending on `scrapeMode`. Each record is one dataset item.

#### How do I connect reviews back to a listing?

Review records include `listing_name` and `listing_url`, which point back to the parent property.

#### Can I use this Actor for hotels, restaurants, and attractions?

Yes. The actor title and dataset schema cover those TripAdvisor categories, and the input is built for both search-driven and URL-driven workflows.

#### Is this Actor usable through Apify MCP?

Yes. It is an Apify Actor with MCP-ready structured output, and the actor identity is `khadinakbar/tripadvisor-scraper`.

#### How is pricing calculated?

Pricing follows Pay per event. Listing records, review records, and Actor Start events each have their own event type. Check the live Pricing tab for the current platform and usage details.

### Responsible use

Use this Actor for lawful, policy-compliant collection of publicly available TripAdvisor data. Make sure your use of the output fits your internal privacy, access, and data-handling requirements, and review TripAdvisor's terms and any applicable regulations before building production workflows around the results.

# Actor input Schema

## `searchQueries` (type: `array`):

Use this field when the user provides search terms like 'hotels in Miami' or 'restaurants in Paris'. Each query is searched on TripAdvisor and top listing URLs are extracted. Use startUrls instead when the user provides direct TripAdvisor URLs.

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

Use this field when the user provides specific TripAdvisor listing URLs (Hotel\_Review, Restaurant\_Review, Attraction\_Review). Do NOT use this when the user describes a destination or topic — use searchQueries for that.

## `scrapeMode` (type: `string`):

listings\_and\_reviews: scrape full listing details plus reviews (default). listings\_only: scrape listing data only, no reviews. reviews\_only: scrape reviews only from provided listing URLs.

## `maxResults` (type: `integer`):

Maximum number of listing pages to scrape. Each listing counts as one billable result. Start with 5–10 to test before scaling up.

## `maxReviewsPerListing` (type: `integer`):

How many reviews to collect per listing (when scrapeMode includes reviews). Set to 0 to skip reviews. Each review counts as one billable result.

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

Proxy settings. Datacenter proxies are used by default (fast and affordable). Switch to residential proxies if you encounter blocks.

## Actor input object example

```json
{
  "searchQueries": [
    "hotels in New York City"
  ],
  "startUrls": [],
  "scrapeMode": "listings_only",
  "maxResults": 1,
  "maxReviewsPerListing": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

Scraped listing and review records. Filter by record\_type: 'listing' or 'review'. Listings include name, rating, review\_count, address, price\_level, amenities. Reviews include reviewer, rating, title, text, date.

# 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 = {
    "searchQueries": [
        "hotels in New York City"
    ],
    "scrapeMode": "listings_only",
    "maxResults": 1,
    "maxReviewsPerListing": 0,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/tripadvisor-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 = {
    "searchQueries": ["hotels in New York City"],
    "scrapeMode": "listings_only",
    "maxResults": 1,
    "maxReviewsPerListing": 0,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/tripadvisor-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 '{
  "searchQueries": [
    "hotels in New York City"
  ],
  "scrapeMode": "listings_only",
  "maxResults": 1,
  "maxReviewsPerListing": 0,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call khadinakbar/tripadvisor-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,khadinakbar/tripadvisor-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/0pcfEHOjOgw7MQhgR/builds/4QN485auRHjJPpKtn/openapi.json
