Booking.com Hotel & Price Scraper avatar

Booking.com Hotel & Price Scraper

Under maintenance

Pricing

from $2.50 / 1,000 results

Go to Apify Store
Booking.com Hotel & Price Scraper

Booking.com Hotel & Price Scraper

Under maintenance

Scrape hotel search results from Booking.com — prices, ratings, reviews, availability, and location. Filter by star rating, price range, and sort order. Supports 10 currencies. Hybrid API + HTML extraction for maximum reliability. Ideal for price monitoring and market research.

Pricing

from $2.50 / 1,000 results

Rating

0.0

(0)

Developer

Tomáš Gregorovič

Tomáš Gregorovič

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

3 days ago

Last modified

Share

Scrape hotel search results from Booking.com with structured data including prices, ratings, availability, location, and amenities. Export to JSON, CSV, or Excel.

Features

  • Dual extraction engine: API interception (primary) + HTML fallback for maximum reliability
  • Fast & Enriched modes: Quick search-only scraping (default) or deep detail page extraction with room options, full amenities, review breakdowns, and photos
  • Anti-detection: Browser fingerprint spoofing, user-agent rotation, viewport randomization, stealth scripts
  • Proxy support: Built-in residential proxy rotation with Apify Proxy (RESIDENTIAL group recommended)
  • Smart pagination: Offset-based with configurable max results (up to 1,000 hotels)
  • Advanced filters: Property type, minimum review score, children with ages, star rating, price range
  • CAPTCHA detection: Automatically detects and backs off on CAPTCHA pages with retry logic
  • Rich data output: 20+ fields per hotel including GPS coordinates, price breakdowns, availability, and optional detail data
  • Production error handling: Clear failure reporting via Actor.fail() with descriptive status messages
  • Graceful degradation: If a detail page fails (CAPTCHA, timeout), search data is still pushed

Use Cases

  • Price monitoring: Track hotel pricing trends over time by scheduling daily or weekly runs. Compare rates across destinations and date ranges to identify pricing patterns.
  • Competitive analysis: Benchmark your property against competitors in the same destination. Monitor review scores, pricing strategies, and availability across the market.
  • Market research: Analyze hotel supply in a destination — count properties by star rating, average price per night, and review scores to assess market saturation.
  • Travel deal alerts: Combine with Apify webhooks to get notified when prices drop below a threshold. Automate deal-finding across multiple destinations.
  • Academic research: Collect structured hospitality data for tourism studies, pricing elasticity research, or geographic analysis of accommodation supply.

Fast vs. Enriched Mode

Fast Mode (default)Enriched Mode
InputenrichData: falseenrichData: true
Speed~50–100 hotels/min~10–20 hotels/min
Data sourceSearch result cards onlySearch cards + detail pages
Fields14 base fields14 base + room options, full amenities, review breakdown, photos, description
CostLower (fewer requests)Higher (1 extra page per hotel)
Best forPrice monitoring, market overviewCompetitive analysis, full property comparison

Input Parameters

ParameterTypeRequiredDefaultDescription
destinationstringYesCity, region, or property name
checkInstringYesCheck-in date (YYYY-MM-DD)
checkOutstringYesCheck-out date (YYYY-MM-DD)
adultsintegerNo2Number of adult guests
roomsintegerNo1Number of rooms
childrenintegerNo0Number of children (requires childrenAges)
childrenAgesarrayNo[]Ages of children (0–17), one per child
currencystringNoUSDCurrency code (USD, EUR, GBP, CZK, etc.)
languagestringNoen-usBooking.com language code
maxResultsintegerNo100Max hotels to return (1–1,000)
sortBystringNoprice_lowSort order: price_low, price_high, rating, review_score
minPriceintegerNoMin price per night filter
maxPriceintegerNoMax price per night filter
starRatingarrayNo[]Filter by star ratings, e.g. [3, 4, 5]
propertyTypearrayNo[]Filter by type: hotel, apartment, hostel, resort, villa, guesthouse
minReviewScorenumberNoMinimum review score (0–10)
enrichDatabooleanNofalseEnable detail page scraping for richer data
detailTimeoutintegerNo30Detail page load timeout in seconds (5–120)
proxyConfigobjectNoApify RESIDENTIALProxy configuration

