Booking.com Hotel Search Scraper avatar

Booking.com Hotel Search Scraper

Under maintenance

Pricing

from $0.80 / 1,000 hotel-listeds

Go to Apify Store
Booking.com Hotel Search Scraper

Booking.com Hotel Search Scraper

Under maintenance

Scrape every hotel Booking.com is selling for a destination and your dates. Just add city names and get name, stars, guest review score, price for the stay, address, coordinates, free-cancellation flag and a photo. Export to CSV, JSON or Excel, or schedule it.

Pricing

from $0.80 / 1,000 hotel-listeds

Rating

0.0

(0)

Developer

BonCross API

BonCross API

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

17 hours ago

Last modified

Categories

Share

What is Booking.com Hotel Search Scraper?

Booking.com Hotel Search Scraper prices a whole destination for your dates: hotels, apartments, hostels, guest houses and homes, one row each, with the price for your party, the guest score, the address and the coordinates. You type a city and two dates. Or you point it at a landmark, draw a box on the map, or let the dates float.

Why it's worth choosing for market work:

  • Booking does the sorting and filtering. All ten of its sort orders and its sidebar filters are passed to Booking itself, and what you get is what the site returns for the same search. A property Booking filters out is never charged.
  • You can search the way the site lets a traveller search: around a landmark or airport, inside a map rectangle, within a radius of a point, or across flexible dates where each property is priced at its own cheapest stay.
  • Every price says whether tax is in it. Each row has a flag and the amount payable on top, and prices are quoted on one basis on every run, which keeps two runs comparable.
  • It's fast at scale. Four cities at 300 hotels each took 4 to 5 seconds on most runs, and 36 cities (about 10,400 rows) took 15 to 21 seconds.
  • $1.20 per 1,000 hotels on the Free plan, $0.80 on Business. Looking up a destination is free and proxy usage is included.

BonCross Verified means we tested this actor against the live site before release and kept the record:

  • 46 of 46 live checks on its inputs and filters passed on 8 October 2026
  • 7 destinations run on 7 October 2026 in 7 countries: 175 hotels, none empty
  • Charges checked against the 175 rows

Four ways to define the market you want

You haveYou setYou get
A place name"Destinations": a city, region or districtEvery property Booking is selling there for your dates
A point of interest"Landmark or airport", with or without a destination, and a radius if you want oneProperties nearest first, each with its distance from the landmark
An area on a map"Map area: box", or "Map area: centre point" with a radiusEverything inside the box or the circle
No fixed dates"Flexible months" with a length of stay and a start day, or "Flexible: days either side"Each property priced for its own cheapest dates, which are on the row

You can combine any of them with Booking's filters: property type, stars, review score, budget per night, meals, free cancellation and no prepayment, plus anything else on its sidebar by name, from "Swimming pool" to a neighbourhood or a hotel brand.

What data do you get for each property?

FieldNotes
🏨id, hotelId, name, slug, urlthe property and a link back to it; id is the property and stay
propertyTypeId, propertyTypeBooking's type code and its name on Booking's Property type filter ("Hotels", "Aparthotels", "Hostels")
📅checkIn, checkOut, nightsthe stay the price was quoted for
💶priceTotal, priceTotalText, pricePerNight, currencystay total (as a number and as the site shows it) and nightly equivalent
priceBeforeDiscount, discountsthe struck-through price and the deal behind it, such as "Limited-time Deal"
🧾pricesIncludeTax, taxesAndChargesExcludedwhether the price includes every tax and charge Booking puts a figure on, and the amount payable on top where it does not
hasExcludedChargestrue where something is payable on top of the price, such as a city tax
⭐stars, qualityRatingofficial star rating; qualityRating is Booking's own 1-5 award for homes and apartments (the squares on the card), kept apart from stars
💬rating, ratingScale, ratingText, reviewCountguest score out of 10 and its wording; null on a property with no reviews yet
📍address, city, countryCode, lat, lngfull location
🚇neighbourhood, distanceFromCentreText, publicTransportTextas the site words them
isFreeCancellation, isNoPrepaymentbooking conditions advertised on the card
🛏bedsInRoom, bedroomsthe offer matched to your party; bedrooms is null on ordinary hotel rooms
🍳mealPlanTextthe meal plan on the card, where one is advertised (a minority of properties)
isSoldOut, isSponsored, isSustainable, isCentrallyLocatedrow flags
isPartnerSuppliedtrue when every room offered for your dates comes through one of Booking's supply partners rather than the property itself
📷photothe property's main photo
sortBythe order the rows came back in
🗺destination, destinationId, destinationTypethe destination you typed and the place it resolved to (city, region, district …)
distanceFrom, distanceMeters, distanceTexton a landmark or map-point search: the landmark (or point), the straight-line distance in metres and Booking's own wording ("0.2 miles from Eiffel Tower")
scrapedAtwhen the row was collected
  1. Create a free Apify account and open Booking.com Hotel Search Scraper.
  2. Add your destinations: city, region or district names, such as "Paris" or "Lisbon".
  3. Set your check-in and check-out dates and how many adults, rooms and children you're pricing for.
  4. If you want, pick a sort order, add filters, and cap the rows per destination or for the run.
  5. Click Start. Download the rows as CSV, Excel or JSON when it finishes, usually within seconds.

