Trip.com & Ctrip Hotel Reviews Scraper avatar

Trip.com & Ctrip Hotel Reviews Scraper

Pricing

from $1.40 / 1,000 review delivereds

Go to Apify Store
Trip.com & Ctrip Hotel Reviews Scraper

Trip.com & Ctrip Hotel Reviews Scraper

Scrape Trip.com and Ctrip (携程) hotel reviews without login: text, English translation, sub-ratings, date, traveler type, room, photos, videos, hotel replies, hotelId and the hotel's aggregate score on every row. Sort, date, rating and language filters. Errors free.

Pricing

from $1.40 / 1,000 review delivereds

Rating

0.0

(0)

Developer

Scrapewise Data

Scrapewise Data

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

3

Monthly active users

5 hours ago

Last modified

Share

Trip.com & Ctrip Hotel Reviews Scraper: every review, sub-ratings and the hotel summary

Scrape hotel reviews from Trip.com and Ctrip (携程) without an account or cookies: review text, overall rating and the four sub-ratings, date, stay month, traveler type, room, reviewer country, guest photos and hotel replies, plus one summary row per hotel with the rating breakdown, review tags and Trip.com's AI review summary.

Built for hotel and travel analytics, reputation monitoring, competitor benchmarking across Asia, and review datasets for sentiment analysis and LLMs. Trip.com and Ctrip share hotel ids, so a Ctrip hotel gives you its Chinese guest reviews through the same run.

At a glance

  • Fee per run start: None
  • Trip.com and Ctrip links: Yes, plus bare hotel ids
  • hotelId on every row, so reviews join to the right property without parsing URLs
  • Hotel aggregate score on every review (aggregateReviewScore, description, count and the four sub-scores), plus a full summary row per hotel
  • Translations: Trip.com's own translation when it has one, and with translateTo every foreign-language review gets one
  • Review insights (optional, free): sentiment on every review and one summary row per hotel with complaint and praise themes, month by month rating and reply speed, computed in the run with no AI model
  • Never placeholder content: a response that looks like a template (same text on every review) is retried and never delivered or charged

What it fixes

  • Real reviews or a clear error, never filler. If Trip.com answers with the same template text for every review, the Actor retries; if it keeps happening you get a free TEMPLATE_CONTENT row instead of a dataset of identical rows.
  • "No reviews" is double-checked. Trip.com sometimes answers "0 reviews" for a hotel that has thousands (about 1 request in 15 in our tests). The Actor asks again before reporting NO_REVIEWS, and re-asks for empty pages before the known end.
  • The same hotel pasted twice is read once. A hotel in both startUrls and hotelUrl, or as a link and an id, gives one summary row and no duplicate charges.
  • Your limit is the limit. maxReviews from another actor's input is honoured, not replaced by this form's default.
  • Aggregated data and hotel id come on each review, and a hotel summary row adds review tags, traveler types, languages and Trip.com's AI summary.
  • Insights without paying for AI. Turn on reviewInsights and every review gets sentiment and sentimentScore, and each hotel gets one free insights row: what guests praise and complain about most (repeated phrases with two short quotes each), positive and negative share month by month, and how often and how fast the hotel replies. Computed in the run from a keyword lexicon and the 10-point rating: instant, repeatable, no extra charge.

Switching from another Trip.com reviews actor? Your existing input works

Paste the input you already use; these field names are read as they are:

You may already sendRead as
hotelUrl, startUrls (texts or { "url": ... } objects), startUrl, urls, hotelIdshotels to read
maxReviews, maxItemsmaxReviewsPerHotel
sortBy: mostRelevant, mostRecent, ratingHighToLow, ratingLowToHighsame values
cutoffDatefromDate
includeInsights, aiInsights, sentimentAnalysisreviewInsights
{
"hotelUrl": "https://www.trip.com/hotels/shanghai-hotel-detail-346403/grand-hyatt-shanghai/",
"maxReviews": 100,
"sortBy": "mostRecent",
"cutoffDate": "2025-01-01"
}

Each review then carries the fields you may already map: hotelId, rating, ratingLabel, text, translatedText, language, reviewDate, stayDate, travelType, roomName, helpfulCount, photos, videos, hotelResponses, recommend and the aggregateReview* fields.

One real row

From a test run on 2026-09-27 (Marina Bay Sands, Singapore):

