Airbnb Images Scraper With Room Labels & True Location avatar

Airbnb Images Scraper With Room Labels & True Location

Pricing

from $3.99 / 1,000 results

Go to Apify Store
Airbnb Images Scraper With Room Labels & True Location

Airbnb Images Scraper With Room Labels & True Location

Pricing

from $3.99 / 1,000 results

Rating

0.0

(0)

Developer

Scraply

Scraply

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

0

Monthly active users

9 days ago

Last modified

Share

Scrape the full Airbnb photo tour — not just the 8 preview images most Airbnb scrapers return — with every photo labeled by room (bedroom, kitchen, bathroom, exterior...), plus the listing's real country, region, city and GPS coordinates. Give it Airbnb room URLs, get a photo-by-photo, room-by-room breakdown of the listing back as structured JSON/CSV/Excel.

This actor is a superset of the base airbnb-images-scraper: every base input and every base output field (url, title, location, rating, reviews, images) still works exactly as before — this variant only adds new fields and inputs alongside them.

What does this Airbnb photo scraper do?

Most Airbnb scrapers stop at the handful of images embedded in the listing page's structured-data block — usually just 8, regardless of how many photos the host actually uploaded. This actor instead reads the listing's own photo-tour data and returns:

  • Every photo in the tour (measured 22–126 photos per listing, vs. 8 from the base actor), each with its own direct image URL, id, orientation, aspect ratio and accessibility label.
  • The room each photo belongs toroomName from Airbnb's own room-tour breakdown (living room, bedroom 1, kitchen, pool, etc.), backed by Airbnb's own machine-generated airbnbTags as a fallback signal.
  • A per-room roll-up (rooms[]) — how many photos exist for each room, so you can spot "1 photo of the bathroom, 27 of the exterior" at a glance.
  • The listing's true location — country, region, city, the exact location line Airbnb prints on the page, and latitude/longitude — independent of the base actor's location field (which is preserved unchanged for backward compatibility, including its known limitation, see Honest caveats below).
  • Host captions where the host wrote one, plus their machine translation when Airbnb auto-translated it.
  • Property type and overview facts (bedrooms/beds/baths/guests) as the denominator for judging how much photo coverage a listing has.

Use it for reshoot audits (which rooms are under-photographed), portfolio mapping (real coordinates instead of a hardcoded region), photo-tour QA for property managers, or building a room-labeled Airbnb photo dataset for research or ML training data.

Key features

  • 📷 Full photo tour, not a fixed preview set — every photo the listing's photo-tour section serves, in one HTTP round-trip (no extra requests per photo).
  • 🚪 Photo-to-room labelingroomName + Airbnb's own room tags (airbnbTags), something no competing Airbnb photo/image scraper on Apify currently ships.
  • 🌍 Real location data — true country/region/city/breadcrumbs + coordinates, fixing the base actor's location field without breaking it.
  • 🔎 Room filter — keep only photos matching a room keyword (e.g. bedroom, kitchen, exterior, pool).
  • 🔢 Minimum-photos filter — drop thin listings (or surface only the richest ones) before you even look at the dataset.
  • 🧾 Derived countsphotoCount, captionedPhotoCount, roomCount, roomNames, isRoomBreakdownAvailable, photosMissingRoomLabel for quick dataset scanning.
  • 🛡️ Automatic proxy fallback — starts without a proxy, switches to Apify Residential proxy on a detected block, and follows Airbnb's geo-redirect ("domain switch") page automatically so runs succeed from non-US egress too.
  • ↩️ Backward compatible — a base-actor input (just urls) still runs and returns the base's own 6 fields with identical values.

