# GuruWalk Reviews Scraper (`knagymate/guruwalk-reviews-scraper`) Actor

Scrape GuruWalk reviews, ratings, guide responses, and traveler details from walking tour pages. Collect data from multiple tours, set review limits and a date cutoff, and export to CSV, JSON, or Excel for competitor research and reputation monitoring.

- **URL**: https://apify.com/knagymate/guruwalk-reviews-scraper.md
- **Developed by:** [knagymate](https://apify.com/knagymate) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 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/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

## GuruWalk Reviews Scraper | Walking Tour Ratings & Guide Feedback

Extract **GuruWalk walking tour reviews, guide responses, traveler details, and aggregate ratings** from public tour pages. This Apify Actor delivers structured data for **tour operator benchmarking, guide performance analysis, reputation monitoring, and travel market research**.

Collect feedback from multiple free walking tours without copying reviews page by page. Analyze individual comments alongside GuruWalk's **Professionalism, Entertainment, Communication, Quality, and Route** scores, then export the results to **JSON, CSV, or Excel** for reporting and customer insight workflows.

### What data can you extract from GuruWalk?

- **Traveler reviews:** review text, star rating, review ID, publication date, and language.
- **Guide feedback:** guide or guru response and guide name when available.
- **Reviewer context:** display name, username, avatar URL, location, country, and total reviews.
- **Booking details:** traveler group type, adult attendees, child attendees, and combined traveler count.
- **Tour-level ratings:** overall score, five category scores, and the review count shown on the tour page.
- **Source references:** tour URL and tour ID for joining data and tracing findings back to the source.

The dataset contains both **individual review records** and **tour summary records**. This lets you compare high-level ratings while retaining the comments that explain traveler satisfaction.

### Who is this scraper for?

Built for **walking tour operators, local experience brands, travel marketplaces, destination marketing teams, and travel analytics providers** that need repeatable access to customer feedback.

| Business use case | How the data helps |
|---|---|
| Guide performance benchmarking | Compare tour-level Professionalism, Communication, and Entertainment scores; use individual comments and guide names, when available, to investigate feedback. |
| Competitor research | Compare selected tours by aggregate ratings, review volume, traveler segments, and recurring praise or complaints. |
| Reputation monitoring | Collect recent reviews on a schedule and identify emerging issues for your customer experience team. |
| Walking tour product improvement | Find comments about pacing, route quality, storytelling, meeting points, and suitability for families. |
| Travel marketplace supplier evaluation | Assess traveler feedback across potential tour partners before making a shortlist. |
| Customer insight and content planning | Turn common traveler questions and booking concerns into clearer tour descriptions and useful FAQs. |
| AI-powered review analysis | Build sentiment classification, topic extraction, or review summaries grounded in source review IDs. |

Aggregate scores describe the **tour page**, not a separate scorecard for every guide. For destination-level reporting, join `tourId` or `tourUrl` to your own city and tour reference data.

### Features

- **Multiple GuruWalk tour URLs per run**, with an independent review limit per URL.
- **Automatic review pagination**, without manually navigating review pages.
- **Tour summaries included with every review**, plus a separate summary record for each successfully parsed tour page.
- **Optional date cutoff** for recurring review collection.
- **Configurable review volume**, defaulting to 100 reviews per URL.
- **Structured Apify dataset output** for spreadsheets, analytics, and data pipelines.
- **API access, schedules, and webhooks** through the Apify platform.

### Supported GuruWalk URLs

Provide public **individual GuruWalk walking tour pages**. These examples cover walking tours in Paris, London, Kyoto, and Mexico City:

| Destination | Example tour URL |
|---|---|
| Paris, France | [The Village of Montmartre Without the Crowds](https://www.guruwalk.com/walks/46480-the-village-of-montmartre-without-the-crowds) |
| London, United Kingdom | [London Essentials: London in Under Two Hours](https://www.guruwalk.com/walks/41165-london-essentials-london-in-under-two-hours-free-walking-tour) |
| Kyoto, Japan | [Kyoto Night Free Walking Tour: Gion & Geisha](https://www.guruwalk.com/walks/54591-kyoto-night-free-walking-tour-gion-geisha) |
| Mexico City, Mexico | [Historic Center of Mexico City: The Heart of the Capital](https://www.guruwalk.com/walks/14861-historic-center-of-mexico-city-the-heart-of-the-capital) |

Add more tour URL objects to `urls` to collect reviews for multiple tours. City listings, search results, and guide profile pages are not supported inputs.

The Actor extracts the tour ID and aggregate ratings from the tour page, then paginates through GuruWalk's review API.

**Use the English tour page for the most complete summary extraction.** Category scores and review counts are parsed using English labels. Localized pages may yield missing summary values, and changing the URL language does not configure the review API language.

### How to scrape GuruWalk reviews

1. Open the Actor in Apify Console.
2. Add one or more GuruWalk tour URLs.
3. Set the maximum number of reviews per URL and optionally a cutoff date.
4. Start the run and open its dataset.
5. Export the records or retrieve them through the Apify API.

Start with one tour and a small review limit to assess the data before expanding your collection.

### Input configuration

| Field | Type | Required | Description |
|---|---|:---:|---|
| `urls` | Array of objects | Yes | GuruWalk tour URLs, each supplied as an object with a `url` property. |
| `max_review_per_url` | Integer | No | Maximum individual reviews to collect per URL. Default: `100`. Minimum: `1`. The separate summary record does not count toward this limit. |
| `cutoff_date` | Date string | No | Review publication cutoff in `YYYY-MM-DD` format. Stops collection for a tour at the first review with a parseable date before this date. Omit it or use an empty string for no cutoff. |

#### Example input

Collect up to **25 reviews per tour** across four destinations with this ready-to-use input:

```json
{
  "urls": [
    {
      "url": "https://www.guruwalk.com/walks/46480-the-village-of-montmartre-without-the-crowds"
    },
    {
      "url": "https://www.guruwalk.com/walks/41165-london-essentials-london-in-under-two-hours-free-walking-tour"
    },
    {
      "url": "https://www.guruwalk.com/walks/54591-kyoto-night-free-walking-tour-gion-geisha"
    },
    {
      "url": "https://www.guruwalk.com/walks/14861-historic-center-of-mexico-city-the-heart-of-the-capital"
    }
  ],
  "max_review_per_url": 25
}
```

#### Example input for recent review monitoring

```json
{
  "urls": [
    {
      "url": "https://www.guruwalk.com/walks/46480-the-village-of-montmartre-without-the-crowds"
    }
  ],
  "max_review_per_url": 200,
  "cutoff_date": "2026-01-01"
}
```

The cutoff includes reviews dated on the selected day. It applies to review publication dates, not tour attendance dates, and does not filter the tour summary.

The Actor uses the API's default review order and expects newest-first results for date-based stopping; it does not send an explicit sort parameter. If the source changes its ordering, date-based collection may be incomplete. Reviews with missing or unparseable dates can still appear. There is no `sort_by` input.

### Output dataset

#### Record types

| `recordType` | Contents |
|---|---|
| `summary` | One tour-level snapshot emitted after the tour page is parsed, before review collection. Review-specific fields are `null`. |
| `review` | One individual review, including the same `tourSummary` snapshot for context. |

**Filter to `recordType = "review"` before counting reviews or calculating review-level averages.** The four-tour example above can produce up to 104 dataset items: 25 reviews per tour plus four summary records.

#### Output fields

| Field | Description |
|---|---|
| `recordType` | `summary` or `review`. |
| `tourUrl` | Input GuruWalk tour URL. |
| `tourId` | Tour ID extracted from the source page, returned as a string. |
| `id` | Review identifier, returned as a string. |
| `date` | Parsed review publication date, serialized as an ISO datetime. |
| `travellerCount` | Sum of available adult and child counts; `null` when that sum is zero. Missing counts are treated as zero when calculating this value. |
| `rating` | Individual review rating on a 5-point scale. |
| `authorName` | Reviewer display name. |
| `authorUsername` | GuruWalk reviewer username. |
| `authorAvatar` | Reviewer avatar URL, not a downloaded image. |
| `authorPlace` | Reviewer location text. |
| `authorCountry` | Reviewer country. |
| `authorTotalReviews` | Number of reviews written by the reviewer, as reported by GuruWalk. |
| `comments` | Review text returned by the API. |
| `operatorComment` | Guru or guide response, when present. |
| `operatorName` | Guide name, when supplied with the review. |
| `language` | Review language code returned by GuruWalk. |
| `bookingType` | Traveler group type, such as `alone`, `couple`, `family`, or `group`. |
| `adultAttendees` | Adult attendee count, when available. |
| `childAttendees` | Child attendee count, when available. |
| `tourSummary` | Tour-level summary object included on both record types. |

#### Tour summary fields

| Field within `tourSummary` | Description |
|---|---|
| `tourId` | GuruWalk tour identifier. |
| `startUrl` | Input tour URL used to obtain the summary. |
| `numberOfReviews` | Review count parsed from the tour page, not the number collected in this run. |
| `ratings.overall` | Overall tour rating shown on the page. |
| `ratings.professionalism` | Aggregate Professionalism score. |
| `ratings.entertainment` | Aggregate Entertainment score. |
| `ratings.communication` | Aggregate Communication score. |
| `ratings.quality` | Aggregate Quality score. |
| `ratings.route` | Aggregate Route score. |

Missing source values can be `null` or empty. Summary scores are page-level snapshots, not recalculated averages of the collected reviews and not restricted to the cutoff window.

#### Example summary output item

The examples below use illustrative values, not live ratings or real traveler feedback. Review-specific `null` fields are omitted from this summary example for readability.

```json
{
  "recordType": "summary",
  "tourUrl": "https://www.guruwalk.com/walks/46480-the-village-of-montmartre-without-the-crowds",
  "tourId": "46480",
  "tourSummary": {
    "tourId": "46480",
    "startUrl": "https://www.guruwalk.com/walks/46480-the-village-of-montmartre-without-the-crowds",
    "numberOfReviews": 200,
    "ratings": {
      "overall": 4.8,
      "professionalism": 4.9,
      "entertainment": 4.8,
      "communication": 4.9,
      "quality": 4.8,
      "route": 4.7
    }
  }
}
```

#### Example review output item

```json
{
  "recordType": "review",
  "tourUrl": "https://www.guruwalk.com/walks/46480-the-village-of-montmartre-without-the-crowds",
  "tourId": "46480",
  "id": "1234567",
  "date": "2026-02-15T00:00:00",
  "travellerCount": 2,
  "rating": 5.0,
  "authorName": "Example Traveler",
  "authorUsername": "example_traveler",
  "authorAvatar": null,
  "authorPlace": "London",
  "authorCountry": "United Kingdom",
  "authorTotalReviews": 3,
  "comments": "Clear meeting instructions and engaging stories. The route helped us discover places we would have missed on our own.",
  "operatorComment": "Thank you for joining the walk and sharing your experience.",
  "operatorName": "Example Guide",
  "language": "en",
  "bookingType": "couple",
  "adultAttendees": 2,
  "childAttendees": 0,
  "tourSummary": {
    "tourId": "46480",
    "startUrl": "https://www.guruwalk.com/walks/46480-the-village-of-montmartre-without-the-crowds",
    "numberOfReviews": 200,
    "ratings": {
      "overall": 4.8,
      "professionalism": 4.9,
      "entertainment": 4.8,
      "communication": 4.9,
      "quality": 4.8,
      "route": 4.7
    }
  }
}
```

### Export and integrate GuruWalk review data

Download the run's dataset as **JSON, CSV, or Excel** using Apify's export options. JSON preserves the nested `tourSummary` object; for spreadsheets, flatten the summary fields you want to compare.

Start runs through the [Apify API](https://docs.apify.com/api/v2) and retrieve the results using the run's `defaultDatasetId`:

```text
GET https://api.apify.com/v2/datasets/{defaultDatasetId}/items?format=json
```

When authentication is required, pass your Apify token in the `Authorization: Bearer <APIFY_TOKEN>` header. Keep tokens out of shared URLs and source code.

Use [Apify schedules](https://docs.apify.com/platform/schedules) for recurring collection and [webhooks](https://docs.apify.com/platform/integrations/webhooks) to trigger downstream processing after a run finishes. The records can feed Python and pandas workflows, BI dashboards, data warehouses, or LLM applications for review classification and summarization.

#### Building a recurring review monitoring workflow

1. Save your tour URLs, review limit, and optional cutoff in an Apify task.
2. Schedule collection according to the volume of new reviews.
3. Update `cutoff_date` for each collection window if needed. A saved date is fixed and does not advance automatically.
4. Separate summary records from review records, then merge reviews using `tourId` and `id` when both are available.
5. Save summary snapshots with your own collection timestamp to track rating changes over time.

The Actor does not maintain cross-run history or automatically remove reviews collected in previous runs. Use overlapping date windows and downstream deduplication for recurring collection, accounting for the source-order limitations above.

### Frequently asked questions

#### Can I scrape reviews from multiple GuruWalk tours?

Yes. Add each tour URL as a separate object in `urls`. The review limit applies independently to every URL. The Paris, London, Kyoto, and Mexico City example uses a limit of 25 reviews per tour and can produce up to 100 review records plus four summary records, subject to source availability and the cutoff.

#### Can I export GuruWalk reviews to CSV or Excel?

Yes. Export the Apify dataset in your preferred format. Filter by `recordType` to separate review analysis from tour-level rating comparisons.

#### Does the scraper include all five GuruWalk rating categories?

It extracts Professionalism, Entertainment, Communication, Quality, and Route scores when they can be parsed from the tour page, plus the overall rating. These are aggregate scores, not category ratings for each individual review.

#### Can I filter reviews by date or language?

Use `cutoff_date` for date-based stopping. There is no language filter input: review API requests currently use `language=en`, and the Actor returns the text and language metadata supplied by GuruWalk. It does not perform its own translation or guarantee coverage of every review language.

#### Can I collect every review for a tour?

Set a sufficiently high `max_review_per_url` and omit the cutoff. Pagination continues until the limit is reached or the API reports no more pages. The page's total review count may differ from the accessible API results; complete historical or all-language coverage is not guaranteed.

#### Does this Actor scrape tour prices, bookings, or review photos?

No. It focuses on reviews and tour-level rating summaries. It does not extract pricing, private bookings, departure availability, or review photo galleries. `authorAvatar` is a reviewer profile image URL, not a tour photo.

#### How much does GuruWalk review scraping cost?

See the Actor's current pricing in Apify Store and your Apify plan for applicable charges. Runtime and resource use depend on the number of tours, available reviews, and requested limits. Start with a small run to assess the output and cost before scaling up. "Free walking tour" describes the tour category, not the Actor's pricing.

### Limitations and responsible use

- Source availability and changes to GuruWalk's pages or API can affect collection and field completeness.
- Reviewer details, attendee counts, and guide responses are only available when supplied by the source.
- The Actor provides extracted data, not precomputed sentiment, business recommendations, or guaranteed review coverage.
- Reviews and profile data may be subject to privacy obligations and intellectual property rights. Collect only what you need and ensure appropriate rights before republishing content or using it for model training.
- You are responsible for complying with GuruWalk's terms and applicable laws.

Use the example input for your first run, then configure the tour list and collection window for your guide benchmarking or review monitoring workflow.

# Actor input Schema

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

List of GuruWalk tour URLs to scrape reviews from.

## `max_review_per_url` (type: `integer`):

Maximum number of reviews to scrape per URL.

## `cutoff_date` (type: `string`):

Only reviews from this date onward will be returned.

## Actor input object example

```json
{
  "urls": [
    {
      "url": "https://www.guruwalk.com/walks/44721-buda-and-pest-in-one-step-see-it-all-miss-nothing"
    }
  ],
  "max_review_per_url": 100
}
```

# Actor output Schema

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

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

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

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        {
            "url": "https://www.guruwalk.com/walks/44721-buda-and-pest-in-one-step-see-it-all-miss-nothing"
        }
    ],
    "max_review_per_url": 100,
    "cutoff_date": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("knagymate/guruwalk-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.guruwalk.com/walks/44721-buda-and-pest-in-one-step-see-it-all-miss-nothing" }],
    "max_review_per_url": 100,
    "cutoff_date": "",
}

# Run the Actor and wait for it to finish
run = client.actor("knagymate/guruwalk-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 '{
  "urls": [
    {
      "url": "https://www.guruwalk.com/walks/44721-buda-and-pest-in-one-step-see-it-all-miss-nothing"
    }
  ],
  "max_review_per_url": 100,
  "cutoff_date": ""
}' |
apify call knagymate/guruwalk-reviews-scraper --silent --output-dataset

```

## MCP server setup

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