Tripadvisor Review Scraper : Photo & Visual Content Filters
Under maintenancePricing
from $2.99 / 1,000 results
Tripadvisor Review Scraper : Photo & Visual Content Filters
Under maintenanceGet clean Tripadvisor review data for research. This actor collects comments, star ratings, reviewer details, timestamps, and listing info. Ideal for hospitality insights, market evaluation, and customer experience analysis.
Pricing
from $2.99 / 1,000 results
Rating
0.0
(0)
Developer
SimpleAPI
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
0
Monthly active users
6 days ago
Last modified
Categories
Share
Tripadvisor Review Scraper — Ratings, Photos and Reviewer Data
The Tripadvisor Review Scraper extracts hotel reviews from TripAdvisor Hotel_Review pages as structured JSON — review text, star ratings and subratings, reviewer profiles, owner/management responses, and review photos. This variant adds a photo/visual-content layer: maxPhotosPerReview controls how many photos come back per review, hasPhotos and minPhotoCount keep only photo-rich reviews, and a running pctReviewsWithPhotos stat scores each property's visual coverage. Hospitality marketers, reputation-management agencies, and NLP/sentiment pipelines use it to separate photo-backed guest feedback from text-only reviews. No TripAdvisor account or API key is required to run it.
🏨 What is the Tripadvisor Review Scraper : Photo & Visual Content Filters?
It's an Apify Actor that scrapes guest reviews from TripAdvisor Hotel_Review pages and returns them as clean, typed JSON rows — one row per review. You give it a direct URL, a hotel name, or a keyword; it resolves the hotel, paginates through its reviews automatically, and pushes each review to the dataset as soon as it's collected. No TripAdvisor login, account, or API key is needed — the scraper authenticates only against TripAdvisor's public pages, behind Apify Proxy.
Key features:
- 🔗 Three ways to target a hotel — a direct
Hotel_ReviewURL, a hotel name (auto-resolved via Google Search), or a free-text keyword - 📝 Core review fields — review text, title, star rating, per-category subratings, published date, helpful-vote count, trip type and travel date
- 👤 Optional reviewer profile — name, username, home location, avatar, total contribution count, profile link
- 📸 Photo-aware collection — up to 20 photos per review, plus derived
photoCount,hasPhotos, and property-levelpctReviewsWithPhotoscoverage - 🎯 Built-in filters — sort order, review language, star-rating bucket, and two photo-richness filters
- 💾 Real-time, exportable output — rows land in the dataset live during the run and export to JSON, CSV, Excel, or XML from the Apify platform
📦 What data can I extract with the Tripadvisor Review Scraper?
Every review is returned as one JSON object covering the review text and rating, the reviewer, the property, and — the focus of this variant — the review's photos and visual-coverage signals.
| Field | Example value | Use case |
|---|---|---|
id | "1040504451" | Unique review ID, dedupe across runs |
url | "https://www.tripadvisor.com/ShowUserReviews-g60763-d208453-r1040504451-..." | Link back to the live review |
title | "Perfect Holidays at Hilton Times Square !!!!!" | Review headline for display/search |
lang | "en" | Filter or route by review language |
locationId | "208453" | Join reviews to the same property |
publishedDate | "2025-11-27" | Trend and recency analysis |
publishedPlatform | "OTHER" | Segment by web vs. mobile app source |
rating | 5 | Overall star score (1–5) |
helpfulVotes | 0 | Signal of review usefulness to other guests |
text | "We were for 2 weeks holidays in New York!!..." | Sentiment/NLP input |
roomTip | null | Guest-submitted room tip, when present |
travelDate | "2025-11" | Month of stay |
tripType | "FAMILY" | Segment reviews by traveler type |
user | { "userId": "...", "name": "Dimitris T", ... } or null | Reviewer identity (see below) |
ownerResponse | { "text": "...", "responder": "..." } or null | Property's reply to the review |
subratings | [{ "name": "Value", "value": 5 }] | Per-category scoring (Value, Rooms, Location, etc.) |
photos | [{ "id": "...", "url": "...", "caption": "" }] | Review-attached photos (see below) |
photoCount | 1 | Derived count of photos on this review |
hasPhotos | true | Quick boolean filter/flag for photo-bearing reviews |
pctReviewsWithPhotos | 42.9 | Running visual-coverage stat for this property (see below) |
propertyImage | "https://dynamic-media-cdn.tripadvisor.com/media/photo-o/hotel-hero.jpg" | Property hero image, surfaced on every row |
placeInfo | { "name": "Hilton New York Times Square", ... } | Property metadata (see below) |
scrapedAt | "2026-08-04T10:15:03Z" | Collection timestamp for this row |
📸 Photo and visual-content data
photos is an array of { id, url, caption, albumId } — direct image URLs only, never downloaded files. photoCount is a zero-extra-request count of that array, and hasPhotos is the boolean derived from it. pctReviewsWithPhotos is a running stat, recomputed after every review and written to both the top-level row and placeInfo.pctReviewsWithPhotos: the percentage of this property's reviews evaluated so far in this run (after the rating filter, before the photo filter) that carry at least one photo. It reflects this run's own sample of a property, not TripAdvisor's full historical review count — use it to compare visual engagement across properties you scrape in the same batch, not as an absolute site-wide figure.
🏨 Reviewer and property targeting data
user carries userId, name, username, userLocation, avatar, link, and contributions.totalContributions when scrapeReviewerInfo is on; contributions.helpfulVotes is always null because TripAdvisor's GraphQL surface has no source for a per-user helpful-votes total (returning an honest null rather than a fake 0). placeInfo carries the property's own name, rating, numberOfReviews, locationString, latitude/longitude, webUrl, website, address, a structured addressObj, and a ratingHistogram (count1–count5). Use subratings, rating, and placeInfo.locationString/coordinates together to segment or map review quality by location.
🧭 How does the Tripadvisor Review Scraper differ from the official TripAdvisor API?
TripAdvisor publishes an official Content API, but its Location Reviews endpoint returns up to 5 of the most recent reviews per location — as documented on its own reference page (observed 2026-08-04, tripadvisor-content-api.readme.io/reference/getlocationreviews) — which makes it unusable for any bulk review analysis, reputation monitoring, or historical dataset work.
| Feature | TripAdvisor Content API | This Actor |
|---|---|---|
| Reviews per location | Up to 5 most recent (observed 2026-08-04) | Up to maxComments (max 10,000), paginated automatically |
| Photos per location/review | Up to 5 photos per location (observed 2026-08-04) | 1–20 photos per review, caller-set via maxPhotosPerReview |
| Photo/rating filtering | Not documented | Built-in hasPhotos, minPhotoCount, reviewRatings filters |
| Reviewer profile data | Not documented in the reference | Optional full reviewer profile via scrapeReviewerInfo |
| Access requirements | Sign-up for a paid API plan, pay-as-you-go billing (observed 2026-08-04) | Apify account only — no TripAdvisor account or API key |
| Rate limits | Up to 50 queries/second plus a daily call budget you configure and pay for (observed 2026-08-04) | Bound by Apify proxy/session throughput; no published QPS figure |
| Output format | JSON via REST endpoint | JSON via Apify dataset; exports to CSV, Excel, XML |
Why is the official API capped at 5 reviews per location?
TripAdvisor's Content API is built for showing a small "recent reviews" widget on a partner site, not for bulk extraction — so its Location Reviews endpoint hard-caps at 5 reviews, however many a property actually has. That's unusable for reputation monitoring across a hotel's full history, or for building a photo-coverage dataset like pctReviewsWithPhotos, which needs a real sample of reviews to be meaningful. This Actor reads the same public review pages a browser would, paginates through them itself, and applies rating/photo filtering after collection — closing that gap without touching the Content API at all.
Use the official Content API when you only need a handful of the newest reviews to display alongside a listing. Use this Actor when you need deep, filterable, photo-aware review history at scale.
💡 How to use data extracted from TripAdvisor?
🏨 Hospitality marketing and reputation teams
Pull a property's reviews with hasPhotos: true to build a real, guest-submitted photo gallery for social proof — filter further with reviewRatings: "POSITIVE" to surface only 4–5-star photo-backed reviews. The photos[] URLs and text fields drop straight into a marketing CMS or review-widget feed; ownerResponse shows whether the property is already engaging with guests, which is useful context before publishing.
📋 Agencies monitoring properties on behalf of clients
Run the same startUrls list on a schedule, filtering by sortOrder: "newest" and a recent travelDate, to catch new reviews as they land. pctReviewsWithPhotos and rating trends across runs let an agency show a client whether visual engagement and sentiment are moving up or down without re-reading every review.
📊 Market research and competitive intelligence
Scrape several competing hotels' startUrls in one run and compare placeInfo.rating, ratingHistogram, and pctReviewsWithPhotos side by side to see which properties get more photo-rich, higher-scoring feedback in the same market or neighborhood.
🤖 AI agents and automated pipelines
Feed text, rating, and subratings into a sentiment or summarization pipeline, using hasPhotos/photoCount as a confidence signal that a review reflects a genuine, documented stay. Because output is called via a standard Apify Actor run, it drops into any agent framework that can make an HTTP call and read JSON.
🔼 Input sample
startUrls is the only required field. Everything else has a working default, so the shortest valid input is a single URL.
| Parameter | Required | Type | Description | Example value |
|---|---|---|---|---|
startUrls | Yes | array | Direct TripAdvisor Hotel_Review URLs, hotel names (resolved via Google Search), or free-text keywords — mix and match in one run | ["https://www.tripadvisor.com/Hotel_Review-g60763-d208453-Reviews-Hilton_New_York_Times_Square-New_York_City_New_York.html"] |
maxComments | No | integer | Reviews to extract per URL, before any photo filter is applied. min 1, max 10000, default 10 | 50 |
sortOrder | No | string | Fetch order. Enum: newest (default), oldest, relevant, rating. relevant currently returns the same order as newest — TripAdvisor exposes no distinct relevance ranking here | "newest" |
reviewsLanguages | No | string | Review language. Enum: ALL_REVIEW_LANGUAGES or one of 29 named languages (English, Spanish, French, ...). default "English" | "English" |
reviewRatings | No | string | Star-rating filter. Enum: ALL_REVIEW_RATINGS (default), POSITIVE (4–5★), NEGATIVE (1–2★), AVERAGE (3★), or a single "5"–"1" | "POSITIVE" |
scrapeReviewerInfo | No | boolean | Include full reviewer profile (name, username, location, avatar, contributions, profile link). default true; when false, user is null | true |
maxPhotosPerReview | No | integer | Photos to request per review. min 1, max 20, default 10 | 15 |
hasPhotos | No | boolean | Keep only reviews with ≥1 photo. default false | true |
minPhotoCount | No | integer | Keep only reviews with at least this many photos. min 0, max 20, default 0 (no minimum) | 2 |
proxyConfiguration | No | object | Apify proxy config. Defaults to the RESIDENTIAL group when left blank | { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] } |
{"startUrls": ["https://www.tripadvisor.com/Hotel_Review-g60763-d208453-Reviews-Hilton_New_York_Times_Square-New_York_City_New_York.html"],"maxComments": 50,"sortOrder": "newest","reviewsLanguages": "English","reviewRatings": "POSITIVE","scrapeReviewerInfo": true,"maxPhotosPerReview": 15,"hasPhotos": true,"minPhotoCount": 2,"proxyConfiguration": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"]}}
Common pitfall: the input schema only accepts TripAdvisor Hotel_Review URLs — restaurant and attraction review URLs are silently skipped with a log warning, not an error. And setting maxComments to 0 doesn't mean "unlimited": the source treats a falsy value (0, empty) as 100, not the schema's own default of 10, so pass a real positive integer if you want a specific count.
🔽 Output sample
Output is typed, normalized JSON, one object per review, pushed to the dataset the moment it's collected — export it as JSON, CSV, Excel, or XML from the Apify platform's Output tab.
{"id": "1040504451","url": "https://www.tripadvisor.com/ShowUserReviews-g60763-d208453-r1040504451-Hilton_New_York_Times_Square-New_York_City_New_York.html","title": "Perfect Holidays at Hilton Times Square !!!!!","lang": "en","locationId": "208453","publishedDate": "2025-11-27","publishedPlatform": "OTHER","rating": 5,"helpfulVotes": 0,"text": "We were for 2 weeks holidays in New York!! Hilton Times Square was the perfect choice...","roomTip": null,"travelDate": "2025-11","tripType": "FAMILY","user": {"userId": "4381D233A5C57ADAF67693B272BEFE70","name": "Dimitris T","contributions": { "totalContributions": 2, "helpfulVotes": null },"username": "margaretmN8866NJ","userLocation": "Thessaloniki, Greece","avatar": "https://dynamic-media-cdn.tripadvisor.com/media/photo-o/1a/f6/de/5a/default-avatar-2020-36.jpg?w=100&h=100&s=1","link": "www.tripadvisor.com/Profile/margaretmN8866NJ"},"ownerResponse": null,"subratings": [{ "name": "Value", "value": 5 },{ "name": "Location", "value": 5 }],"photos": [{ "id": "123456789", "url": "https://dynamic-media-cdn.tripadvisor.com/media/photo-o/...", "caption": "", "albumId": "" }],"photoCount": 1,"hasPhotos": true,"pctReviewsWithPhotos": 42.9,"propertyImage": "https://dynamic-media-cdn.tripadvisor.com/media/photo-o/hotel-hero.jpg","placeInfo": {"id": "208453","name": "Hilton New York Times Square","rating": 4.3,"numberOfReviews": 7879,"locationString": "New York City, New York","latitude": 40.75665,"longitude": -73.988815,"webUrl": "https://www.tripadvisor.com/Hotel_Review-g60763-d208453-...","website": "https://www.hilton.com/en/hotels/nyctshh-hilton-times-square/","address": "234 West 42nd Street, New York City, NY 10036","addressObj": { "street1": "234 West 42nd Street", "street2": "", "city": "New York City", "state": "NY", "country": "United States", "postalcode": "10036" },"ratingHistogram": { "count1": 267, "count2": 290, "count3": 704, "count4": 2568, "count5": 5064 },"image": "https://dynamic-media-cdn.tripadvisor.com/media/photo-o/hotel-hero.jpg","pctReviewsWithPhotos": 42.9},"scrapedAt": "2026-08-04T10:15:03Z"}
Every pushed row is charged once under the row_result event — reviews skipped by the reviewRatings, hasPhotos, or minPhotoCount filters are never pushed to the dataset, so you are not charged for rows you asked the Actor to filter out.
🎯 How do you filter and target specific reviews?
Direct URL vs. hotel name vs. keyword — startUrls accepts all three. Direct Hotel_Review URLs are resolved instantly and always the most accurate; a hotel name is resolved to a URL via a Google Search lookup (TripAdvisor's own search sits behind heavier anti-bot protection); a bare keyword goes through the same lookup but may match a different, similarly-named property. Use direct URLs whenever you already have them.
Language and sort scope — reviewsLanguages narrows the fetched reviews to one locale (or all of them); sortOrder controls fetch order (newest, oldest, relevant, rating), though relevant is not a distinct order on TripAdvisor's current data source and silently matches newest.
Quality thresholds — reviewRatings filters by star bucket (single star, or the POSITIVE/NEGATIVE/AVERAGE groups); hasPhotos and minPhotoCount filter on visual richness, applied after fetch against the photos[] array each review already carries, at no extra request cost.
Volume controls — maxComments caps reviews per URL (up to 10,000); TripAdvisor's own GraphQL endpoint returns 10 reviews per page regardless of input, so the Actor auto-paginates behind the scenes. Because rating/photo filters are applied after fetching, an aggressive filter combined with a high maxComments can mean reading through more underlying pages than the number of rows you actually get back — the run still stops at the property's total review count or a 10,000-review safety ceiling, whichever comes first.
{ "startUrls": ["https://www.tripadvisor.com/Hotel_Review-g60763-d208453-Reviews-Hilton_New_York_Times_Square-New_York_City_New_York.html"], "maxComments": 500, "hasPhotos": true, "minPhotoCount": 3 }
{ "startUrls": ["Marriott Marquis San Diego Marina"], "reviewRatings": "NEGATIVE", "reviewsLanguages": "English", "maxComments": 100 }
{ "startUrls": ["luxury hotel Paris"], "sortOrder": "rating", "maxPhotosPerReview": 20, "scrapeReviewerInfo": false }
▶️ Want to try other SimpleAPI scrapers?
| Scraper name | What it extracts |
|---|---|
| TikTok Shop Data Scraper: Reviews & Sentiment Analysis | Product reviews and sentiment signals from TikTok Shop listings |
| Facebook Events Scraper: Multi-City Search & Ticket Price | Event listings, dates, and ticket pricing across multiple cities |
| Facebook Group Posts And Details & Contact Leads Scraper | Group posts, member activity, and extracted contact leads |
| LinkedIn Search Jobs Scraper With Advanced Search Filters | Job postings with salary, seniority, and company filters |
⚙️ How to extract TripAdvisor review data programmatically
This Actor runs like any Apify Actor: one API call starts the run, structured JSON comes back from the dataset — no separate TripAdvisor credentials involved.
Python example
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run_input = {"startUrls": ["https://www.tripadvisor.com/Hotel_Review-g60763-d208453-Reviews-Hilton_New_York_Times_Square-New_York_City_New_York.html"],"maxComments": 100,"reviewRatings": "POSITIVE","hasPhotos": True,"minPhotoCount": 2,}run = client.actor("<YOUR_USERNAME>/tripadvisor-review-scraper-photo-and-visual-content-filters").call(run_input=run_input)for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["rating"], item["photoCount"], item["text"][:80])
Export to spreadsheets or CRM
Export the dataset as CSV directly from the Apify Console's Output tab. Map rating, text, publishedDate, user.name, and photoCount to columns in a spreadsheet, or into a CRM/reputation tool's review-import fields — placeInfo.name and locationId give you the join key back to the property record.
⚖️ Is it legal to scrape TripAdvisor reviews?
Yes — TripAdvisor review pages are public; anyone with a browser can read them without logging in, and this Actor collects the same data a browser would render. That said, review rows returned with scrapeReviewerInfo enabled include personal data — reviewer name, username, home location, and avatar/profile links — so GDPR and CCPA govern how you may store, process, and reuse it once collected, not whether the page itself may be viewed. Disable scrapeReviewerInfo if you only need review text and ratings and want to avoid handling personal data at all. Consult legal counsel for commercial applications involving bulk storage of personal data.
❓ FAQ
What happens if a review or property listing changes after I scrape it?
The Actor doesn't flag stale reviews — it returns what TripAdvisor's page shows at request time, stamped with scrapedAt. Re-run the Actor against the same startUrls to pick up new reviews, updated ownerResponse replies, or a changed placeInfo.rating.
Can I get reviewer profile data along with the review text?
Yes — scrapeReviewerInfo: true (the default) attaches user.name, username, userLocation, avatar, link, and contributions.totalContributions to every row. contributions.helpfulVotes is always returned as null; no source for a per-user helpful-votes total exists on the data this Actor reads.
How accurate is the rating and review data?
The Actor returns rating, text, and property data exactly as TripAdvisor's page shows it at request time. Accuracy of placeInfo.rating/ratingHistogram depends on TripAdvisor's own aggregation being current, and pctReviewsWithPhotos reflects only this run's sample of a property, not its full review history.
How many reviews can I get per run?
Up to maxComments, capped at 10,000 by the input schema. TripAdvisor's own API returns 10 reviews per page regardless of input, so the Actor paginates automatically; pagination also stops once it passes a 10,000-review safety ceiling or reaches the property's total review count, whichever comes first.
How do hasPhotos and minPhotoCount work together?
Both are post-fetch filters over the same photos[] array a review already carries — no extra requests. hasPhotos: true keeps only reviews with 1+ photos; minPhotoCount sets a higher bar (e.g. 3 drops any review with 0–2 photos). Use either alone or combine them; minPhotoCount effectively supersedes hasPhotos when set above 0.
How does this differ from a standard TripAdvisor review scraper?
This variant adds a photo/visual-content layer on top of the same collection engine: caller-controlled photo depth (maxPhotosPerReview, 1–20 instead of a fixed 10), photo-richness filters (hasPhotos, minPhotoCount), and derived coverage stats (photoCount, pctReviewsWithPhotos) that a plain text-and-rating scraper doesn't compute.
Does this scraper work with Claude, ChatGPT, and AI agent frameworks?
It isn't published with an MCP server, so it's not directly registerable as an MCP tool today. It is callable as a standard Apify Actor run via apify-client from any language or agent framework that can make an HTTP call and parse JSON — including custom tools built for Claude or ChatGPT-based agents.
Can I use this without a TripAdvisor API key or developer account?
Yes. You need only an Apify account to run it. No TripAdvisor login, API key, or developer application is required — the Actor reads TripAdvisor's public pages through Apify Proxy.
Conclusion
The Tripadvisor Review Scraper : Photo & Visual Content Filters turns public hotel review pages into structured, filterable JSON — reviews, ratings, reviewer profiles, and, distinctively, photo-depth control and visual-coverage stats no plain review scraper computes. It's built for hospitality marketers, reputation agencies, market researchers, and AI pipelines that need photo-backed guest feedback at scale, not the 5-review trickle of TripAdvisor's own Content API. Add a Hotel_Review URL, hotel name, or keyword to startUrls and run it on Apify to see it in action.