Example Input (Fast Mode)

{
"destination": "Prague, Czech Republic",
"checkIn": "2026-03-15",
"checkOut": "2026-03-18",
"adults": 2,
"rooms": 1,
"currency": "EUR",
"maxResults": 50,
"sortBy": "price_low",
"starRating": [3, 4, 5]
}

Example Input (Enriched Mode)

{
"destination": "Barcelona, Spain",
"checkIn": "2026-04-10",
"checkOut": "2026-04-14",
"adults": 2,
"children": 1,
"childrenAges": [8],
"currency": "EUR",
"maxResults": 20,
"enrichData": true,
"propertyType": ["hotel", "resort"],
"minReviewScore": 8.0
}

Output

Each hotel record contains structured data. The data_source field indicates whether the record was enriched with detail page data.

Fast Mode Output (data_source: "search")

{
"hotel_id": "12345",
"name": "Grand Hotel Prague",
"url": "https://www.booking.com/hotel/cz/grand-prague.html",
"price": {
"per_night": 142.00,
"total": 426.00,
"currency": "EUR",
"original_price": 178.00,
"discount_percent": 20.0
},
"rating": {
"score": 8.7,
"review_count": 3421,
"review_word": "Fabulous"
},
"location": {
"address": "Kralodvorska 4, Prague 1",
"city": "Prague",
"country": "Czech Republic",
"latitude": 50.0875,
"longitude": 14.4280,
"distance_from_center": "0.3 km from center"
},
"stars": 5,
"property_type": "Hotel",
"amenities": ["Free WiFi", "Spa", "Restaurant"],
"images": ["https://cf.bstatic.com/xdata/images/hotel/max1024x768/123456.jpg"],
"availability": {
"rooms_left": 3,
"free_cancellation": true,
"no_prepayment": false,
"deal_badge": "Genius discount"
},
"check_in": "2026-03-15",
"check_out": "2026-03-18",
"scraped_at": "2026-02-06T14:30:00Z",
"data_source": "search",
"detail": null
}

Enriched Mode Output (data_source: "search+detail")

When enrichData is enabled, the detail object is populated with data from the hotel's detail page:

{
"hotel_id": "12345",
"name": "Grand Hotel Prague",
"url": "https://www.booking.com/hotel/cz/grand-prague.html",
"data_source": "search+detail",
"detail": {
"description": "Located in the heart of Prague's Old Town, Grand Hotel Prague offers...",
"all_amenities": ["Free WiFi", "Spa", "Restaurant", "Airport Shuttle", "24-hour Front Desk", "Bar", "Non-smoking Rooms", "Room Service", "Fitness Center"],
"room_options": [
{
"name": "Superior Double Room",
"max_occupancy": 2,
"beds": "1 large double bed",
"price_per_night": 142.00,
"price_total": 426.00,
"currency": "EUR",
"meal_plan": "Breakfast included",
"free_cancellation": true
}
],
"review_summary": {
"overall_score": 8.7,
"total_reviews": 3421,
"staff": 9.1,
"cleanliness": 9.0,
"comfort": 8.8,
"location": 9.5,
"facilities": 8.6,
"value_for_money": 8.2,
"free_wifi": 9.3
},
"photo_urls": [
"https://cf.bstatic.com/xdata/images/hotel/max1024x768/123456.jpg",
"https://cf.bstatic.com/xdata/images/hotel/max1024x768/123457.jpg"
]
}
}

Note: The enriched output includes all Fast Mode fields (price, rating, location, etc.) plus the detail object. If detail page extraction fails for a hotel, it falls back gracefully with data_source: "search" and detail: null.

