The Mine Works
← All posts
tutorial July 11, 2026 · 4 min read

Airbnb Scraper: Listing Prices, Ratings, and Availability Without the API

Airbnb has no public listings API. Here's how to pull nightly price, rating, superhost status and coordinates from Airbnb search results using Python.

Try the scraper

The actor referenced in this article. Pay only for results delivered.

View the scraper →

Airbnb does not publish a listings API. There is a partner API for hosts to manage their own properties and for a small set of approved booking platforms, but there is no endpoint you can call to search listings by city, pull nightly prices, or read guest ratings for units you don’t own. If you’ve gone looking for api.airbnb.com/v2/search documentation, the closest you’ll get is reverse-engineered notes from other developers — Airbnb doesn’t support or document it, and it changes without notice.

That leaves scraping as the only practical way to get structured Airbnb data at scale. The catch is that Airbnb’s search results are rendered client-side behind heavy JavaScript, and the site fingerprints and rate-limits scraping traffic aggressively. The Airbnb Scraper handles the search resolution, pagination and price extraction for you, running behind residential proxies, and returns clean JSON, CSV or Excel instead of raw HTML.

What you get per listing

Each result includes:

  • listingId — Airbnb’s internal listing ID
  • name and title — listing name and subtitle
  • propertyType — e.g. “Entire rental unit”
  • personCapacity — max guests
  • price (numeric) and priceText (formatted string) plus currency
  • rating and reviewsCount
  • isSuperhost — boolean
  • latitude / longitude
  • city
  • photoUrl
  • badges — array, e.g. ["Guest favorite"]
  • url — the listing’s Airbnb page
  • scraped_at — ISO timestamp of the scrape

Notably absent: bedroom/bathroom counts and square footage. Airbnb doesn’t expose those as structured search-result fields the way Zillow does for long-term rentals — they live inside the listing description text instead, not in the search response this actor works from.

Running it

You need a location, and optionally a date range and guest count if you want date-specific pricing rather than the default nightly rate Airbnb shows for an unspecified stay.

import os
from apify_client import ApifyClient

apify = ApifyClient(os.environ["APIFY_TOKEN"])

run = apify.actor("themineworks/airbnb-scraper").call(run_input={
    "location": "Austin, TX",
    "checkIn": "2026-09-01",
    "checkOut": "2026-09-04",
    "adults": 2,
    "minPrice": 40,
    "maxPrice": 250,
    "maxItems": 200,
})

listings = list(apify.dataset(run["defaultDatasetId"]).iterate_items())
print(f"Pulled {len(listings)} listings")

Without check-in/check-out dates, you still get every field except date-adjusted pricing — Airbnb falls back to a generic nightly rate. If you’re doing pricing research (see below), always set dates: Airbnb’s nightly price swings with season and day-of-week, and a rate pulled without dates won’t match what a guest actually sees at booking time.

Reading the output

import statistics

prices = [l["price"] for l in listings if l.get("price")]
superhosts = [l for l in listings if l.get("isSuperhost")]

print(f"Median nightly price: ${statistics.median(prices):.0f}")
print(f"Superhost share: {len(superhosts)}/{len(listings)} ({len(superhosts)/len(listings)*100:.0f}%)")

# Highest-rated listings under $150/night
budget_top_rated = sorted(
    [l for l in listings if l.get("price", 999) < 150 and l.get("rating")],
    key=lambda l: l["rating"],
    reverse=True,
)[:5]

for l in budget_top_rated:
    print(f"{l['rating']}★ ({l['reviewsCount']} reviews) — {l['priceText']}{l['name']}")

Because latitude and longitude come back on every listing, you can plot results directly on a map without a separate geocoding step — useful for spotting price clusters by neighborhood rather than city-wide averages, which tend to hide a lot of variance in a market like Austin or Lisbon where price differs block by block.

Pagination and limits

Set maxItems up to 2,000 per run. Airbnb search results are capped per query in practice, so pulling a large market usually means running the actor multiple times with narrower location strings (by neighborhood rather than city) or different date windows, then combining the datasets — the same pattern you’d use against any search-paginated site with a soft per-query ceiling.

Pricing

You pay only for listings actually returned — there’s no charge for the search request itself, no subscription, and no charge if a proxy session fails to resolve results. A 200-listing pull like the one above costs a small fraction of what a scraping-as-a-service subscription runs, and there’s nothing to provision or maintain.

Where this fits

Raw listing data like this is the input, not the output. If you’re pulling it to answer “what should I charge for my own unit,” the next step is turning a list of comparable listings into an actual pricing decision — see Short-Term Rental Market Research: Using Airbnb Data for Dynamic Pricing for that workflow.

If you’re deciding whether Airbnb data or Zillow’s long-term rental data answers your question — they measure genuinely different things — Airbnb vs Zillow Rental Listings breaks down the field-level differences between nightly STR data and monthly lease data.

FAQ

Do I need an Airbnb account or API key? No. There’s no login and no API key — enter a location and run.

Can I get date-specific prices? Yes, set checkIn and checkOut and the returned price reflects that stay window.

Why does the actor use residential proxies? Airbnb fingerprints and rate-limits by IP. Residential proxies, which are the default, keep runs reliable at volume — datacenter IPs get blocked quickly on a site this aggressive about scraping defense.

Can this run inside an AI agent? Yes — it’s exposed as an MCP tool at https://mcp.apify.com/?tools=themineworks/airbnb-scraper, so an assistant like Claude can call it directly and answer a question like “find the cheapest superhost stays in Bali this weekend” with live data instead of training-data guesses.

Related Actor

Explore the scraper referenced in this article — see inputs, outputs, and pricing, then run it on Apify.