{
"type": "review",
"hotelId": 687592,
"hotelName": "Marina Bay Sands",
"hotelUrl": "https://www.trip.com/hotels/singapore-hotel-detail-687592/marina-bay-sands/",
"reviewId": 2109823308,
"rating": 10,
"ratingScale": 10,
"ratingLabel": "Outstanding",
"ratingLocation": 10,
"ratingAmenities": 10,
"ratingService": 10,
"ratingCleanliness": 10,
"text": "Loved everything! The cleanliness, the facilities, the complimentaries were all top notched and it's expected. The Infinity pool was not crowded. Staff were all friendly and accomodating.",
"language": "en",
"reviewDate": "2026-09-20",
"reviewDateTime": "2026-09-20 17:38:55",
"stayDate": "2026-09",
"travelType": "Solo traveler",
"roomName": "Sands Premier Double Queen",
"reviewerName": "Guest User",
"reviewerCountry": "Singapore",
"helpfulCount": 0,
"photos": ["https://ak-d.tripcdn.com/images/0230b224x9aqtiwjn3BFC_W_1280_853_R5_Q70.jpg?proc=autoorient"],
"photoCount": 6,
"videoCount": 0,
"hotelResponses": [],
"languageName": "English",
"translatedText": null,
"translatedLanguage": null,
"translationSource": null,
"recommend": true,
"videos": [],
"aggregateReviewScore": 9.7,
"aggregateReviewDescription": "Amazing",
"aggregateReviewCount": 1807,
"aggregateReviewSubScore": [{"name": "Cleanliness", "score": 9.8}, {"name": "Amenities", "score": 9.6}, {"name": "Location", "score": 9.8}, {"name": "Service", "score": 9.6}],
"scrapedAt": "2026-09-27T19:40:12Z",
"errorCode": null,
"error": null
}

And the hotel summary row (type: "hotel"): rating 9.7 of 10 ("Amazing"), reviewCount 1807, location 9.8, amenities 9.6, service 9.6, cleanliness 9.8, 7 review tags ("Clean pool": 461), traveler types, languages and 4 AI summary topics such as "Service Quality".

Input

FieldTypeWhat it does
hotelUrls (also startUrls, hotelUrl, startUrl, urls, hotelIds)listTrip.com hotel pages from any country site, Ctrip pages (hotels.ctrip.com/hotels/1286148.html) or numeric hotel ids. Texts or { "url": ... } objects. The same hotel twice is read once.
maxReviewsPerHotel (also maxReviews, maxItems)integer, default 20Reviews per hotel. 0 = every review.
onlyNewReviews (also onlyNew)boolean, default falseFor schedules: only reviews posted since the last run, remembered per hotel in your account. See below.
sortBymostRelevant, mostRecent, ratingHighToLow, ratingLowToHighThe hotel page's own orders.
fromDate (also cutoffDate)YYYY-MM-DD or daysOnly reviews posted on or after the date. Without a sort, reads newest first and stops early.
minRating, maxRating1 to 10Trip.com's 10-point scale. maxRating: 6 collects complaints.
reviewFilterall, positive, negative, withPhotosTrip.com's own review type filter.
languagetextEnglish, Chinese, Japanese, Korean... or a code such as zh.
translateTotext, such as enFill translatedText for every review in another language: Trip.com's own translation when it exists, otherwise a free machine translation (translationSource says which). Same price.
includeHotelSummaryboolean, default trueOne type: "hotel" row per hotel, charged as one item.
reviewInsightsboolean, default falsesentiment and sentimentScore on every review, and one free type: "insights" row per hotel. See below.
proxyConfigurationproxyApify Proxy by default.

Schedule it daily: only new reviews

Turn on onlyNewReviews, save your hotels as a Task and attach a Schedule: every run delivers, and charges, only the reviews posted since the previous run. Connect Slack, e-mail or Google Sheets and new guest feedback for your hotel, or your competitors', lands where your team reads it.

{ "hotelUrls": ["https://www.trip.com/hotels/singapore-hotel-detail-687592/marina-bay-sands/"],
"maxReviewsPerHotel": 100, "onlyNewReviews": true }
  • The memory lives in a Key-Value Store in your own account (tripcom-hotel-reviews-only-new), one record per hotel and filter set (language, review type, ratings, date). Delete it to start over.
  • The first run delivers up to maxReviewsPerHotel and marks the pages it read as seen; later runs read newest first and stop at the first page with nothing new.
  • The hotel summary row comes on the first run and on runs that found new reviews. A day with nothing new ends with a status message and costs nothing.

Review insights: sentiment and themes, no AI needed

With reviewInsights on, each review gets sentiment (positive, neutral, negative) and sentimentScore (-1 to 1); the 10-point rating is the strongest signal and the words adjust it. After each hotel's reviews comes one insights row with reviewsAnalyzed, periodFrom, periodTo, averageRating, ratingDistribution, sentimentDistribution, positiveShare, negativeShare, monthly (reviews, average rating and positive/negative share per month), complaintThemes and praiseThemes (phrase, how many reviews mention it, share and two short quotes with the review id) and replies (reply rate and hours to reply of the hotel on these reviews).