How much does it cost?

EventFree planStarterScaleBusiness
actor-start, per run$0.001$0.001$0.001$0.001
hotel-listed, per property row written$0.0012$0.001$0.0009$0.0008

Enterprise plans pay the Business price.

$1.20 per 1,000 hotels on the Free plan, $0.80 on Business. You pay nothing extra to look a destination up, error rows are never charged, and proxy usage and platform usage are included in the price.

  • One city, 100 hotels: $0.001 + 100 × $0.0012 = $0.121 ($0.081 on Business).
  • Five cities, 500 hotels each: $0.001 + 2,500 × $0.0012 = $3.001 ($2.001 on Business).
  • A daily scan of one city's 100 hotels for a month: 30 × ($0.001 + 100 × $0.0012) = $3.63 for the month ($2.43 on Business).

The $5 of credits that comes with Apify's Free plan each month covers about 41 searches of 100 hotels, or roughly 4,100 priced properties.

⬇️ Input

Give it destinations and dates, and you have a run. Everything else narrows or reshapes the search.

You have two limits. "Max hotels per destination" (default 100, and 0 means every one) applies to each destination separately. "Max rows in total" caps the whole run across every destination, and 0 means no ceiling.

InputTypeNotes
destinationsarrayCity, region or district names
checkIn, checkOutstringYYYY-MM-DD. Check-out must be after check-in
adults, rooms, childrenAgesnumber, arrayWho the prices should cover
maxHotelsPerDestinationnumberProperties per destination (default 100). 0 means every one
maxItemsnumberCeiling for the whole run, across every destination (default 0, no ceiling)
sortBystringBooking's sort orders (default popularity): popularity (Our top picks), upsort_bh, price, price_from_high_to_low, review_score_and_price, class, class_asc, class_and_price, distance_from_search, bayesian_review_score
propertyTypesarrayNames from Booking's Property type filter: Hotels, Apartments, Hostels, Ryokans, Entire homes & apartments …
minStars, minRatingnumberBooking's star and review-score filters; a score between its bands (8.5) is finished off row by row
minPricePerNight, maxPricePerNightnumberBooking's budget filter, per night, in the run's currency
mealPlansarraybreakfast, breakfast_and_dinner, breakfast_and_lunch, all_meals, all_inclusive, self_catering
onlyFreeCancellation, noPrepaymentOnlybooleanBooking's reservation-policy filters
excludePartnerSuppliedbooleanLeave out properties whose rooms are all sold through a supply partner (default off: they are real and bookable)
filtersarrayAnything else on the sidebar, by label ("Swimming pool", "Free WiFi", "Pets allowed") or code (hotelfacility=433)
destinationTypestringForce what a name resolves to. Auto prefers a city
landmarkstringSearch around a landmark or airport ("Eiffel Tower", "Big Ben" or "Heathrow Airport"), looked up inside each destination the way Booking's own landmark search does, or on its own with no destination. Rows come nearest first unless you choose another sort order
radiusKmnumberKeep properties within this distance of the landmark, the map centre, or otherwise the destination's centre. Required with mapCentre
mapBoundingBoxstringA map rectangle instead of destinations: "south lat, west lng, north lat, east lng"
mapCentrestringA map point instead of destinations, "lat, lng" such as "48.859, 2.3585", with radiusKm
flexibleMonths, flexibleNights, flexibleStartDayarray, number, stringAny dates in these months (YYYY-MM), for this many nights, starting on this weekday. Replaces check-in and check-out
flexibleDaysnumberLet each stay move 1, 2, 3 or 7 days either side of check-in
currency, languagestringCurrency code and Booking language code
maxConcurrency, delayMsnumberParallel requests, 1 to 32 (default 32), and an optional pause before each call in ms (default 0). Neither changes the rows

