Booking.com Search Scraper - Hotels & Prices
Pricing
from $1.70 / 1,000 results
Booking.com Search Scraper - Hotels & Prices
Search Booking.com by destination and export every property returned: coordinates, address, star rating, guest review score, description, photo, and paid-placement markers. Add check-in/check-out dates for real per-stay prices.
Pricing
from $1.70 / 1,000 results
Rating
0.0
(0)
Developer
The Netaji
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Booking.com Search Scraper
The Actor searches Booking.com by destination and returns every property in the result set: coordinates, address, star rating, guest review score, description, photo, and paid-placement markers. Setting checkin and checkout adds a real, dated price to each row; without them, Booking prices a stay rather than a hotel, and no row carries one.
Accepted input
| Field | Type | Default | Description |
|---|---|---|---|
destination | string | required | Free text, exactly as typed into Booking's own search box: a city, region, neighbourhood, or country. |
checkin | string (YYYY-MM-DD) | — | Arrival date. Must be set together with checkout. |
checkout | string (YYYY-MM-DD) | — | Departure date. Must be after checkin. |
adults | integer | 2 | Guests in the party, 1-30. |
rooms | integer | 1 | Rooms wanted, 1-30. |
offset | integer | 0 | Row offset to start pagination at, 0-10000, in steps of rows_per_page. |
rows_per_page | integer | 25 | Properties Booking returns per request, 1-100. |
maxItems | integer | 100 | Maximum properties saved across all pages. 0 removes the limit. |
{"destination": "San Francisco","checkin": "2026-09-10","checkout": "2026-09-12","adults": 2,"rooms": 1,"maxItems": 50}
Response fields
| Field | Contents |
|---|---|
property_id | Booking's internal property id, stable across dated and dateless searches |
slug, country_code | Together, the input the Booking.com Hotel Scraper takes |
url, name, description | The property's page, name, and one-paragraph blurb |
star_rating / star_rating_scale_max | The property's star classification, out of five |
review_score / review_score_scale_max | The guest score, out of ten |
review_count | Exact review count the score is computed over |
external_review_score / external_review_count | A score sourced from outside Booking's own guests, when one exists |
photo_url | The property's lead photo |
destination_id | Booking's internal id for the city or area |
accommodation_type_id | Booking's own code for the kind of property; Booking publishes no label mapping for it |
is_closed, is_sold_out, is_sustainable | Property status flags |
is_ad, native_ad_id | Whether the row bought its position, and the placement id if so |
is_preferred, is_preferred_plus | Booking's Preferred Partner tiers, a commercial relationship distinct from a paid ad slot |
location | address, city, country_code, latitude, longitude, display_location, distance_from_centre, public_transport_distance, is_centrally_located, is_within_best_location_score_area |
price | null unless checkin/checkout were set; otherwise per_night_display, stay_total_display, stay_total_amount, currency |
{"slug": "club-quarters-san-francisco","country_code": "us","name": "Club Quarters Hotel","star_rating": 4,"review_score": 8.2,"review_count": 5043,"is_ad": false,"price": { "per_night_display": "$193", "currency": "USD" }}
Behaviour on pagination
The Actor walks Booking's search API in pages of rows_per_page rows, starting at offset, and advances the offset itself; the run does not need to be started once per page. Each response states has_more and exhausted, computed from Booking's own reported total (total_results) rather than from whether the page came back full, so the last page of a 353-property city (three rows) is not mistaken for a full page one step early. The walk stops on whichever comes first: has_more turning false, an empty page, or maxItems being reached. This calls the same search API Booking's own frontend calls when scrolling, not its search page, which serves the identical first 25 results regardless of any offset passed to it.
Frequently asked questions
Why is price null on every row?
No checkin/checkout was given. Booking prices a stay, not a hotel: without both dates, every row comes back with no price at all, not because the data is missing but because a price is not a property of a hotel by itself. Setting both dates adds a real, dated price to every row.
Why do star_rating and review_score look like two different ratings?
They are. star_rating is the property's star classification, out of five; review_score is the guest score, out of ten. star_rating_scale_max and review_score_scale_max state each row's own ceiling explicitly so the two are never read on the wrong scale.
Should rows with is_ad: true be filtered out?
Not necessarily; is_ad states a fact rather than making a recommendation. It marks a row that bought its position in the results Booking returned, which is a different thing from is_preferred, Booking's separate Preferred Partner programme. Both are stated on every row so a reader who wants only organic placements can filter for is_ad: false directly.
Why did the run save fewer rows than maxItems?
Either the destination's result set was exhausted before the limit was reached (a small town can hold fewer than 25 properties in total), or the search matched nothing Booking could place and it returned an empty page. Either way the run finishes normally rather than failing, since an empty result is a real answer, not an error.
Can a run be resumed after being interrupted? Yes. A resumed run continues from the exact page and row it stopped on, using the offset of the page the interruption landed inside rather than re-fetching pages already saved.
Related
Booking.com Hotel Scraper fetches one property's full record by slug: the complete subscore breakdown and up to ten featured guest reviews. Every row from this Actor carries the slug and country_code it needs, so a search result feeds directly into it.