Zoover Reviews Scraper — Hotel Guest Reviews & Ratings avatar

Zoover Reviews Scraper — Hotel Guest Reviews & Ratings

Pricing

$4.00 / 1,000 review rows

Go to Apify Store
Zoover Reviews Scraper — Hotel Guest Reviews & Ratings

Zoover Reviews Scraper — Hotel Guest Reviews & Ratings

Every Zoover.nl guest review of any hotel, campsite or apartment: the 1-10 score, title, full Dutch review text, per-aspect scores, travel party, travel date, reviewer and the owner's reply. Give Zoover accommodation URLs or ids. No browser, no login. Pay per review.

Pricing

$4.00 / 1,000 review rows

Rating

0.0

(0)

Developer

Tedj MEABIOU

Tedj MEABIOU

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

8 days ago

Last modified

Share

Zoover Reviews Scraper — hotel guest reviews and ratings

This Zoover reviews scraper turns any accommodation page on Zoover.nl into structured rows: one per guest review, with the 1-10 score, the title, the full text, the per-aspect scores, the travel party, the travel date, the reviewer and the owner's reply. As a hotel reviews scraper it reads Zoover hotel reviews, camping reviews, bungalow-park reviews and apartment reviews the same way, so you can pull guest reviews for a whole portfolio in one run. No browser, no login, no Zoover api key — just accommodation URLs or ids in, hotel reviews out, billed per delivered review.

Zoover is the review site Dutch and Flemish holidaymakers actually write on, and its reviews are graded 1-10 with a separate score for the room, the service, the location, the hygiene and the price/quality ratio. That makes it the sharpest source of dutch hotel reviews there is — and the one place where a Mediterranean resort's Dutch-language guest feedback lives.

Last verified working: 2026-08-29.

What does this Zoover reviews scraper do?