Two cities for one night, well-reviewed properties only, in euros

{
"destinations": ["Paris", "Lisbon"],
"checkIn": "2026-11-02",
"checkOut": "2026-11-03",
"adults": 2,
"rooms": 1,
"currency": "EUR",
"maxHotelsPerDestination": 100,
"minRating": 8
}

The cheapest hostels and guest houses with free WiFi in Lisbon, under 60 a night

{
"destinations": ["Lisbon"],
"checkIn": "2026-11-02",
"checkOut": "2026-11-04",
"sortBy": "price",
"propertyTypes": ["Hostels", "Guest houses"],
"filters": ["Free WiFi"],
"maxPricePerNight": 60
}

Hotels within 1 km of the Eiffel Tower, nearest first

{
"destinations": ["Paris"],
"landmark": "Eiffel Tower",
"radiusKm": 1,
"checkIn": "2026-11-10",
"checkOut": "2026-11-11"
}

Everything inside a map rectangle over the Marais

{
"mapBoundingBox": "48.853, 2.349, 48.865, 2.368",
"checkIn": "2026-11-10",
"checkOut": "2026-11-11",
"maxHotelsPerDestination": 500
}

A Friday-to-Sunday weekend any time in November or December, each property at its cheapest weekend

{
"destinations": ["Lisbon"],
"flexibleMonths": ["2026-11", "2026-12"],
"flexibleNights": 2,
"flexibleStartDay": "friday"
}

Filter labels are matched on each destination's own sidebar, because the options differ by place (a neighbourhood list, the brands present, the landmarks nearby). Not sure of a label? Each run saves that sidebar, with the label, code and count of each filter, and you can copy the codes from there.

One warning about those counts. They're Booking's sidebar figures, and for a few options they measure something different from what the filter returns. The clearest case is Number of bedrooms: the filter counts bedrooms in entire homes and apartments, while the sidebar count also includes hotels whose offer for your party spans two rooms. In Tokyo, 852 hotels are counted under "2+ bedrooms" and the filter returns 46 of them.