How It Works

  1. Input validation: All parameters are validated (date ranges, price filters, star ratings) before crawling begins. Invalid inputs produce clear error messages.
  2. Search URL construction: Builds Booking.com search URL with all filters and pagination offset.
  3. Phase A — API Interception: Captures Booking.com's internal GraphQL/REST API responses for structured data extraction.
  4. Phase B — HTML Fallback: If API interception yields no results, falls back to CSS selector-based extraction from rendered HTML.
  5. Pagination: Automatically paginates through results (25 per page) until maxResults is reached or no more results exist.
  6. CAPTCHA handling: Detects Cloudflare challenges and reCAPTCHA. Backs off for 30 seconds on first detection, aborts after consecutive blocks.
  7. Error reporting: Uses Actor.fail() with descriptive messages for zero results, CAPTCHA blocks, and invalid input. Partial results still succeed via Actor.exit().

Integration Examples

Scheduled Runs (Price Monitoring)

Set up a daily schedule in Apify Console to track prices over time:

  1. Go to your Actor run → Schedules tab
  2. Create a schedule with cron expression 0 8 * * * (daily at 8:00 AM)
  3. Results accumulate in the default dataset — export via API or download

Webhook Notifications

Trigger actions when a run completes:

  1. Go to IntegrationsWebhooks
  2. Set event to ACTOR.RUN.SUCCEEDED
  3. Point to your endpoint (Slack webhook, email API, etc.)

API Access

Retrieve results programmatically after a run:

# Start a run
curl -X POST "https://api.apify.com/v2/acts/YOUR_ACTOR_ID/runs" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"destination": "Paris", "checkIn": "2026-04-01", "checkOut": "2026-04-03"}'
# Get dataset items
curl "https://api.apify.com/v2/datasets/DATASET_ID/items?format=json" \
-H "Authorization: Bearer YOUR_TOKEN"

Python Client

from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("YOUR_ACTOR_ID").call(run_input={
"destination": "London",
"checkIn": "2026-05-01",
"checkOut": "2026-05-03",
"maxResults": 200,
"currency": "GBP",
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(f"{item['name']}: {item['price']['per_night']} {item['price']['currency']}")

Proxy Recommendations

Booking.com has aggressive anti-bot protection. For best results:

  • Use Apify Proxy with RESIDENTIAL group (default configuration)
  • The scraper includes stealth measures (fingerprint spoofing, timing randomization) but residential proxies significantly improve success rates
  • Expected extraction speed: 50–100 hotels/minute with residential proxies

FAQ

How fast is the scraper? With residential proxies, expect 50–100 hotels per minute. A typical 100-hotel run completes in 1–3 minutes. Larger runs (500–1,000 hotels) take 5–15 minutes depending on pagination and page load times.

What happens if Booking.com blocks the scraper? The scraper detects CAPTCHAs and anti-bot challenges automatically. On first detection, it backs off for 30 seconds and retries. After two consecutive blocks, it aborts with a clear error message. Using residential proxies minimizes blocking.

Why are some fields null? Not all fields are available for every property. Star ratings (stars) depend on Booking.com's HTML structure which varies across page renders. GPS coordinates require API interception to succeed. The scraper returns null rather than guessing.

Can I scrape specific hotel pages (not search results)? Yes! Set enrichData: true and the scraper will visit each hotel's detail page to extract room options, full amenities, review breakdowns by category, descriptions, and photo galleries. This is slower but gives you the richest data available.

How much does it cost to run? Costs depend on proxy usage, memory allocation, and run time. Typical estimates:

ResultsApproximate Cost
100 hotels~$0.10–0.25
500 hotels~$0.50–1.25
1,000 hotels~$1.00–2.50

What currencies are supported? USD, EUR, GBP, CZK, JPY, CNY, AUD, CAD, CHF, and INR. The currency input parameter controls which currency Booking.com uses for pricing.

Can I filter by property type or review score? Yes. Use propertyType to filter by hotel, apartment, hostel, resort, villa, or guesthouse. Use minReviewScore to only return properties scoring above your threshold (0–10 scale).

Limitations

  • Maximum 1,000 results per search (Booking.com platform limit)
  • Maximum stay duration: 30 nights
  • CAPTCHA pages trigger backoff and may cause early termination after consecutive blocks
  • Results depend on Booking.com's current page structure — the dual extraction engine mitigates breakage risk
  • Star rating field may be null on some page renders