How to use

  1. Add one or more Airbnb room URLs (e.g. https://www.airbnb.com/rooms/782682596976136912) to the urls input — one per line.
  2. Leave includePhotoDetails and includeTrueLocation on (both default to true) to get the full photo tour, room labels and true location. Turn either off to get a lighter, base-only payload.
  3. Optionally set roomFilter (e.g. ["bedroom", "pool"]) to keep only matching photos, and/or minPhotos to skip thin listings entirely.
  4. Run the actor. Each input URL produces one dataset row; export it as JSON, CSV, or Excel from the Apify dataset UI.

This actor scrapes individual listing (room) pages — it does not accept a city/search query and does not paginate search results; each row corresponds to one Airbnb room URL you provide.

Input

{
"urls": [
"https://www.airbnb.com/rooms/782682596976136912"
],
"includePhotoDetails": true,
"includeTrueLocation": true,
"roomFilter": [],
"minPhotos": 0
}
InputTypeDefaultDescription
urlsarray (stringList)— (required)Airbnb room URLs, one per line. Must match https://www.airbnb.com/rooms/....
includePhotoDetailsbooleantrueFull photo tour + room labels + propertyType/overviewFacts/photo & room counts. Turn off for base-only (8-image) behavior.
includeTrueLocationbooleantrueTrue locationLine, country, region, city, breadcrumbs, latitude/longitude.
roomFilterarray (stringList)[]Keep only photos whose room name or Airbnb room tag contains any of these words (case-insensitive substring match). Empty = keep all. Only applies when includePhotoDetails is on.
minPhotosinteger0Drop the whole listing if its raw photo count (before roomFilter) is below this number. 0 = keep every listing. Only applies when includePhotoDetails is on.
proxyConfigurationobject (proxy)Apify Proxy off by defaultSame as the base actor — proxy is only engaged automatically after a detected block.
requestTimeoutSecsinteger30Per-request timeout in seconds (5–120).

Output

[
{
"url": "https://www.airbnb.com/rooms/782682596976136912",
"title": "\"Perfect Getaway\" 2 Miles from MIA & 8To UR Cruise",
"locationLine": "Hialeah, Florida, United States",
"locationCountry": "United States",
"locationRegion": "Florida",
"locationCity": "Hialeah",
"locationBreadcrumbs": ["Homes", "United States", "Florida", "Hialeah"],
"latitude": 25.857,
"longitude": -80.278,
"location": "Hialeah, Florida, United States",
"propertyType": "Entire guest suite",
"overviewFacts": ["4 guests", "1 bedroom", "2 beds", "1 bath"],
"rating": 4.95,
"reviews": 168,
"photoCount": 44,
"captionedPhotoCount": 15,
"roomCount": 6,
"roomNames": ["Bedroom", "Kitchen", "Bathroom", "Living room", "Exterior", "Pool"],
"isRoomBreakdownAvailable": true,
"photosMissingRoomLabel": 3,
"images": [
"https://a0.muscache.com/im/pictures/c6cbda16-164d-481c-99d4-9d3c6344986c.jpg"
],
"photos": [
{
"id": "1620294495",
"url": "https://a0.muscache.com/im/pictures/...jpg",
"roomName": "Bedroom",
"airbnbTags": ["Bedroom"],
"caption": "Queen bed with garden view",
"captionTranslated": null,
"accessibilityLabel": "Bedroom",
"orientation": "LANDSCAPE",
"aspectRatio": 1.5
}
],
"rooms": [
{ "roomName": "Bedroom", "photoCount": 8, "photoIds": ["1620294495", "..."], "roomFeatures": ["Queen bed"] }
],
"scrapedAt": "2026-07-30T12:00:00Z"
}
]

Output fields

FieldDescription
url, title, location, rating, reviews, imagesBase actor fields, unchanged — location keeps the base actor's own hardcoded region suffix (see caveats below), and images stays capped at the ~8 URLs from the page's structured-data block.
locationLineThe location line Airbnb itself prints on the listing page (e.g. "Rome, Lazio, Italy").
locationCountry / locationRegion / locationCityParsed from the listing's own breadcrumb trail and location block.
locationBreadcrumbsThe full breadcrumb trail as Airbnb structures it.
latitude / longitudeThe listing's coordinates.
propertyTypee.g. "Entire apartment", "Entire guest house".
overviewFactsGuest/bedroom/bed/bathroom counts as a plain string list.
photoCountNumber of photos in the full photo tour (post-filter if roomFilter/minPhotos are set).
captionedPhotoCountNumber of those photos that have a host caption.
roomCount / roomNamesNumber and names of distinct rooms identified.
isRoomBreakdownAvailabletrue when Airbnb's own room-tour breakdown had real room titles for this listing; false when it didn't (see caveats).
photosMissingRoomLabelHow many of the returned photos have no roomName (even after the airbnbTags fallback).
photos[]One entry per photo: id, url, roomName, airbnbTags, caption, captionTranslated, accessibilityLabel, orientation, aspectRatio.
rooms[]One entry per identified room: roomName, photoCount, photoIds, roomFeatures.
scrapedAtISO 8601 UTC timestamp of when the row was scraped.

Failed URLs are pushed as a 2-key row ({"url", "error"}) instead of the full row above — the same shape the base actor uses.

Honest caveats (measured, not assumed)

  • location (base field) is preserved as-is, including its known bug: the base actor hardcodes a , Florida, United States suffix onto every listing regardless of the real location. This variant keeps that field unchanged for backward compatibility — read locationLine/locationCountry/locationRegion/locationCity instead for the real address.
  • images (base field) stays capped at whatever the page's structured-data block ships — measured at 8 URLs regardless of the listing's real photo count. Use photos[] for the full tour.
  • locationLine coverage was measured at roughly 70% across a multi-country sample — it can come back null on some listings. locationCountry/locationBreadcrumbs/locationCity were present on 100% of the sample; locationRegion is sometimes a shallow value (e.g. a district name rather than a full region) when the listing's breadcrumb trail is short.
  • Room labels (roomName) come from Airbnb's own room-tour breakdown, which is not present on every listing — measured present on roughly 3 out of 4 listings sampled; the remaining listings return isRoomBreakdownAvailable: false and rely on the airbnbTags fallback (which covered nearly all photos in testing, but is a coarser, tag-based signal rather than a curated room title).
  • caption coverage is low by nature — host-written captions were present on roughly a third of photos sampled; captionTranslated only appears when Airbnb auto-translated a foreign-language caption, which is rare.
  • No pricing, availability, or per-category review scores (cleanliness, accuracy, etc.) are collected — this actor is scoped to photos, rooms, and location, not pricing/booking data.
  • roomFilter filters photos, not listings — a room "survives" the filter if any of its photos matched by roomName or airbnbTags, so a room can appear in rooms[] even if only one of its photos matched directly.
  • minPhotos is evaluated on the raw (pre-roomFilter) photo count — a listing is dropped entirely, before any room filtering happens, if its full tour has fewer photos than the threshold.

Use cases

  • Reshoot / listing-quality audits — find listings with too few exterior or bathroom photos using roomFilter + photosMissingRoomLabel.
  • Portfolio mapping — plot listings on a real map using latitude/longitude instead of a guessed region.
  • Photo dataset building — a room-labeled Airbnb photo dataset for computer-vision or interior-design research.
  • Location correction — cross-check or replace a base Airbnb images dataset's location field with the real locationLine/locationCountry/locationCity.
  • Market/property research — combine propertyType, overviewFacts, rating and reviews alongside the photo breakdown for a fuller per-listing picture.

FAQ

Does this replace the base Airbnb Images Scraper? It is a superset of it — every base input and output field still works and returns the same values, with the new photo, room and location fields added alongside.

Can I search by city instead of pasting listing URLs? No. This actor scrapes individual Airbnb room pages by URL; it does not accept a location/search query or paginate search results.

Why is roomName sometimes null? Not every Airbnb listing has a room-tour breakdown published. When it's missing, isRoomBreakdownAvailable is false for that listing, and photos fall back to Airbnb's own airbnbTags where available.

Does it use a proxy for every request? No — it tries a direct request first and only switches to Apify Residential proxy after detecting a block (or an Airbnb geo-redirect page it can't resolve directly), matching the base actor's proxy behavior.