For developers

  • The run's key-value store holds STATS (counts, including each destination's matching total in totalByDestination, which is the number the rows follow) and SEARCH_OPTIONS (each destination's filters with their labels, codes and counts).
  • maxHotelsPerDestination is the per-destination limit and maxItems the run-wide one.
  • A filter that keeps almost nothing is cut short: after 500 rows read for a destination, the run stops reading it if fewer than 0.15 rows per 100 are being kept.
  • maxConcurrency (default 32, from 1 to 32) is how many requests run at once. Several destinations and pages are read together. Set it to 1 for a strictly one-at-a-time run. The hotels are the same either way.
  • delayMs (default 0) pauses before each call. Values above 2000 are treated as 2000.
  • A map area is one search. Its rows have destination "map …" with the area's coordinates, destinationType BOUNDING_BOX or LATLONG, and no destinationId.
  • If the platform moves or restarts a run part-way, it carries on where it stopped. Rows already in the dataset aren't delivered or billed twice. We tested it by restarting a 36-city run part-way, and no row appeared twice.

⬆️ Output

One row per property. This one is from the Paris and Lisbon example above, run on 7 October 2026.

{
"id": "51086-2026-11-02-2026-11-03",
"hotelId": 51086,
"name": "Mercure Tour Eiffel Grenelle",
"slug": "toureiffelparis",
"url": "https://www.booking.com/hotel/fr/toureiffelparis.html",
"checkIn": "2026-11-02",
"checkOut": "2026-11-03",
"nights": 1,
"address": "64, Boulevard de Grenelle",
"city": "Paris",
"countryCode": "FR",
"lat": 48.8505123550271,
"lng": 2.2926490008831,
"propertyTypeId": 204,
"stars": 4,
"qualityRating": null,
"rating": 8.1,
"ratingScale": 10,
"ratingText": "Very good",
"reviewCount": 1049,
"currency": "EUR",
"priceTotal": 205.23,
"priceTotalText": "€ 205.23",
"pricePerNight": 205.23,
"priceBeforeDiscount": null,
"discounts": [],
"pricesIncludeTax": false,
"taxesAndChargesExcluded": 37.42,
"hasExcludedCharges": true,
"isSoldOut": false,
"isFreeCancellation": false,
"isNoPrepayment": false,
"isSponsored": false,
"isSustainable": true,
"isPartnerSupplied": false,
"bedsInRoom": 2,
"bedrooms": null,
"mealPlanText": null,
"distanceFromCentreText": "2.7 miles from centre",
"neighbourhood": "15th arr., Paris",
"publicTransportText": "Dupleix station is within 100 yards",
"isCentrallyLocated": false,
"photo": "https://cf.bstatic.com/xdata/images/hotel/square600/776603526.webp?k=2eabefa89ada95f00159c251594146fe6f5bf6d54d30b2f01835668f44d57471&o=",
"scrapedAt": "2026-10-07T20:34:31.892Z",
"propertyType": "Hotels",
"destination": "Paris",
"destinationId": -1456928,
"destinationType": "CITY",
"sortBy": "popularity"
}

How to read the price

Every price is the one Booking.com shows a visitor in the United States, whichever run or row you look at. Two runs of the same search are always on the same basis. On that basis some properties have every tax inside the price and others quote it before taxes, and each row tells you which. pricesIncludeTax is false where a tax or charge with a figure is payable on top, and taxesAndChargesExcluded is that figure for the stay. priceTotal + taxesAndChargesExcluded is then the full price: €205.23 + €37.42 in the row above. Prices are reported exactly as Booking returned them and never converted from one basis to the other. A charge Booking can't put a figure on, such as a city tax that "may apply", doesn't count against pricesIncludeTax and is flagged by hasExcludedCharges.

Unrated properties

A property with no reviews yet returns rating, ratingScale and ratingText as null and reviewCount as 0. A score of zero there would read as the worst possible rating and drag down any average you compute, which is why you get "not rated". Up to 7 of 200 properties were unrated in a large city search.

Landmark, map and flexible-date rows

Searching around a landmark or a map point adds three columns: distanceFrom (the landmark's name, or the point), distanceMeters (the straight-line distance from it, worked out from the two sets of coordinates) and distanceText (Booking's own wording). On the Eiffel Tower example, Pullman Paris Tour Eiffel came back with distanceMeters 349 and distanceText "0.2 miles from Eiffel Tower". distanceFromCentreText is then empty, since Booking's distance is measured from the landmark or the point.

On a flexible-date search each row is priced for its own dates. checkIn, checkOut and nights are the stay Booking priced that property for: its cheapest stay of the length and start day you asked for, in the months you gave, or its cheapest night inside the window around your dates. priceTotal is for those dates and id includes them, which means the same property can appear on another run at other dates. We checked this against fixed-date searches of the same properties on the dates given: the prices were identical, and the dates were the cheapest of the alternatives.

You can export the dataset as JSON, CSV, Excel, XML or HTML.

How many hotels can you get, and how fast?

As many as the destination has. A large city runs to a couple of thousand matching properties for a one-night stay (2,057 in Osaka and 1,406 in Kyoto when measured), and the actor pages through them until it reaches your limit.

RunRowsTime
36 cities, two nights, 300 eachabout 10,40015 to 21 s
12 cities, two nights, 300 each3,6007 to 9 s
Lisbon, Bangkok, Osaka and Kyoto, two nights, 300 each1,2004 to 5 s on most runs, up to 15 s
One city (Osaka), one night, 10 hotels103 to 5 s

Whole runs on Apify, measured on 2 October 2026, with start-up and the resolving of the destination names included. The spread on the four-city line is Booking.com itself, which answers faster at some hours than others. The 36-city run worked out at about 30,000 rows a minute, and a few hundred destinations finish well inside the default one-hour run limit.

Limitations

  • You get one stay per run, unless you search flexible dates, where each property gets its own cheapest stay. To compare fixed dates, run the same destination across several date pairs.
  • A search row has one price per property, the cheapest the site is advertising for your party. For every room and rate plan, use Booking.com Room Rates Scraper.
  • propertyType names Booking's own type code in English (en-gb, the default), the same on every run: an aparthotel is "Aparthotels" even when Booking lists it under Hotels. One code that Booking never names on its filter (mostly inns) has an empty propertyType, and propertyTypeId is always there. In other languages the name comes from the destination's filter list, and it can be empty for a type that list doesn't show. Booking's own Hotels filter can still include aparthotels on some searches and not others.
  • Sold-out properties aren't listed. The search returns properties with something to sell for your dates, as Booking's own "Only show available properties" does.
  • Partner-supplied rooms come and go between identical searches. Booking offers some properties through supply partners, and whether those rooms are listed changes from one search to the next. A property whose rooms are all partner-supplied (isPartnerSupplied: true) can be missing from the next identical search, and Booking leaves such properties out of its own match count: a search Booking counts as 31 properties can return 31 or 32 rows. In one 300-row search, 22 rows were partner-supplied.
  • Price order is Booking's own. Sorting by price follows the figure Booking ranks by, which isn't always the price shown: in 8 cheapest-first and dearest-first runs of 30 rows, at most one row per run sat out of place.
  • Paid placements are rare. isSponsored was false on all 503 rows measured, which is why there's no option to exclude them.
  • Distances are localised text ("2.7 miles from centre"), because the site words them that way. The wording and unit follow your language input, as a visitor in the United States sees them. On a landmark or map-point search distanceMeters gives the straight-line distance as a number.
  • A flexible-month search needs a start weekday. Booking prices nothing without one.
  • Prices follow the currency and language you ask for. A property's own currency may differ.

FAQ

Why does the same search return a slightly different list the second time?

Mostly because of partner-supplied rooms, which Booking shows in some answers and leaves out of others. If you need a list that holds still from run to run, switch on "Leave out partner-supplied properties". Those properties are real and bookable, and that's why the switch is off by default.

The landmark search picked the wrong place. What do I do?

A landmark is Booking's first suggestion for the name inside the destination. Look at distanceFrom on the rows (or the run log) to see what it resolved to, and give a fuller name if it isn't the place you meant.

Why did a destination resolve to the wrong kind of place?

A bare name prefers the city over a landmark inside it. Set "Destination type" to force a specific kind of place. If Booking has none of that kind, the error row names what it does offer.

Why do some properties have no star rating?

Booking.com doesn't give them one. Apartments, guesthouses and many private rentals are unrated on the site, and the field stays empty. A minimum star filter will therefore remove more than you expect. The guest review score is present far more often and is usually the better filter.

Is the price per night or for the stay, and for how many people?

Both are on the row: priceTotal is the stay and pricePerNight the nightly equivalent. They're quoted for the party you entered, children included.

How do I get the rooms and rate plans, not just one price?

Feed the hotels this actor returns into Booking.com Room Rates Scraper. The url on each row is the input it takes.

Can I compare several dates in one run?

Not with fixed dates. A search returns one stay, and comparing dates means running the same destination once per date pair. If what you want is each property's cheapest dates, a flexible search does that in one run.

Do I need proxies or a Booking.com account?

Neither. No login and no cookie of yours is used, and proxy usage is included in the price.

The actor reads only what Booking.com serves to a logged-out visitor, takes no account access and collects no private data. Reading public pages like these is generally lawful in the UK, EU and US. You remain responsible for how you use what you collect and for the site's own terms.

Pipelines, schedules and agents

Search rows are usually the first step of something longer: a daily price scan into a warehouse, or a list of hotels handed on to the room rates and reviews actors. Apify Schedules run it on a cron, a webhook can fire when a run finishes, and the rows go on to Google Sheets, Slack, Make or Zapier through Apify's integrations.

POST https://api.apify.com/v2/acts/boncross~booking-hotel-search/run-sync-get-dataset-items with the input JSON as the body returns the rows in a single call for short runs. An agent can call the same actor through the Apify MCP server at mcp.apify.com with a city and dates, and gets structured rows back.

More from BonCross

Your feedback

If a filter label doesn't match, a landmark resolves oddly or a row looks wrong against the site, open an issue on the actor's Issues tab and include the input you ran. We reply there, and requests for new search options are welcome.