# Klook Reviews Scraper - Activity Ratings, Photos & Text (`haketa/klook-reviews-scraper`) Actor

Scrape Klook activity, tour and experience reviews across Asia-Pacific and worldwide. Extract star ratings, full review text, translations, reviewer photos, liked counts, booked package and activity summary (city, category, score) by activity URL or ID. Export JSON, CSV, Excel.

- **URL**: https://apify.com/haketa/klook-reviews-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Travel, Business, Lead generation
- **Features:** Limited permissions
- **Stats:** 5 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

## Klook Reviews Scraper — Activity & Experience Reviews with Ratings, Photos and Translations

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-orange?logo=apify)](https://apify.com/haketa/klook-reviews-scraper)
[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://apify.com/haketa/klook-reviews-scraper)
[![Data Format](https://img.shields.io/badge/Data-JSON%20%7C%20CSV%20%7C%20Excel-blue)](#-output)
[![Pagination](https://img.shields.io/badge/Pagination-1%2C000%2B%20Unlocked-brightgreen)](#-pagination--scale)
[![Proxy Support](https://img.shields.io/badge/Proxy-Residential%20\(Asia--Pacific\)-success)](#-input)

> **The most complete Klook review extractor on Apify.** This **Klook scraper** lets you **scrape Klook** — the leading activities, tours and experiences platform across Asia-Pacific and worldwide — and pull real guest reviews with the full review text, its **translation**, a 0–5 star rating, reviewer **photos**, liked counts, the exact **package booked**, and each activity's overall score, city, country and category. **No login, no coding.** Built for reputation monitoring, competitor benchmarking, sentiment analysis and travel-experience market research.

Export every review to **JSON, CSV, Excel, or API**.

> **Built for** activity & tour operators tracking their reputation, travel-analytics and OTA teams, market researchers studying the Asia-Pacific experiences market, and data scientists building review/sentiment datasets.

***

### ⚡ At a glance

| Feature | Details |
| :--- | :--- |
| **Target Website** | [klook.com](https://www.klook.com) (Global & Asia-Pacific) |
| **Input Methods** | Activity URLs (any locale `/en-US/`, `/zh-CN/`, etc.) or numeric Activity IDs |
| **Pagination Limit** | **1,000+ Unlocked** (set `maxReviewsPerActivity` to `0` for all available reviews) |
| **Data Fields** | Star rating, review text, translated text, photos, package name, reviewer name, date |
| **Activity Metadata** | City, country, category, overall score, total review count attached to each row |
| **Language Support** | 14 languages supported (English, Chinese, Japanese, Korean, Thai, Spanish, etc.) |
| **Proxy Requirement** | Asia-Pacific Residential Proxy (Apify Proxy included by default) |
| **Output Formats** | JSON, CSV, Excel (XLSX), XML, HTML Table, RSS |

***

### 🔎 Why scrape Klook?

[Klook](https://www.klook.com/) is the #1 platform for booking tours, activities, attraction tickets, transport passes and experiences across Asia and beyond — Japan, Taiwan, Korea, Thailand, Singapore, Hong Kong, the UAE and worldwide. Every popular activity accumulates **thousands of verified guest reviews**, and those reviews are uniquely detailed: a star rating, full free-text feedback, an on-platform **translation**, traveler-uploaded **photos**, the exact **package/option** the guest booked, and a helpful-vote count. That is a goldmine of first-party voice-of-customer data — but Klook provides no public download button or open review API.

Collecting it manually is tedious and slow. Reviews are paginated 10 at a time behind dynamic endpoints, photos are nested within individual records, and the site actively blocks plain datacenter connections with DataDome protection.

This **Klook reviews scraper** solves the protocol and formatting hurdles. Point it at an activity URL or ID and it returns **one clean row per review**, fully enriched with the activity summary, ready to export or pipe into your business intelligence pipelines.

**Common reasons people scrape Klook:**

- 🎟️ **Reputation monitoring** — track feedback on your own Klook tours, tickets, and travel experiences to catch recurring complaints early.
- 📊 **Competitor benchmarking** — compare competitor activities, pricing packages, and guest ratings side by side across any Asian city.
- 💬 **Sentiment & NLP analysis** — feed review text and star ratings into LLMs and sentiment models for deep voice-of-customer intelligence.
- 📈 **Market & OTA research** — analyze which attractions and tours delight or disappoint international travelers in key APAC markets.
- 📸 **UGC photo extraction** — download high-resolution traveler photos at scale for visual-quality audits and marketing research.
- 🤖 **Machine learning datasets** — build multi-lingual labeled training sets for rating prediction, translation quality, and aspect extraction.
- ⭐ **Longitudinal trend analysis** — schedule recurring runs to measure changes in review velocity and satisfaction scores over time.

***

### ✨ What this Klook scraper does

- ✅ **Collects every guest review** for any Klook activity, tour, ticket or experience — one clean, deduplicated row per review.
- ✅ **Deep automatic pagination** through Klook's review endpoint (10 reviews/page), walking `page=1, 2, 3, …` until the last page — thousands of reviews per activity.
- ✅ **Rich review fields** captured verbatim: `reviewId`, 0–5 `rating`, `ratingDesc` label (e.g. *Fantastic*), ISO `reviewDate`, original `reviewContent`, its `translatedContent`, `likedCount`, `hasReply`, the reviewer `userName` and `userAvatar`.
- ✅ **Reviewer photos** — every uploaded image URL in `reviewImages` (`|`-separated) plus an `imageCount`.
- ✅ **Package-level attribution** — `packageName` and `packageId` for the exact option the review is about.
- ✅ **Activity summary on every row** (optional): `activityName`, `activityCity`, `activityCountry`, `activityCategory`, `activityScore` and `activityReviewCount`.
- ✅ **Language control** — return review text in English, Chinese (Simplified / Traditional / HK), Japanese, Korean, Thai, Vietnamese, Indonesian, Malay, Spanish, French, German or Russian.
- ✅ **Sort & cap** — order by Most relevant or Most recent, and cap with `maxReviewsPerActivity` (or set `0` for everything).
- ✅ **Resilient fetching** — Asia-Pacific **residential proxy** with session rotation and retry/back-off, so transient `403 / 429 / 590` blocks retry on a fresh IP instead of failing the run.
- ✅ **Multi-activity processing** — pass dozens of URLs or IDs in a single run and export unified datasets.

***

### 🎯 Use cases

- 🎟️ **Activity & tour operators** — monitor your Klook reputation, surface recurring praise and complaints, and inspect traveler photos to improve on-the-ground operations.
- 📊 **Competitor benchmarking** — pull reviews, scores and photos for rival activities in a city and compare them side by side.
- 💬 **Sentiment & voice-of-customer** — run review text and ratings through NLP/LLM models for experience-level insight.
- 📈 **Travel & OTA market research** — study traveler preferences across Asia-Pacific: which experiences delight, which disappoint, and why.
- 📸 **UGC & photo analysis** — collect reviewer-uploaded images at scale for visual quality, moderation or computer-vision work.
- 🤖 **ML / NLP training data** — build large labeled review datasets (rating, language, package, images) for model training.
- 🏨 **Destination & DMO analysts** — measure satisfaction for attractions and transport passes in a market.
- 🧭 **Review aggregators** — add Klook experience reviews to a cross-platform ratings product.

***

### 📥 Input parameters

Paste one or more Klook activity URLs (or numeric IDs), pick a language and sort order, set your cap, and run.

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `startUrls` | Array | `["https://.../activity/73749-..."]` | Klook activity/experience page URLs. Works with any Klook language path (`/en-US/`, `/zh-CN/`, `/ja-JP/`, etc.). |
| `activityIds` | Array | `[]` | Optional. Direct numeric activity IDs (the number right after `/activity/` in the URL, e.g. `73749`). |
| `language` | Select | `"en"` | Language the review text is returned in: `en`, `zh_CN`, `zh_TW`, `zh_HK`, `ja`, `ko`, `th`, `vi`, `id`, `ms`, `es`, `fr`, `de`, `ru`. |
| `sortBy` | Select | `"most_relevant"` | Review sort order: `most_relevant` or `most_recent`. |
| `maxReviewsPerActivity` | Integer | `0` (unlimited) | Max reviews per activity. Set `0` for all available reviews. Prefill is set to `60` for fast initial testing. |
| `maxItems` | Integer | `0` (unlimited) | Global maximum total reviews to collect across all activities combined. Set `0` for no global limit. |
| `includeActivityInfo` | Boolean | `true` | Attach activity name, city, country, category, overall score and total review count to every review record. |
| `proxyConfiguration` | Object | `{ "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }` | Asia-Pacific residential proxy configuration required for anti-bot bypass. |

#### Example input configuration

```json
{
  "startUrls": [
    "https://www.klook.com/en-US/activity/73749-thsr-one-way-ticket-taipei/"
  ],
  "language": "en",
  "sortBy": "most_relevant",
  "maxReviewsPerActivity": 60,
  "includeActivityInfo": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

***

### 📤 Output dataset

Every review is exported as one clean, normalized row.

#### Sample output item

```json
{
  "reviewId": "18171293",
  "activityId": "73749",
  "activityName": "Taiwan High Speed Rail Ticket for non-Taiwanese",
  "userName": "Lee *****",
  "userAvatar": "https://cdn.klook.com/upload/img200X200/f157ba7806e0487c66f0a28d28aaca42.jpg",
  "rating": "5.0",
  "ratingDesc": "Fantastic",
  "reviewDate": "2026-04-01T05:42:53.000Z",
  "reviewContent": "The Taiwan High-Speed Rail ticket for non-Taiwanese was on a buy-one-take-one promotion. We were glad we were able to purchase it before it expired. Upon arrival, we were welcomed by nice staff who instructed us on how to redeem the ticket. The train was very clean and comfortable, and we reached Zuoying Terminal in just under two hours.",
  "translatedContent": "",
  "likedCount": "8",
  "hasReply": "false",
  "imageCount": "6",
  "reviewImages": "https://cdn.klook.com/user_review/product/1949310/e69f7e58-35eb-4b42-414e-0b92abad6f78.0*1200.jpeg | https://cdn.klook.com/user_review/product/1949310/c656cc9a-050d-4461-73f6-5080d8a1731d.0*1200.jpeg",
  "packageName": "Buy 1 Get 1 - Promo Code [G02TAIWAN] · Taipei · Zuoying (Kaohsiung) · Free voucher (select at checkout)",
  "packageId": "339074",
  "activityCity": "Taipei",
  "activityCountry": "Taiwan",
  "activityScore": "4.8",
  "activityReviewCount": "25564",
  "activityCategory": "Transport",
  "activityUrl": "https://www.klook.com/en-US/activity/73749-thsr-one-way-ticket-taipei/",
  "language": "en_US",
  "scrapedAt": "2026-11-10T12:45:00.000Z"
}
```

***

#### Field reference

##### ⭐ Review item fields

| Field | Type | Coverage | Description |
| :--- | :--- | :--- | :--- |
| `reviewId` | String | 🟢 High (100%) | Unique Klook review identifier (natural dedup key). |
| `userName` | String | 🟢 High (100%) | Reviewer display name (often masked for privacy e.g. `Lee *****`). |
| `userAvatar` | String | 🟡 Conditional (70%) | Profile photo URL of the reviewer on Klook CDN. |
| `rating` | String | 🟢 High (100%) | Guest rating score out of 5 (e.g. `5.0`, `4.0`). |
| `ratingDesc` | String | 🟢 High (100%) | Rating sentiment label (e.g. *Fantastic*, *Good*, *Average*). |
| `reviewDate` | String | 🟢 High (100%) | ISO 8601 timestamp when the review was submitted. |
| `reviewContent` | String | 🟢 High (100%) | Full original review text submitted by the guest. |
| `translatedContent` | String | 🟡 Conditional (45%) | Translated review text when Klook provides automatic translation. |
| `likedCount` | String | 🟢 High (100%) | Count of helpful votes received from other travelers. |
| `hasReply` | String | 🟢 High (100%) | Boolean string (`true`/`false`) indicating merchant reply. |
| `imageCount` | String | 🟢 High (100%) | Number of traveler photos attached to the review. |
| `reviewImages` | String | 🟡 Conditional (30%) | Pipe-delimited list of traveler photo URLs on Klook CDN. |
| `packageName` | String | 🟢 High (95%) | Specific package or option name booked by the reviewer. |
| `packageId` | String | 🟢 High (95%) | Identifier of the specific package selected. |

##### 🏙️ Activity metadata fields

| Field | Type | Coverage | Description |
| :--- | :--- | :--- | :--- |
| `activityId` | String | 🟢 High (100%) | Klook numeric activity identifier. |
| `activityName` | String | 🟢 High (99%) | Title of the tour, ticket, or experience. |
| `activityCity` | String | 🟢 High (95%) | Primary destination city of the activity. |
| `activityCountry` | String | 🟢 High (95%) | Destination country or territory. |
| `activityScore` | String | 🟢 High (95%) | Aggregate rating score of the activity out of 5. |
| `activityReviewCount` | String | 🟢 High (100%) | Total review count reported on the activity. |
| `activityCategory` | String | 🟢 High (90%) | Primary activity category (e.g. *Transport*, *Tours*). |
| `activityUrl` | String | 🟢 High (100%) | Canonical link to the activity page on Klook. |
| `language` | String | 🟢 High (100%) | Klook locale code used for translation (e.g. `en_US`). |
| `scrapedAt` | String | 🟢 High (100%) | UTC ISO timestamp when the record was extracted. |

***

### 📊 Comparison: Why use this Actor?

| Feature | Manual Copy-Paste | Custom Puppeteer Script | Klook Reviews Scraper |
| :--- | :--- | :--- | :--- |
| **DataDome Anti-Bot Bypass** | Manual browsing only | Blocks immediately (`403`) | **Built-in got-scraping + Residential** |
| **Max Reviews per Activity** | 10 per page click | Stalls after few pages | **1,000+ Unlocked** (auto-paginated) |
| **Reviewer Photos Extraction** | Right-click save | Complex DOM parsing | **Direct CDN URLs in CSV/JSON** |
| **Package Attribution** | Often missed | High error rate | **Verified package name & ID** |
| **Multi-Language Translation** | Manual Google Translate | Single language | **14 Native Klook languages** |
| **Activity Context Attachment** | Manual spreadsheet join | Multiple requests needed | **Auto-enriched on every row** |

***

### 💻 Developer & API integrations

Integrate Klook review data directly into your analytical stack using Apify's API clients.

#### Python integration

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run_input = {
    "startUrls": ["https://www.klook.com/en-US/activity/73749-thsr-one-way-ticket-taipei/"],
    "language": "en",
    "sortBy": "most_recent",
    "maxReviewsPerActivity": 100,
    "includeActivityInfo": True,
}

run = client.actor("haketa/klook-reviews-scraper").call(run_input=run_input)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"⭐ {item['rating']} [{item['userName']}]: {item['reviewContent'][:80]}...")
```

#### Node.js integration

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const input = {
    startUrls: ['https://www.klook.com/en-US/activity/73749-thsr-one-way-ticket-taipei/'],
    language: 'en',
    maxReviewsPerActivity: 100,
};

const run = await client.actor('haketa/klook-reviews-scraper').call(input);
const { items } = await client.dataset(run.defaultDatasetId).listItems();

console.log(`Extracted ${items.length} reviews from Klook.`);
items.forEach(r => console.log(`${r.ratingDesc} (${r.rating}/5) by ${r.userName}`));
```

***

#### cURL API call

```bash
curl "https://api.apify.com/v2/acts/haketa~klook-reviews-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "startUrls": ["https://www.klook.com/en-US/activity/73749-thsr-one-way-ticket-taipei/"],
    "maxReviewsPerActivity": 50,
    "language": "en"
  }'
```

#### Analyzing Klook reviews with Python & pandas

```python
import pandas as pd
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
dataset_items = client.dataset("DATASET_ID").list_items().items

df = pd.DataFrame(dataset_items)

## Convert ratings to float
df['rating'] = pd.to_numeric(df['rating'], errors='coerce')

## Rating summary & sentiment distribution
print("Average rating:", df['rating'].mean())
print("\nRatings breakdown:")
print(df['ratingDesc'].value_counts())

## Review photo analysis
has_photos = df[df['imageCount'].astype(int) > 0]
print(f"\nReviews with traveler photos: {len(has_photos)} ({len(has_photos)/len(df)*100:.1f}%)")
```

***

### ⚙️ How to use Klook Reviews Scraper

1. **Open the Actor in Apify Console**: Navigate to `haketa/klook-reviews-scraper` on the Apify Store or Console.
2. **Input Activity Targets**: Paste one or more Klook activity URLs in `startUrls`, or input numeric IDs directly in `activityIds`.
3. **Configure Language & Sort**: Choose the target review translation language (e.g., `en`, `ja`, `zh_TW`) and sorting preference (`most_relevant` or `most_recent`).
4. **Set Pagination Limits**: Use the default `60` for a fast initial test, or change `maxReviewsPerActivity` to `0` to scrape thousands of historical reviews.
5. **Click Start**: Monitor real-time extraction progress in the live log and console status message.
6. **Export Your Dataset**: Download the structured results in CSV, Excel, JSON, or connect via Apify API webhooks to your cloud database or BI tool.

***

### 🔁 Pagination & scale

The **Klook scraper** reads reviews straight from Klook's `get_review_list` endpoint, which serves **10 reviews per page**. For every activity it starts at `page=1` and walks forward page by page — `page=1`, `page=2`, `page=3`, … — appending each page of guest feedback to your dataset until Klook signals the last page (`has_next = false`) or your `maxReviewsPerActivity` limit is reached.

- **Hundreds to thousands per activity.** Popular activities carry tens of thousands of reviews; the scraper paginates through all of them when you set `maxReviewsPerActivity` to `0`.
- **Deduplicated rows.** Each review is keyed by its `reviewId`, so reviews that repeat across page boundaries are collected **once** with 0 duplicates.
- **Controlled by `maxReviewsPerActivity`.** Cap each activity to keep runs fast and predictable, or set `0` to pull every available review.
- **Many activities per run.** Add as many Klook activity URLs or IDs as you like; the actor iterates them sequentially, streams results as it goes, and updates a live progress status.
- **Resilient fetching.** Each request runs through an Asia-Pacific **residential proxy** with automatic session rotation and retry/back-off, so transient blocks (`403` / `429` / upstream `590`) are retried on a fresh IP rather than failing the run.

***

### 💡 Pro tips for best results

- **Unlock deep pagination** — Set `maxReviewsPerActivity` to `0` to collect the entire historical backlog of guest feedback for an attraction.
- **Fast monitoring runs** — Setting `maxReviewsPerActivity: 50` or `100` provides an ideal sample size for regular weekly sentiment audits.
- **Sort by most recent** — Use `sortBy: "most_recent"` to detect emerging service issues or seasonal changes in tour quality.
- **English covers all reviews** — Klook provides unified automated translations. Selecting `language: "en"` translates all multi-lingual guest feedback into English automatically.
- **Stale URLs are supported** — Even if Klook renames an activity URL slug, the scraper automatically handles redirects and extracts from the underlying numeric ID.

***

### ⚠️ Limitations & considerations

- **Residential Proxy Required**: Klook's web servers strictly enforce anti-bot challenges on datacenter IP addresses. Apify residential proxies are pre-configured to ensure reliable access.
- **Masked Reviewer Identities**: In compliance with platform privacy policies, Klook masks middle characters in guest names (e.g. `John D****`).
- **Retired Activity Pages**: In rare cases where an older activity was merged or discontinued, its review feed may remain accessible while the landing page metadata is partial.

***

### ❓ Frequently Asked Questions

**How many reviews can I get per activity?**
All of them — set `maxReviewsPerActivity` to `0` and the actor paginates until no more pages exist. Top activities with 20,000+ reviews can be fully extracted.

**Do I need a Klook login or API key?**
No account or API credentials are required. The scraper collects publicly displayed guest feedback.

**Do I need proxies?**
Yes. An Asia-Pacific residential proxy is required to pass Klook's network safeguards and is pre-configured by default.

**Which export formats are supported?**
JSON, CSV, Excel (XLSX), XML, and RSS feeds, plus direct programmatic integration with Google Sheets, Airtable, webhooks, and Apify REST APIs.

**Do reviews include traveler photos?**
Yes. All traveler photo URLs are captured in `reviewImages` alongside the total `imageCount`.

**Can I get reviews translated into my preferred language?**
Yes. Select any of the 14 supported languages in the input settings. Klook automatically translates the review text into your chosen language.

***

### 🔗 Related scrapers

- [Trip.com & Ctrip Reviews Scraper](https://apify.com/haketa/trip-com-reviews-scraper) — hotel ratings, review text and traveler details across Trip.com and Ctrip.
- [Despegar Hotel Reviews Scraper](https://apify.com/haketa/despegar-reviews-scraper) — hotel reviews with pros, cons and category scores for Latin America.
- [Trustpilot Reviews Scraper](https://apify.com/haketa/trustpilot-reviews-scraper) — business ratings, reviews and company replies from Trustpilot.
- [G2 Reviews Scraper](https://apify.com/haketa/g2-reviews-scraper) — software reviews, star ratings and reviewer profiles from G2.
- [Meesho Reviews Scraper](https://apify.com/haketa/meesho-reviews-scraper) — product ratings, comments, photos and author details from Meesho.

***

### 📋 Changelog

#### Version 1.2 (2026-11)

- **Unlocked 1,000+ Pagination**: Verified deep pagination across 100+ review pages with `maxReviewsPerActivity: 0`.
- **Fast Prefill Execution**: Optimized prefill configuration (60 reviews) for verification runs in under 60 seconds.
- **Enhanced Anti-Bot Resilience**: Strengthened residential proxy session rotation for handling transient upstream HTTP 590 errors.
- **Refined Schema Standards**: Added full coverage indicators and verified 0 duplicate review ID tracking across pages.

#### Version 1.1 (2026-09)

- Added automatic fallback to canonical activity URLs for legacy activity slugs.
- Added support for 14 translation languages.

#### Version 1.0 (2026-08)

- Initial release with activity metadata, guest ratings, review text, translations, and photos.

# Changelog

This Actor's version history is a separate document: https://apify.com/haketa/klook-reviews-scraper/changelog.md

# Actor input Schema

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

Paste Klook activity/experience page URLs (e.g. https://www.klook.com/en-US/activity/73749-thsr-one-way-ticket-taipei/). All guest reviews are collected for each activity. Works with any Klook language path (/en-US/, /zh-CN/, /ja-JP/, etc.).

## `activityIds` (type: `array`):

Optional. Provide Klook numeric activity IDs directly — the number after '/activity/' in the URL (e.g. 73749).

## `language` (type: `string`):

Language the review text is returned in. Klook translates reviews into the chosen language. Choose English for the widest, most readable output.

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

Order in which reviews are collected.

## `maxReviewsPerActivity` (type: `integer`):

Maximum number of reviews to collect per activity. Set to 0 for all available reviews (popular activities can have tens of thousands).

## `maxItems` (type: `integer`):

Optional overall cap on total reviews collected across all activities in this run. Set to 0 for no global limit.

## `includeActivityInfo` (type: `boolean`):

Attach the activity name, city, country, category, overall score and total review count to every review record.

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

Proxy configuration. An Asia-Pacific residential proxy is required and enabled by default.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.klook.com/en-US/activity/73749-thsr-one-way-ticket-taipei/"
  ],
  "activityIds": [
    "73749"
  ],
  "language": "en",
  "sortBy": "most_relevant",
  "maxReviewsPerActivity": 60,
  "maxItems": 0,
  "includeActivityInfo": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `reviewId` (type: `string`):

Unique Klook review ID

## `activityId` (type: `string`):

Klook activity ID

## `activityName` (type: `string`):

Activity name

## `userName` (type: `string`):

Reviewer display name

## `userAvatar` (type: `string`):

Reviewer avatar URL

## `rating` (type: `string`):

Guest rating out of 5

## `ratingDesc` (type: `string`):

Rating label (e.g. Fantastic)

## `reviewDate` (type: `string`):

Review timestamp (ISO 8601)

## `reviewContent` (type: `string`):

Original review text

## `translatedContent` (type: `string`):

Translated review text (if different)

## `likedCount` (type: `string`):

How many users liked the review

## `hasReply` (type: `string`):

Whether the merchant replied

## `imageCount` (type: `string`):

Number of reviewer photos

## `reviewImages` (type: `string`):

Reviewer photo URLs ( | separated)

## `packageName` (type: `string`):

Booked package/option name

## `packageId` (type: `string`):

Booked package ID

## `activityCity` (type: `string`):

Activity city

## `activityCountry` (type: `string`):

Activity country

## `activityScore` (type: `string`):

Activity overall score out of 5

## `activityReviewCount` (type: `string`):

Total reviews for the activity

## `activityCategory` (type: `string`):

Activity top category

## `activityUrl` (type: `string`):

Activity page URL

## `language` (type: `string`):

Review language code

## `scrapedAt` (type: `string`):

Extraction timestamp

# 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.klook.com/en-US/activity/73749-thsr-one-way-ticket-taipei/"
    ],
    "maxReviewsPerActivity": 60,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/klook-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.klook.com/en-US/activity/73749-thsr-one-way-ticket-taipei/"],
    "maxReviewsPerActivity": 60,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/klook-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.klook.com/en-US/activity/73749-thsr-one-way-ticket-taipei/"
  ],
  "maxReviewsPerActivity": 60,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call haketa/klook-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,haketa/klook-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/7VLwlnAvBDWDOnceS/builds/nCIn6DP95e8CsEgc3/openapi.json
