Use TripAdvisor Hotel, Restaurant & Attraction Finder with Python
Search TripAdvisor by phrase or place URL for hotels, restaurants, and attractions, with rating, ranking, address, contact details, and pricing per place.
1. Choose the data you need
Review the published README for supported collection modes, examples, and limits. The recipe below uses the current published input definition.
2. Prepare a source-based input
This JSON contains published prefills and required-field defaults. Review every value for your task before running it; it is not a promise of successful collection.
{
"includeDetails": false,
"maxItems": 1,
"maxReviews": 20,
"mode": "search",
"query": "Eiffel Tower"
}
Download input.example.json and save your reviewed copy as input.json.
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | optional | search finds ranked places from a query; details reads one place per URL or ID; reviews exports review rows with optional filters. |
query | string | optional | What to search for, for example 'hotels in New York', 'restaurants Paris' or 'Eiffel Tower'. The place family is inferred from words such as hotels, restaurants, museums or things to do. |
location | string | optional | Optional destination used with query, for example 'New York' or 'Paris'. When set, query can be just 'hotels' or 'restaurants'. |
startUrls | array | optional | Tripadvisor place URLs (Hotel_Review, Restaurant_Review or Attraction_Review) or numeric location IDs. Used by details and reviews modes. |
maxItems | integer | optional | Maximum search results, detail places, or review target places to process. One place can return many reviews. |
includeDetails | boolean | optional | Fetches amenities and a larger photo for place rows. HTML enrichment is used in details mode when the JSON fields are missing. |
maxReviews | integer | optional | Reviews to collect for each target place in reviews mode. Upstream returns 20 per request; the actor paginates until this cap. |
reviewSort | string | optional | Order of the review stream. Attractions automatically use DETAILED for MOST_RECENT so product reviews do not mix into the attraction's own reviews. |
reviewRating | string | optional | Only return reviews with this bubble rating. |
reviewLanguage | string | optional | Only return reviews written in this language. |
reviewTripType | string | optional | Only return reviews from this traveler type. |
reviewMonth | string | optional | Only return reviews submitted in this month. |
reviewKeyword | string | optional | Only return reviews whose text matches this keyword, for example 'pool' or 'breakfast'. |
proxyConfiguration | object | optional | Optional. The actor tries direct access first, then the free Apify datacenter proxy, and only escalates after a real block. You do not need to configure a proxy to run it. |
3. Start an Actor run
Set APIFY_TOKEN in your environment. Python 3.10 or newer is sufficient; this recipe uses no third-party packages.
Execution may incur charges. Review current pricing on Apify. The request asks for a 120-second timeout and a charge limit; these settings are subject to Apify’s pricing and do not guarantee an all-inclusive spending cap.
import json
import os
import urllib.request
# Save the schema-derived example as input.json; review and edit it first.
with open("input.json", encoding="utf-8") as stream:
actor_input = json.load(stream)
token = os.environ["APIFY_TOKEN"]
request = urllib.request.Request(
"https://api.apify.com/v2/acts/sv4kVnROMGAakFpbJ/runs?timeout=120&maxTotalChargeUsd=0.50",
data=json.dumps(actor_input).encode("utf-8"),
headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"},
method="POST",
)
# This starts a potentially billable run. Do not automatically retry this POST.
with urllib.request.urlopen(request, timeout=40) as response:
run = json.load(response)["data"]
print("Run ID:", run["id"])
print("Status:", run["status"])
# Inspect and download results in Apify Console once the run succeeds.
4. Inspect the actual results
Open the run in Apify Console and wait for a successful completion. Use the published output schema to locate results and the dataset schema to understand declared views. Missing or optional record fields must not be treated as guaranteed values.
One row per place in search/details modes and one row per review in reviews mode. Empty fields are omitted at every depth. Every record carries recordType, sourceUrl and scrapedAt. Legacy place names are kept for backward compatibility; rating, numberOfReviews, latitude and longitude are strings, while ratingValue, reviewCount, lat and lng are numeric.
Questions before you run
Which inputs are required?
No top-level fields are marked required in the published schema. Conditional requirements can still apply; check the README.
What does this guide verify?
The fields, prefills, and schema links are rendered from the published build. This is a usage recipe, not a paid live extraction test. Source availability and collection results can vary.
What if the run request times out?
Check Apify Console before retrying. The first request may already have created a run. Do not automatically repeat a run-creation POST.
Generated from source build gsx9VyA0GeR1bwgRX and its README and schemas. Source changes regenerate this guide; no third-party editorial claims are inferred.