Scrape Trip.com Hotel Prices for Travel Research (2026)
Extract structured hotel pricing data from Trip.com for travel research. Nightly rates, star class, ratings, amenities, and coordinates across global cities.

Thirdwatch's Ctrip / Trip.com Hotel Scraper extracts structured hotel pricing data from Trip.com — nightly rates, star class, guest ratings, review counts, amenities, coordinates, and room types across 20+ global cities. Built for travel researchers, hospitality consultants, and academic teams studying tourism economics. Pay-per-result pricing means you pay only for the hotel records you collect, not for idle compute or flat subscriptions.
Why scrape Trip.com for travel pricing research
Trip.com (the international brand of Ctrip, China's largest OTA) reported over 590 million annual room nights booked in 2024, making it the world's third-largest hotel booking platform behind Booking.com and Expedia. For travel researchers, this volume represents a pricing surface that captures rate behaviour across Asia-Pacific, Europe, and the Middle East in ways that Western-only OTAs miss entirely.
The research job-to-be-done is concrete. A tourism economics PhD studying dynamic pricing wants nightly rate distributions across star classes in Bangkok during peak and shoulder seasons. A hospitality consulting firm benchmarking ADR (average daily rate) for a client's competitive set needs rates from the same platform guests actually book on. An airline revenue management team studying destination demand signals wants hotel price movements as a leading indicator of inbound travel volume. A government tourism board tracking hotel inflation in their capital needs weekly snapshots with star-class segmentation.
All of these reduce to the same pipeline: query Trip.com for a city and date range, capture structured price records, aggregate downstream. The scraper returns price, original_price, currency, stars, and rating per hotel — the exact fields needed for ADR analysis, discount depth measurement, and quality-tier segmentation.
How does this compare to the alternatives?
Three paths to Trip.com hotel pricing data:
| Approach | Reliability | Setup time | Maintenance |
|---|---|---|---|
| DIY Python script against Trip.com | Low — Trip.com uses client-side rendering and anti-bot defences that break raw HTTP requests | 2-4 weeks including CAPTCHA handling | Constant — Trip.com updates defences frequently |
| Generic scraping API (ScrapingBee, ScraperAPI) | Medium — handles rendering but not Trip.com-specific session logic | 1-2 days | You maintain the parsing logic |
| Thirdwatch Trip.com Scraper | Production-tested with automatic anti-bot handling | Under 30 minutes | Thirdwatch maintains the extraction layer |
Trip.com renders its hotel list entirely client-side and protects the page with session-token validation. A generic headless browser approach misses the dynamic XHR data that contains full hotel records. The Thirdwatch actor handles the session management and returns clean, structured JSON.
How to scrape Trip.com hotel prices for research in 4 steps
Step 1: How do I get an Apify API token?
Sign up at apify.com (free tier available, no credit card required). Navigate to Settings, then Integrations, and copy your API token. Store it as an environment variable:
export APIFY_TOKEN="apify_api_xxxxxxxxxxxxxxxx"Step 2: How do I configure a hotel price search?
Define the city, dates, and guest configuration. The city field accepts plain-text city names. For production reliability, include the cityId if you know it (228 for Tokyo, 73 for Singapore, 187 for Paris).
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run_input = {
"city": "Bangkok",
"checkIn": "2026-07-01",
"checkOut": "2026-07-03",
"guests": 2,
"rooms": 1,
"maxResults": 50,
}
run = client.actor("thirdwatch/ctrip-hotels-scraper").call(run_input=run_input)Step 3: How do I retrieve and filter the hotel pricing data?
Fetch the dataset and filter by star class or price range for your research segment:
dataset_items = client.dataset(run["defaultDatasetId"]).list_items().items
# Filter to 4-5 star hotels for ADR benchmarking
upscale = [h for h in dataset_items if h.get("stars", 0) >= 4]
for hotel in upscale:
print(f"{hotel['hotel_name']} | {hotel['stars']}* | "
f"{hotel['currency']} {hotel['price']} | "
f"Rating: {hotel.get('rating', 'N/A')} ({hotel.get('reviews_count', 0)} reviews)")Step 4: How do I build a multi-city seasonal comparison?
Run searches across multiple cities and date windows to build a seasonal pricing matrix:
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
cities = [
{"city": "Bangkok", "cityId": 95},
{"city": "Tokyo", "cityId": 228},
{"city": "Singapore", "cityId": 73},
]
seasons = [
("2026-07-01", "2026-07-03"), # Summer peak
("2026-10-15", "2026-10-17"), # Shoulder
("2026-12-20", "2026-12-22"), # Holiday peak
]
all_results = []
for city_cfg in cities:
for check_in, check_out in seasons:
run_input = {
"city": city_cfg["city"],
"cityId": city_cfg["cityId"],
"checkIn": check_in,
"checkOut": check_out,
"guests": 2,
"rooms": 1,
"maxResults": 30,
}
run = client.actor("thirdwatch/ctrip-hotels-scraper").call(run_input=run_input)
items = client.dataset(run["defaultDatasetId"]).list_items().items
all_results.extend(items)Step 5: How do I calculate ADR by star class and city?
Aggregate the collected data into research-grade metrics:
from collections import defaultdict
adr_by_segment = defaultdict(list)
for h in all_results:
key = (h.get("search_city", ""), h.get("stars", 0), h.get("checkin_date", ""))
if h.get("price"):
adr_by_segment[key].append(h["price"])
for (city, stars, checkin), prices in sorted(adr_by_segment.items()):
avg = sum(prices) / len(prices)
print(f"{city} | {stars}* | {checkin} | ADR: ${avg:.0f} | n={len(prices)}")Sample output
Each hotel record contains the fields needed for pricing research — rate, discount depth, quality tier, and location:
[
{
"hotel_name": "Mandarin Oriental Bangkok",
"hotel_id": 548219,
"url": "https://www.trip.com/hotels/detail/?hotelId=548219",
"price": 312,
"currency": "USD",
"original_price": 389,
"rating": 4.8,
"rating_label": "Excellent",
"reviews_count": 4210,
"stars": 5,
"address": "48 Oriental Avenue, Bangrak",
"city": "Bangkok",
"district": "Riverside",
"latitude": 13.7234,
"longitude": 100.5167,
"image_url": "https://ak-d.tripcdn.com/images/hotel/548219/exterior.jpg",
"amenities": ["Pool", "Spa", "Fitness Center", "Restaurant", "Free WiFi"],
"room_types": ["Deluxe Room", "Premier Room", "Suite"],
"tags": ["Member Price", "Free Cancellation"],
"distance_from_center": "3.2 km from city center",
"checkin_date": "2026-07-01",
"checkout_date": "2026-07-03",
"search_city": "Bangkok",
"source": "api"
},
{
"hotel_name": "Ibis Bangkok Riverside",
"hotel_id": 1084532,
"url": "https://www.trip.com/hotels/detail/?hotelId=1084532",
"price": 42,
"currency": "USD",
"original_price": null,
"rating": 4.1,
"rating_label": "Very Good",
"reviews_count": 1890,
"stars": 3,
"address": "27 Charoen Nakhon Road",
"city": "Bangkok",
"district": "Thonburi",
"latitude": 13.7121,
"longitude": 100.5012,
"image_url": "https://ak-d.tripcdn.com/images/hotel/1084532/exterior.jpg",
"amenities": ["Pool", "Restaurant", "Free WiFi"],
"room_types": ["Standard Room"],
"tags": [],
"distance_from_center": "4.8 km from city center",
"checkin_date": "2026-07-01",
"checkout_date": "2026-07-03",
"search_city": "Bangkok",
"source": "api"
}
]Key fields for pricing research: price and original_price together reveal discount depth. stars enables tier-segmented ADR. checkin_date and checkout_date are echoed back so downstream aggregation can segment by season without re-joining input metadata.
Common pitfalls
Date format matters. Trip.com requires YYYY-MM-DD for checkIn and checkOut. Passing MM/DD/YYYY or DD-MM-YYYY will return zero results without an error message. Always validate date strings before submitting.
City name ambiguity. "San Jose" could resolve to San Jose, California or San Jose, Costa Rica. For research pipelines that run unattended, always supply the cityId parameter. The actor auto-resolves common city names, but ambiguous inputs may return unexpected results. Trip.com's city ID for Tokyo is 228, Singapore is 73, Paris is 187.
Rate currency assumptions. Trip.com defaults to USD, but rates may include or exclude local taxes depending on the property. For cross-city ADR comparisons, confirm whether your target cities show rates inclusive or exclusive of VAT/service charges. The currency field reflects the display currency, not the billing currency.
Scroll-based pagination ceiling. Trip.com loads additional hotels via scroll-triggered XHR. The practical ceiling is 50-100 hotels per search. For research requiring exhaustive coverage of a city, run multiple searches with different date ranges or filter segments and deduplicate by hotel_id.
The Thirdwatch actor handles session management, anti-bot defences, and XHR capture automatically. You focus on the research design; the data pipeline stays stable.
Related use cases
- Build a hotel price comparison database with Ctrip data — aggregate Trip.com pricing into a queryable database for competitive analysis.
- Monitor Ctrip hotel availability across cities — track inventory and rate changes over time for revenue management.
- Track Trip.com hotel ratings for hospitality intel — analyse guest sentiment and review trends across properties.
- Scrape Booking.com hotels for hospitality research
- Scrape TripAdvisor reviews for travel insights
- The complete guide to scraping travel data
- More scraping guides on the Thirdwatch blog.
Frequently asked questions
What hotel data fields does the Trip.com scraper return?
Each record includes hotel_name, price, currency, original_price, rating, rating_label, reviews_count, stars, address, city, district, latitude, longitude, amenities, room_types, tags, and distance_from_center. Currency defaults to USD. Coordinates enable geographic clustering for spatial research.
How many cities does the Trip.com scraper support?
The actor supports any city on Trip.com including Tokyo, Bangkok, Paris, Singapore, Dubai, London, New York, Seoul, Shanghai, Barcelona, and many more. Pass the city name directly or supply a Trip.com cityId for faster, more reliable resolution on ambiguous names.
Related
100 free credits, no credit card.
About 30 real searches. Add the MCP to Claude or Cursor in two minutes.