Hrs Hotels Reviews Scraper
Pricing
from $3.50 / 1,000 reviews
Hrs Hotels Reviews Scraper
Scrape guest reviews from any HRS hotel to JSON, CSV or Excel. Exports review text, 1-10 ratings, per-category scores, traveller type, dates and hotel replies — no login or API key needed. Sweeps all seven HRS locales so you get every published review, not just the ones in one language.
Pricing
from $3.50 / 1,000 reviews
Rating
0.0
(0)
Developer
Reviewly
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
HRS Hotel Reviews Scraper — Export Guest Reviews to JSON, CSV & Excel
Scrape every published guest review from any hotel on HRS.com and HRS.de — review text, 1–10 ratings, 12 category scores, traveller type, dates and hotel replies — in seconds. No login, no API key, no cookies.
- ✅ Gets reviews other scrapers miss — HRS splits reviews across 7 language sites. This Actor sweeps all of them and merges the results.
- ✅ Rich data, not just stars — per-category scores (cleanliness, breakfast, beds…), traveller segments, and management responses.
- ✅ Fast and cheap — about 3.5 seconds per hotel, no browser, no CAPTCHA solving.
- ✅ Honest counts — clear reporting of what HRS actually publishes vs. the headline rating number.
- ✅ Export anywhere — JSON, CSV, Excel, XML, or straight into your app via API.
📌 What This Actor Does
HRS is one of Europe's largest hotel booking platforms, especially dominant in business travel across Germany, Austria and Switzerland. Its guest reviews are detailed — every review carries a 1–10 score plus up to 12 individual category ratings — but HRS offers no public API and no way to export them.
This Apify Actor does that for you. Give it a hotel URL or hotel ID, and it returns a clean, structured dataset of that hotel's reviews and profile.
Who it's for
| You are… | You use it to… |
|---|---|
| Hotel & revenue managers | Track your property's reputation and benchmark against competitors |
| Hospitality groups & chains | Monitor reviews across an entire portfolio in one run |
| Market researchers & analysts | Build datasets on European hotel quality and guest sentiment |
| Data scientists & AI teams | Feed real multilingual review text into sentiment models and LLMs |
| Travel tech & OTA developers | Enrich listings with review data HRS doesn't expose via API |
| Agencies & consultants | Produce reputation audits and competitor reports for clients |
✨ Key Features
- Complete review coverage. Sweeps all 7 HRS language sites (German, English, Spanish, French, Italian, Dutch, Polish) and merges them into one deduplicated set.
- Full review detail. Positive comment, negative comment, 1–10 score, recommendation flag, traveller type, and exact timestamp.
- Category-level ratings. Up to 12 scores per review: cleanliness, value for money, breakfast, bed quality, room size, bathroom, reception friendliness, staff service, atmosphere, room layout, restaurant and wellness.
- Hotel management replies. Captures the hotel's public response where one exists.
- Complete hotel profile. Name, star rating, full address, GPS coordinates, image, average score, recommendation rate, and rating breakdowns by traveller segment.
- Bulk scraping. Process one hotel or hundreds in a single run.
- Incremental runs.
targetDatecollects only reviews newer than your last run. - Stable review IDs. Every review gets a deterministic ID so you can deduplicate across runs.
- Analysis-ready output. Split and combined review text, so it works with CSV tools and AI pipelines alike.
- No blocking. No CAPTCHAs, no login walls, no anti-bot workarounds needed.
🧠 Why This Actor Is Different
It solves the problem most HRS scrapers get wrong
An HRS hotel page only shows the reviews written on that language's website.
Take hotel 391864. The English page shows 2 reviews. If your scraper reads that page — which is the obvious thing to do — that's all you get. The German page for the same hotel has 32. The real total is 34.
Scraping one page returns 6% of the available reviews for that hotel. This Actor fetches every language site and merges them, so you get all 34.
It tells you the truth about review counts
HRS displays "67 ratings" for that hotel, but only 34 are published anywhere, in any language. The other 33 are score-only submissions with no written comment, plus ratings older than HRS's ~24-month display window. HRS never serves them — to anyone.
Rather than quietly returning 34 and letting you wonder what broke, this Actor reports both numbers (totalRatings and reviewsScraped) and explains the gap in the run log. No guesswork.
Built on the data layer, not fragile HTML
It reads HRS's own structured server data rather than scraping rendered HTML with CSS selectors. That means cleaner values, no formatting artifacts, and far less breakage when HRS redesigns its pages.
Fast and lightweight
No headless browser, so no browser overhead and no CAPTCHA-solving costs. A 5-hotel run with 67 reviews completes in under 18 seconds.
⚙️ Input Configuration
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
startUrls | Array | One of these | – | HRS hotel page URLs. Any language version works. |
hotelIds | Array | One of these | – | Numeric HRS hotel IDs. Use instead of, or alongside, startUrls. |
languages | Array | No | all 7 | Restrict to specific language sites. Leave empty for complete results. |
maxReviews | Integer | No | 0 | Max reviews per hotel, newest first. 0 = unlimited. |
targetDate | String | No | – | Only reviews on or after this date (YYYY-MM-DD). |
proxyConfiguration | Object | No | – | Optional. HRS does not block requests, so this is rarely needed. |
Basic example — one hotel, all reviews
{"startUrls": [{ "url": "https://www.hrs.com/en/hotel/391864" }]}
Bulk example — several hotels
{"hotelIds": ["391864", "60754", "464662"],"maxReviews": 0}
Incremental example — only new reviews since your last run
{"hotelIds": ["391864"],"targetDate": "2025-06-01"}
💡 Tips for best results
- Leave
languagesempty. Restricting it is the single most common way to end up with an incomplete dataset. Only narrow it if you specifically want reviews from one market. - Where to find the hotel ID: it's the number at the end of the URL —
hrs.com/en/hotel/391864. Bothhrs.comandhrs.deURLs work. maxReviewsdoesn't reduce cost or runtime. HRS sends a whole language's reviews in one page load, so the Actor still fetches everything and then trims. Use it to cap dataset size, not to run faster.- Run daily or weekly with
targetDateset to your last run date for efficient reputation monitoring. - Skip the proxy unless you're running very large batches.
📤 Output Format
The Actor stores one dataset record per hotel, with that hotel's reviews nested inside it. Export as JSON, CSV, Excel, XML, or fetch via the Apify API.
{"hotelId": 391864,"name": "Hotel Brandenburger Tor Potsdam","url": "https://www.hrs.com/en/hotel/391864","stars": 4,"street": "Brandenburger Str. 1 - 3","city": "Potsdam","postalCode": "14467","country": "DEU","latitude": 52.399619,"longitude": 13.048601,"imageUrl": "https://foto.hrsstatic.com/fotos/...jpg","averageRating": 9.1,"ratingMax": 10,"totalRatings": 67,"recommendationRate": 97,"categoryAverages": {"hotelTidiness": 9.2,"friendlinessOfReception": 9.4,"breakfastService": 9.3,"pricePerformanceRatio": 8.8},"ratingsByTravellerType": [{ "travellerType": "BUSINESS", "travellerTypeLabel": "Business traveller", "rating": 9, "recommendationRate": 94.7 }],"languagesScraped": ["de", "en", "es", "fr", "it", "nl", "pl"],"reviewsScraped": 34,"reviewsAvailable": 34,"reviews": [{"reviewId": "5cc88d4ec4709c48","rating": 9.1,"ratingMax": 10,"recommended": true,"reviewerName": null,"travellerType": "BUSINESS","travellerTypeLabel": "Business traveller","date": "2024-11-27T08:34:31.260Z","siteLanguage": "de","positiveComment": "freundliches Personal","negativeComment": null,"text": "freundliches Personal","hotelReply": "Lieber Gast, vielen Dank für Ihr Feedback! ...","categoryRatings": { "hotelTidiness": 10, "qualityOfBeds": 9 },"sourceUrl": "https://www.hrs.com/de/hotel/391864"}]}
Hotel fields
| Field | Type | Description |
|---|---|---|
hotelId | Number | HRS hotel ID |
name | String | Hotel name |
url | String | Canonical HRS hotel page |
stars | Number | Official star rating (1–5) |
street, city, postalCode, country | String | Full address |
latitude, longitude | Number | GPS coordinates |
imageUrl | String | Main hotel photo |
averageRating | Number | Overall guest score, out of 10 |
totalRatings | Number | All ratings HRS counts, including unpublished ones |
recommendationRate | Number | % of guests who would recommend |
categoryAverages | Object | Hotel-wide average per category |
ratingsByTravellerType | Array | Score and recommendation rate per guest segment |
languagesScraped | Array | Language sites successfully visited |
reviewsScraped | Number | Reviews in this record |
reviewsAvailable | Number | Reviews found before maxReviews trimmed them |
Review fields
| Field | Type | Description |
|---|---|---|
reviewId | String | Stable ID, consistent across runs — use it to deduplicate |
rating | Number | Guest's overall score, out of 10 (ratingMax) |
recommended | Boolean | Whether the guest recommends the hotel |
reviewerName | String | null | Display name; null when posted anonymously |
travellerType | String | BUSINESS, PRIVATE, MATURE_COUPLE, YOUNG_COUPLE, … |
travellerTypeLabel | String | Human-readable version of the above |
date | String | ISO 8601 timestamp |
siteLanguage | String | Which HRS language site the review came from |
positiveComment | String | null | What the guest liked |
negativeComment | String | null | What the guest disliked |
text | String | null | Both comments combined — convenient for CSV and AI tools |
hotelReply | String | null | The hotel's public response, if any |
categoryRatings | Object | This guest's individual category scores |
sourceUrl | String | Page the review was read from |
⚠️ Three things worth knowing about the data
- Ratings are out of 10, not 5. HRS uses a 1–10 scale. The
ratingMaxfield carries this so nothing downstream has to assume. - Reviews are split in two. HRS asks guests separately what they liked and disliked, so
positiveCommentandnegativeCommentare distinct fields and either can be empty. Thetextfield joins them for convenience. siteLanguageis the source site, not detected language. It tells you which HRS site a review came from — usually but not always the language of the text. (The English site sometimes carries German-language reviews.) Don't use it as a language label for the review body.
▶️ How to Use
Step 1 — Find your hotel
Search on hrs.com and open the hotel's page. Copy the URL, for example:
https://www.hrs.com/en/hotel/391864
Step 2 — Add it to the input
Paste the URL into Start URLs, or just the number (391864) into Hotel IDs. Add as many hotels as you like.
Step 3 — Run it
Click Start. Most hotels finish in a few seconds.
Step 4 — Export
Open the Dataset tab and download as JSON, CSV, Excel or XML, or pull it via API:
https://api.apify.com/v2/datasets/<DATASET_ID>/items?format=csv
Common workflows
Monitor your hotel weekly
Schedule the Actor to run every Monday with targetDate set to the previous week. You'll only collect new reviews.
Benchmark against competitors
Put your hotel and 5–10 nearby competitors into hotelIds in one run, then compare averageRating and categoryAverages to see exactly where you win or lose.
Build a training dataset
Run across hundreds of hotel IDs with maxReviews: 0 to build a large multilingual review corpus with matching category scores.
📈 Use Cases
1. Hotel reputation monitoring
Track your score over time, catch negative reviews within days, and confirm your team is replying. categoryAverages shows precisely which areas — breakfast, cleanliness, value — are pulling your score down.
2. Competitor benchmarking
Scrape every competing hotel in your city and compare average scores, recommendation rates, and category strengths. Discover that competitors consistently beat you on breakfast but lose on location — then price accordingly.
3. Market research & travel analytics
Build datasets covering entire cities or regions. Because HRS is strong in DACH business travel, it's a valuable source for analysing the European corporate hotel market specifically.
4. AI & sentiment analysis
Feed real multilingual guest feedback into sentiment models, topic clustering, or LLM pipelines. Each review arrives with a numeric score and category ratings attached — ideal labelled training data.
5. Due diligence & property investment
Assessing a hotel acquisition or franchise deal? Pull its full review history to check guest satisfaction trends, recurring complaints, and how management handles criticism.
🛠️ Advanced Tips
Performance. The Actor makes 7 requests per hotel (one per language site) — roughly 3.5 seconds each. A 100-hotel run takes around 6 minutes. Runtime scales with hotel count, not review count.
Cutting requests. If you only need German-market reviews, set languages: ["de"] to make one request per hotel instead of seven. You'll be ~7× faster but you will miss reviews from other sites.
Proxies. HRS doesn't block scraping, so no proxy is needed for normal use. For very large batches, enable Apify Proxy (residential or datacenter) to spread requests across IPs. The Actor automatically retries with a fresh IP if a request fails.
Scaling to thousands of hotels. Split hotel IDs across several runs rather than one huge run — smaller runs are easier to monitor, retry, and resume.
Deduplicating across runs. Use reviewId as your primary key. It's derived from the review's content and stays identical across runs and language sites.
Scheduling. Use Apify Schedules for automated monitoring, and Webhooks to push new reviews straight into Slack, a database, or Google Sheets.
❓ FAQ & Troubleshooting
Why is reviewsScraped lower than totalRatings?
This is expected and correct. totalRatings counts every score the hotel ever received; HRS only publishes reviews that have written text and fall inside its ~24-month display window. Everything HRS makes public is in your dataset — the rest isn't accessible to anyone, including regular website visitors.
The Actor returned very few reviews. Did it fail?
Probably not — some hotels genuinely have few published reviews. Check languagesScraped in the output. If it lists all 7 languages, the scrape was complete. Also confirm you didn't restrict languages or set a targetDate that filters out most reviews.
Why does it visit 7 URLs for one hotel? Because HRS only shows reviews on the language site where they were written. Visiting all 7 is the only way to get a complete set. (For hotel 391864, the English page alone would return 2 of 34 reviews.)
Can I get reviews in one specific language?
Yes — set languages to e.g. ["de"]. Note this selects the site the review was posted on, which is usually but not always the language of the text.
Do I need a proxy? No. HRS serves these pages without blocking. Proxies are optional and mainly useful for very large runs.
Do I need an HRS account or API key? No. The Actor uses only publicly available data.
"Hotel does not exist on HRS (404 on every locale)" The hotel ID is wrong or the property has been removed. Open the URL in your browser to confirm. The Actor skips it and continues with your other hotels.
Can I scrape hotel prices or availability? No. This Actor focuses on reviews and hotel profile data. Prices depend on dates and occupancy and are out of scope.
Why are some reviews missing a reviewer name?
HRS lets guests post anonymously. Those come through as reviewerName: null.
What about GDPR and legal use? The Actor collects only publicly available review data — no personal contact details or private information. Reviewer names appear as HRS publishes them (typically a first name and last initial). You are responsible for using the data in line with applicable laws and Apify's Terms of Service.
Can I export to Google Sheets or a database? Yes. Use Apify's built-in integrations, webhooks, or the Dataset API. CSV export works directly with Sheets and Excel.
💰 Pricing
This Actor uses pay-per-event pricing: you're charged per review successfully scraped and stored. Hotels that fail to scrape cost you nothing, and hotels with no reviews are free.
Apify platform usage (compute, proxy) is billed separately under your plan.
📞 Support
Questions, bug reports, or feature requests are welcome.
- Email: me@ahmedhrid.com
- Issues: Use the Issues tab on this Actor's page in Apify Console
If you're reporting a problem, please include the hotel URL or ID and your run ID — it makes diagnosis much faster.
Need a scraper for a different booking platform, or a customised version of this one? Get in touch.
🔗 Related Keywords
HRS scraper · HRS.com scraper · HRS.de scraper · hotel reviews scraper · hotel review data · guest review scraping · hotel reputation monitoring · web scraping · Apify actor · travel data extraction · hospitality market research · European hotel data · booking platform scraper · hotel ratings API alternative