Airbnb Experiences Scraper
Pricing
from $4.99 / 1,000 results
Airbnb Experiences Scraper
Scrape Airbnb Experiences listings with detailed information including title, price, rating, duration, host details, and more.
Pricing
from $4.99 / 1,000 results
Rating
0.0
(0)
Developer
Coding Frontned
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
2 days ago
Last modified
Categories
Share
Collect Airbnb Experiences listings from a city or from custom Airbnb search URLs. The Actor reads Airbnb's server-rendered experience data, falls back to stable card selectors when needed, paginates until the requested limit, and can optionally enrich records from individual detail pages.
What it can collect
- Search result identity, title, byline, location, category, price, currency, rating, review count, duration, badges, image URLs, and page metadata.
- Optional detail data: host name and description, structured location, meeting point, gallery media, highlights, agenda, guest requirements, meeting types, policies, ticketing metadata, and detail price.
- Optional bounded public review samples and currently exposed availability slots.
- A transparent diagnostic dataset record when Airbnb blocks or makes a page unavailable. Block/empty-page debugging HTML and a screenshot are also stored in the key-value store when available.
Input
All fields are optional. The default search is London with USD prices and a maximum of 50 records.
| Field | Type | Default | Description |
|---|---|---|---|
location | string | London | City, region, or country to search when startUrls is empty. |
category | enum | (all) | One of art, cooking, entertainment, fitness, history, nature, social, sports, or tours. |
currency | enum | USD | USD, EUR, GBP, CAD, AUD, INR, JPY, or SGD. |
locale | string | en | Airbnb language/locale tag such as en or fr-FR. |
startDate / endDate | YYYY-MM-DD | (none) | Optional experience date range. |
startUrls | array | (automatic) | Custom HTTPS Airbnb Experiences search URLs; these take precedence over generated search filters. |
maxItems | integer | 50 | Maximum number of records to emit, from 1 to 1,000. |
maxPages | integer | 0 | Maximum search pages; 0 means continue until maxItems or no next page. |
deduplicate | boolean | true | Remove repeated experience IDs across pages and custom URLs. |
includeDetails | boolean | false | Fetch detail pages and merge structured detail fields into records. |
maxDetailItems | integer | 20 | Maximum records to enrich when detail mode is enabled. |
includeReviews | boolean | false | Include a bounded public review sample on enriched records. |
maxReviews | integer | 5 | Maximum review entries per enriched record. |
includeAvailability | boolean | false | Include currently exposed time slots and capacity metadata. |
requestDelayMs | integer | 2000 | Delay before each request, from 0 to 15,000 ms. |
maxConcurrency | integer | 1 | Browser pages processed in parallel, from 1 to 5. |
maxRequestRetries | integer | 3 | Browser request retries, from 0 to 10. |
requestTimeoutSecs | integer | 120 | Browser and HTTP timeout, from 30 to 300 seconds. |
proxyConfiguration | object | direct/no proxy | Optional Apify or custom proxy settings. Explicit proxy setup failures stop the run; direct HTTP fallback is not used behind the caller's back. |
Example input:
{"location": "London","currency": "GBP","maxItems": 10,"maxPages": 2,"includeDetails": true,"maxDetailItems": 3,"includeReviews": true,"maxReviews": 3,"includeAvailability": true,"requestDelayMs": 2500}
Custom URL example:
{"startUrls": [{ "url": "https://www.airbnb.com/s/Paris/experiences?currency=EUR" }],"maxItems": 5}
Output
Each experience record contains stable search fields such as experienceId, url, title, description, location, price, priceFormatted, currency, rating, reviewCount, durationMinutes, category, thumbnailUrl, imageUrls, badges, searchLocation, pageNum, source, extractionMethod, and scrapedAt. Optional fields are omitted when Airbnb does not expose them; the dataset schema marks them nullable.
When includeDetails is enabled, additional fields include detailEnriched, detailDescription, detailPriceFormatted, detailCategory, hostName, hostUrl, hostDescription, meetingPoint, locationDetails, detailImageUrls, detailImageCount, detailImageAspectRatios, highlights, agenda, guestRequirements, meetingTypes, policies, productType, isTicketed, and supportsLimitedInventory.
With the corresponding toggles, reviews contains bounded public review objects and availability contains currently exposed slot/capacity objects. If a detail request fails, the original search record is still emitted with detailEnriched: false, detailError, and detailErrorCode.
Example record:
{"experienceId": "1234567","url": "https://www.airbnb.com/experiences/1234567","title": "Example Historic Walking Tour","description": "Explore a historic district with a local guide.","location": "Example City","price": 45,"priceFormatted": "From $45 USD per guest","currency": "USD","rating": 4.9,"reviewCount": 128,"durationMinutes": 150,"category": "Cultural tours","thumbnailUrl": "https://a0.muscache.com/im/pictures/example.jpg","imageUrls": ["https://a0.muscache.com/im/pictures/example.jpg"],"badges": ["Popular"],"searchLocation": "Example City","pageNum": 1,"source": "Airbnb Experiences search","extractionMethod": "browser_ssr_json","scrapedAt": "2026-01-15T12:00:00.000Z"}
Notes
Only public Airbnb pages are requested with bounded retries and pacing, one transparent Apify user-agent, and ordinary headers. Fingerprint generation, header generation, login, CAPTCHA solving, paywall crossing, and other access-control bypasses are not used. Direct access is the default; an explicit proxy configuration is honored when supplied. CAPTCHA/access-denied/rate-limit responses create a BLOCKED_FAIL_CLOSED diagnostic and fail the run when no real experience rows are available. Use a respectful delay and low concurrency, and review Airbnb's current terms before collecting data.
For local QA, run npm test and npm run validate. Cloud JSON can be checked without storing a copy by piping it to node validate-datasets.js -.