Give it accommodation URLs (https://www.zoover.nl/a/91488/esperos-blue-village-spa) or ids, and every run produces three kinds of dataset row:

Row typeWhat it isCost
reviewOne guest review, with everything Zoover holds about it$0.004
accommodationOne context row per property: ids, star rating, Zoover guest rating, aspect averages, place, chain, contactfree
statusOne row per input: what happened, how many reviews were delivered, how many the filters droppedfree

The important part is the billing rule: you are charged for exactly the review rows delivered to your dataset. Filters run before billing, a property with no reviews costs nothing, an unknown id costs nothing, and a run that hits your spending limit stops delivering rather than delivering rows you did not pay for.

Zoover review fields: what do you get from each review?

Every review row carries these fields:

FieldDescription
review_idZoover's review id (a uuid). Legacy rows without one get h<review_legacy_id>, stable across runs
review_legacy_idZoover's numeric id of the review itself
accommodation_idThe property's internal id (uuid) — feed it back to skip the page read
helios_idThe number in the accommodation URL /a/<number>/…
accommodation_nameProperty name as Zoover shows it
accommodation_urlThe property's page on zoover.nl
titleReview title as the guest wrote it
textFull review text
text_lengthCharacters of review text, as Zoover counts them
scoreThe guest's overall score, 1-10 (10 is best)
aspectsScores per aspect, 1-10: room, food, service, location, hygiene, pool, childFriendly, priceQuality, general
localeLanguage the review was written in (nl, de, …)
traveled_withCOUPLE, FAMILY_WITH_YOUNG_CHILDREN, FAMILY_WITH_OLDER_CHILDREN, FRIENDS, SINGLE, BUSINESS, GROUP
review_date / review_datetimeWhen the review was published (date and ISO timestamp)
updated_dateWhen the guest last edited it
travel_dateMonth of the stay
reviewer_nameReviewer display name
reviewer_verifiedWhether Zoover marks the reviewer as verified
reviewer_levelZoover's reviewer badge, when the profile has one
likesHelpful votes the review received
photos / photo_countGuest photo URLs (rewritten to fetchable links) and how many
responseThe owner's reply, in full
response_date / response_author / response_positionWhen it was written, who signed it, their role (e.g. Owner)
targetThe input value this row came from
fetched_atWhen the row was read, ISO 8601 UTC

The free accommodation row adds giata_id, accommodation_type, star_rating, rating (Zoover's overall guest rating), review_count, aspect_ratings (the property's average per aspect), country, region, city, chain, phone, email, address, postal_code, website, image, bookable, reviews_listed, reviews_fetched, plus this run's own tallies scores (reviews per score) and travel_parties (reviews per party).

The free status row carries status, reviews, filtered, pages, total, duplicates and error — so a scheduled run can be audited without reading a single review.

How do you point the scraper at an accommodation?

Three ways, and you can mix them in one run:

  1. startUrls — full accommodation URLs. Only the number after /a/ matters; the slug can be wrong or missing.
  2. accommodationIds — the same number on its own (91488). Zoover calls it the heliosId.
  3. accommodationIds with a uuid — the Zoover accommodation id (accommodation_id) from an earlier run (9c471493-27a9-4dfc-a0e5-60ec206b3b62). This is the fast path: the uuid is the key Zoover's own review endpoint takes, so the run skips the page read entirely. A uuid has no page, so it produces no accommodation row.

A URL, its number and its uuid are recognised as the same property: one is scraped, the others come back as free duplicate status rows. An id Zoover does not know is a free not_found row, never an invented result.

{
"startUrls": ["https://www.zoover.nl/a/91488/esperos-blue-village-spa"],
"accommodationIds": ["83376", "9c471493-27a9-4dfc-a0e5-60ec206b3b62"],
"maxReviewsPerAccommodation": 0,
"includeAccommodationRow": true
}

Review filters: which ones keep your Zoover review data bill down?

Every filter runs before billing, so a filtered review is a review you never pay for:

  • maxReviewsPerAccommodation0 takes every review the property has; N takes the newest N. It becomes the page size too, so a cap of 6 costs exactly one request.
  • maxRating — keep only reviews scoring at or below this on the 1-10 scale. 6 is the complaints feed, and the fastest way to find zoover negative reviews.
  • minRating — keep only reviews scoring at or above this. 9 is the testimonial feed. Combine the two for a band (5 to 7 = the lukewarm middle where churn hides).
  • requireText — drop score-only reviews.
  • sinceDate2026-01-01, or relative (30 days, 6 months, 2 years) so a schedule never goes stale. Reviews come newest first, so the run stops paging once a whole page predates the cut.
{
"accommodationIds": ["91488", "83376"],
"maxRating": 6,
"requireText": true,
"sinceDate": "12 months"
}

How much does it cost?

$0.004 per review row. Nothing else is charged: accommodation rows, status rows, properties with no reviews, unknown ids, duplicate inputs and every filtered review are free. A typical Zoover property delivers a handful of reviews, so a hundred properties usually land between $0.02 and $0.40 for the whole sweep — and if a property turns out to be empty, that property cost you nothing at all.

There is no per-run start fee and no per-dataset-item fee, which matters when you are sweeping hundreds of properties that may each hold nothing.

How many reviews does a Zoover property have?

Fewer than you would guess, and you should plan for it. In a measured sample of accommodations taken from Zoover's own sitemap on 2026-08-29, review counts ran 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 6, 11, 16, 23 — most properties had none at all, and the busiest held 23. Zoover's catalogue is large (32,504 accommodation URLs in its sitemap) and its review depth is shallow.

So use this scraper the way it is built to be used: feed it lists of properties, not one property expecting thousands of rows. A destination sweep of 500 hotels is a normal run; "all reviews of one resort" is a run that finishes in two seconds. Because empty properties are free, a wide sweep is cheap — you only pay where the reviews actually are.

Zoover in the Dutch and Belgian market — why this review data is different

Zoover is a Dutch review platform (with a Belgian sibling) whose audience is Dutch and Flemish package-holiday travellers, plus German visitors on its sister sites. That gives Zoover review data three properties no global site has:

  • Language. These are Dutch-language guest reviews, mostly locale: "nl". If you monitor a Spanish, Greek or Turkish resort, this is where its Dutch-speaking guests speak — and their complaints rarely appear on the English-language sites.
  • The 1-10 grade with aspects. Zoover ratings are not stars. Every review can score the room, food, service, location, hygiene, pool, child friendliness, price/quality and a general mark, all on 1-10. That is a ready-made feature vector for hotel sentiment analysis, no NLP required.
  • Package-holiday inventory. Zoover covers campings, bungalow parks and apartment resorts that global OTAs list thinly or not at all, so zoover camping reviews and holiday-park feedback have no substitute elsewhere.

For a hotel that sells into the Benelux, this is the missing half of hotel reputation management: review monitoring in the language the guests complained in.

How do you scrape Zoover reviews from Python, JavaScript or curl?

Python, with the Apify client:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("kestrel/zoover-reviews-scraper").call(run_input={
"startUrls": ["https://www.zoover.nl/a/91488/esperos-blue-village-spa"],
"maxReviewsPerAccommodation": 0,
"maxRating": 6,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
if row["type"] == "review":
print(row["score"], row["review_date"], row["title"])

JavaScript (Node):

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('kestrel/zoover-reviews-scraper').call({
accommodationIds: ['91488', '83376'],
sinceDate: '12 months',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((i) => i.type === 'review').length, 'reviews');

curl — start a run and read the dataset:

curl -X POST "https://api.apify.com/v2/acts/kestrel~zoover-reviews-scraper/runs?token=$APIFY_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"startUrls":["https://www.zoover.nl/a/91488/esperos-blue-village-spa"],"maxReviewsPerAccommodation":0}'
curl "https://api.apify.com/v2/acts/kestrel~zoover-reviews-scraper/runs/last/dataset/items?token=$APIFY_TOKEN&format=csv&clean=1" > zoover-reviews.csv

That last line is also how you download Zoover reviews as CSV: the dataset exports to zoover reviews csv, JSON, XLSX or XML from the same endpoint, or with one click in the Apify console.

How do you use it with n8n, Make and AI agents?

  • n8n — the Apify node runs the actor and hands the dataset straight into your workflow; use "Run actor and get dataset" and filter on type == "review".
  • Make — the Apify app has a "Run an actor" module; chain it into Google Sheets, Slack or a database in the usual way.
  • MCP / AI agents — the actor is callable over Apify's MCP server, so an agent can ask for a property's reviews as a tool call and reason over the returned rows. Its input schema is the tool schema; nothing extra to write.
  • Scheduling — set sinceDate to 7 days and a daily schedule, and each run reads only the new reviews.

Input reference

InputTypeDefaultWhat it does
startUrlsarray[]Zoover accommodation URLs
accommodationIdsarray[]The number from /a/<number>/…, or an accommodation_id uuid
maxReviewsPerAccommodationinteger00 = all; N = newest N
maxRatingnumber0Keep reviews scoring ≤ this (1-10); 0 = off
minRatingnumber0Keep reviews scoring ≥ this (1-10); 0 = off
requireTextbooleanfalseDrop score-only reviews
sinceDatestring""YYYY-MM-DD or relative (30 days)
includeAccommodationRowbooleantrueEmit the free property context row
sessionsinteger2Parallel proxy sessions (egress IPs)
perIpnumber1Requests per second per session
proxyConfigurationobjectApify ProxyDatacenter is enough; residential works too

At least one of startUrls or accommodationIds is required. Bad input fails the run immediately, before anything is fetched or charged.

Output reference — the dataset views

The dataset ships with five ready-made views, so you rarely need to write a transformation:

  • Overviewtype, accommodation_name, score, title, text, review_date, traveled_with, status.
  • Reviews — every review field worth reading at a glance, including aspects, locale, travel_date, reviewer_name, likes, photo_count, response and accommodation_url.
  • Complaints — the same, ordered around the low scores and the response_date of the owner's reply.
  • Accommodationsaccommodation_id, helios_id, accommodation_name, accommodation_type, star_rating, rating, review_count, aspect_ratings, scores, travel_parties, city, region, country, reviews_listed, reviews_fetched.
  • Statustarget, accommodation_id, helios_id, accommodation_name, status, reviews, filtered, pages, total, duplicates, error.

Every run also writes a SUMMARY record to the key-value store with the counts it delivered and charged, so a monitoring job can check one JSON object instead of a dataset.

This actor reads two public things: the accommodation page any visitor can open, and POST /api/getReviews — the JSON endpoint Zoover's own robots.txt explicitly allows (Allow: /api/getReviews, above its Disallow: /api). Nothing here is behind a login, a paywall or a personalisation cookie.

That is not legal advice. Reviews are user-generated content: the text belongs to its author and Zoover's terms govern reuse. Guest names are personal data under the GDPR, so treat reviewer_name accordingly, keep only what you need, and give it a retention period. Aggregate analysis of public reviews — reputation monitoring, competitive benchmarking, sentiment work — is the normal use; republishing scraped review text as if it were yours is not. If you are unsure, ask your own counsel.

How is this different from the other Zoover scrapers?

  • Charged equals delivered. One event, review, priced at $0.004, charged only for rows actually written to your dataset. No per-start fee, no per-dataset-item fee on free context rows.
  • Empty properties are free. On a site where most accommodations hold no reviews, that is the difference between a cheap 500-property sweep and a bill for nothing.
  • A refusal is never reported as "no reviews". A Cloudflare block, a throttle or a 400 from the API becomes status: "error" with the reason. An empty property is no_reviews; an unknown id is not_found. Three different answers, three different words.
  • It sends the page size Zoover requires. The review endpoint quietly returns one review when the request omits its size — while still reporting the true total. A scraper that trips over that under-delivers and looks fine doing it. This one always sends it, and pages the cursor to the end.
  • The uuid fast path. No other Zoover scraper takes the internal id as input. Store accommodation_id once and later runs skip the page fetch entirely — cheaper, faster and one less thing to be blocked on.

FAQ

Do I need a Zoover API key?

No. There is no public Zoover api to sign up for. The actor calls the same endpoint the website's own front end calls, through Apify Proxy, so you get zoover reviews without api credentials of any kind.

Can I scrape Zoover reviews by hotel name?

Not directly — targets are URLs or ids. Search zoover.nl for the property, copy the URL from the address bar, and paste it into startUrls. Once a run has read it, keep the accommodation_id and use that for every later refresh.

How do I get the reviews of many hotels at once?

Put every URL in startUrls or every number in accommodationIds — hundreds are fine in one run. That is how bulk hotel reviews are meant to be collected here, and it is why the empty properties being free matters so much.

What language are the reviews in?

Mostly Dutch (locale: "nl"), which is the point: these are dutch travel reviews written by the guests who booked from the Netherlands and Belgium. The field is on every row, so you can split by language before you translate.

Does it include the hotel's replies?

Yes. Zoover owner replies come back in response, in full, with response_date, response_author and response_position. They are part of the review row, at no extra cost.

How fast is it, and will Zoover block me?

One accommodation page plus one review request per property, paced at one request per second per session (raise sessions to go wider). A paced probe of ten different properties on one datacenter session returned ten of ten, and the actor rotates its proxy session on any refusal and retries.

What happens when a property has no reviews?

You get a free status row with status: "no_reviews" and total: 0, and an accommodation row with the property's details. Nothing is charged. The run does not fail — that is the normal answer on this site.

Can I get zoover guest feedback into a spreadsheet?

Yes — export the dataset as CSV or XLSX from the run page, or hit the dataset API with format=csv. Every field in the tables above becomes a column.

Same billing model, same row shapes, other sources:

  • Booking.com Reviews Scraper — the global OTA counterpart, with the same charged-equals-delivered rule.
  • TripAdvisor Reviews Scraper — up to 30 site languages, sub-ratings and management responses.
  • Kurzurlaub Reviews Scraper — the German short-break market, the closest sibling to this one.
  • HRS Reviews Scraper — German business-travel hotel reviews from HRS with twelve category votes and the hotel's replies, the corporate counterpart to Zoover's holiday guests.
  • Agoda Reviews Scraper — Agoda guest reviews with separate positives and negatives and the hotel's reply, by hotel name, URL or id.
  • Google Hotels Prices Scraper — what the same properties charge: every booking site's rate for a stay as its own row, for the price behind the score.

Run them over the same portfolio and you have the Dutch, German and global guest voice of every property in one dataset shape.