The lexicon covers English, Chinese, Japanese, Portuguese, Spanish, French, German, Italian and Dutch. Reviews come in many languages, so set translateTo: "en" to get themes in one language. Use reviewFilter: "negative" or maxRating: 6 to focus the themes on complaints. The insights row is free; reviews cost the same.

{ "hotelUrls": ["https://www.trip.com/hotels/singapore-hotel-detail-687592/marina-bay-sands/"],
"maxReviewsPerHotel": 300, "sortBy": "mostRecent", "reviewInsights": true }

Insights row from a run like that, shortened (collected on 2026-10-09):

{
"type": "insights",
"hotelName": "Marina Bay Sands",
"reviewsAnalyzed": 300,
"averageRating": 9.84,
"sentimentDistribution": {"positive": 295, "neutral": 4, "negative": 1},
"monthly": [{"month": "2026-10", "reviews": 13, "averageRating": 9.77, "positiveShare": 1.0, "negativeShare": 0.0}],
"praiseThemes": [
{"theme": "infinity pool", "reviews": 38, "share": 0.129,
"examples": [{"reviewId": 2122244600, "rating": 10, "excerpt": "The infinity pool is incredible, and the views are amazing both during the day and at night."}]}
],
"complaintThemes": [],
"replies": {"repliedReviews": 1, "replyRate": 0.003, "averageHoursToReply": 246.4}
}

Price

US$ 2.00 per 1,000 rows on the Free plan (a review or a hotel summary), no start fee. Rows with an errorCode and insights rows are free; reviews outside your date, rating or language filters are skipped and not charged; a review is never charged twice in a run.

Errors you may see

errorCodeMeaningCharged
INVALID_URLnot a Trip.com or Ctrip hotel link or id (hotel search/list pages are not supported: paste each hotel's page)no
TEMPLATE_CONTENTTrip.com kept answering with placeholder text instead of real reviews; nothing was delivered for that partno
NO_REVIEWSwrong hotel id, or a hotel without reviewsno
BLOCKEDTrip.com did not answer after five attempts; run againno
NOT_REACHEDthe run timeout arrived before this hotelno
INVALID_INPUTfromDate or a rating is not validno
ITEM_UNREADABLE, UNEXPECTEDa review came in a shape we did not expect; the rest of the run goes onno

Good to know

  • Every review, not a sample. Trip.com serves 100 reviews per request and pages to the end: 1,596 of 1,596 in our test hotel, 4,000 in a row from a Ctrip hotel with 13,047.
  • "Most recent" is Trip.com's order, and it is approximate. Trip.com mixes a few older reviews into the newest pages. fromDate filters every review by its own date, so nothing older than your date is delivered, and the run stops only when a whole page is older.
  • Reviewer data is the display name and country only. Never a user id, avatar, profile link or review history.
  • Translations: Trip.com translates roughly a third of foreign-language reviews itself. translateTo fills the rest with a free machine translation; if that service is unavailable the review is still delivered, just without the extra translation.
  • Photo links point to Trip.com's CDN and work without login.
  • Something broke? Open an issue on the Actor page.

FAQ

Do I need a Trip.com or Ctrip account? No. Nothing to log in to, no cookies to paste.

Can I get Chinese reviews from Ctrip? Yes. Paste the Ctrip hotel link or its id; Chinese reviews come through Trip.com, which shares Ctrip's hotel ids. Use language: "zh" to keep only those.

How fast is it? 4,000 reviews took 86 seconds in a test. Three hotels are read in parallel.

Can I use it from n8n, Make, Zapier or an AI agent? Yes, through the Apify app or the Apify MCP server. Error rows are free, so an agent can explore cheaply.

Can I monitor a hotel every day without paying twice for the same review? Yes: turn on onlyNewReviews in a scheduled Task. Each run delivers only reviews posted since the last one.

What if a run is cut by its timeout? The Actor stops 45 seconds before the limit and ends successfully with what it delivered, telling you in the status message how to get the rest.

Changelog

  • 0.1 (2026-09-27): first version. Trip.com and Ctrip links and ids, sort, date, rating, language and review type filters, hotel summary row, free error rows.
  • 2026-10-04: onlyNewReviews for scheduled runs: only reviews posted since the last run, remembered per hotel in a Key-Value Store in your account; quiet days cost nothing.
  • 2026-10-08: hotelId and the hotel aggregate score on every review; translatedText, recommend and video links; translateTo for every foreign-language review; placeholder responses retried and never delivered (TEMPLATE_CONTENT); "0 reviews" and empty pages double-checked; the same hotel pasted twice is read once; maxReviews from other actors' inputs honoured.
  • 2026-10-09: reviewInsights (off by default): sentiment on every review and a free insights row per hotel with complaint and praise themes, month by month rating and reply speed, computed in the run without AI. Also read from includeInsights, aiInsights and sentimentAnalysis. Runs without it deliver the same rows as before.