Idealista Property Scraper avatar

Idealista Property Scraper

Pricing

from $5.00 / 1,000 result row emitteds

Go to Apify Store
Idealista Property Scraper

Idealista Property Scraper

Scrape normalized property listings from idealista.com (Spain), idealista.it (Italy), and idealista.pt (Portugal) in one run — unified EUR/m² schema, sale or rent, plus agency and lister contact enrichment neither incumbent ships together.

Pricing

from $5.00 / 1,000 result row emitteds

Rating

0.0

(0)

Developer

DevilScrapes

DevilScrapes

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Categories

Share


🎯 What this scrapes

Idealista is the shared real-estate platform behind idealista.com (Spain), idealista.it (Italy), and idealista.pt (Portugal) — the #1 property portal in every one of those markets. Cross-border investors and PropTech teams today stitch together three separate scrapes with three different schemas just to compare a Madrid flat to a Lisbon apartment. This Actor wraps all three TLDs into a single run and a single normalized schema — EUR pricing, m² area, a shared property-type taxonomy, and EU energy ratings — so a country field is the only thing that changes between rows. On top, every row already carries the agency/lister name straight from the search page, and an optional detail-page pass adds bathrooms, energy rating, coordinates, and the agency's own reference code — fields most Idealista scrapers skip entirely.

🔥 What we handle for you

  • 🛡️ A real browser engine, not a bare HTTP client — we drive an anti-detection browser through a same-context warm-up sequence so the target sees genuine browser traffic, never a bot signature.
  • 🌐 Residential proxy rotation via Apify Proxy, pinned per country — a fresh exit IP on every retry, never the same flagged exit twice.
  • 🧱 A geo-splash guard on every response — a mismatched exit can return a different country's listings at a clean 200; we catch and reject that before it ever reaches your dataset.
  • 🔁 Automatic retries with a freshly rotated proxy session on any block signal.
  • 🧊 Clean, typed dataset rows — Pydantic-validated, ISO-8601 timestamps, stable IDs, JSON / CSV / Excel export straight from the Apify Console.
  • 💰 Pay-Per-Event pricing — you only pay for results that hit your dataset. No data, no charge.

💡 Use cases

  • Cross-border deal screening — compare sale listings in Madrid, Rome, and Lisbon side by side without normalizing three different scrapers' output yourself.
  • Rental market benchmarking — track price-per-m² across ES/IT/PT rental markets in one dataset.
  • Agency/lister lead lists — collect agency names and agent reference codes behind active listings (enable enrichAgencyContact for the reference code).
  • Relocation and expat services — build a unified property feed spanning three Southern European markets for client-facing search tools.

⚙️ How to use it

  1. Click Try for free at the top of the page.
  2. Fill in the input form — most fields have sensible defaults.
  3. Click Start. Output streams into the run's dataset.
  4. Export from Storage → Dataset as JSON, CSV, or Excel — or fetch via the API.

📥 Input

FieldTypeRequiredDefaultNotes
countriesarrayno['ES']Countries to run (ES/IT/PT). Each country runs independently — one blocked country doesn't stop the others.
searchUrlsarrayno'—'Direct idealista.com / idealista.it / idealista.pt search URLs to scrape as-is. Country is inferred from the TLD. Up to…
locationstringno'madrid-madrid'idealista's own two-part search slug — municipality-province, e.g. 'madrid-madrid' (most municipalities do NOT share…
operationstringno'sale'Sale vs. rent. Country-agnostic — mapped to the right per-TLD slug internally.
propertyTypestringno'homes'Shared property-type taxonomy across all three TLDs.
maxResultsPerCountryintegerno100Cap on rows per country; each country's cap is independent.
enrichAgencyContactbooleannoFalseFetch each listing's detail page and add bathrooms, a richer floor label, EU energy rating letter (when the listing's…
proxyCountryMapobjectno{'ES': 'ES', 'IT': 'IT', 'PT': 'PT'}Override the proxy exit country per target country. Idealista hard-localizes by IP — a mismatched exit silently returns…
proxyConfigurationobjectno{'useApifyProxy': True, 'apifyProxyGroups': ['RESIDENTIAL']}Mandatory-by-default RESIDENTIAL — country_code is resolved per-request from Proxy country map.

Example input

{
"countries": [
"ES"
],
"location": "madrid-madrid",
"operation": "sale",
"propertyType": "homes",
"maxResultsPerCountry": 3,
"enrichAgencyContact": false,
"proxyCountryMap": {
"ES": "ES",
"IT": "IT",
"PT": "PT"
},
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": [
"RESIDENTIAL"
]
}
}

📤 Output

Every row is one dataset item.

FieldTypeNotes
listing_idstringIdealista ID, per-TLD.
urlstringCanonical detail URL.
countrystringNormalization key — 'ES', 'IT', or 'PT'.
operationstring'sale' or 'rent', as requested.
property_typestringShared taxonomy value.
titlestringListing headline.
price['number', 'null']Asking price.
currencystringAlways 'EUR'.
price_per_sqm['number', 'null']Published or computed.
area_sqm['number', 'null']Normalized to m².
rooms['integer', 'null']Room count. From the search page on every run.
bathrooms['integer', 'null']Bathroom count. Only available with enrichAgencyContact on.
floor['string', 'null']Raw label, not normalized (per-market variance).
energy_rating['string', 'null']EU EPC letter A–G. Only available with enrichAgencyContact on, and only when the listing's own detail page renders a…
location_address['string', 'null']Street address. Not currently resolvable from idealista's own page markup — always null.
location_neighborhood['string', 'null']Neighborhood, when public.
location_city['string', 'null']City, when resolvable. null (never a placeholder string) when idealista's own markup didn't expose it for this listing.
location_province['string', 'null']Province/region. Not currently resolvable from idealista's own page markup — always null.
latitude['number', 'null']WGS-84 map pin latitude. Only available with enrichAgencyContact on.
longitude['number', 'null']WGS-84 map pin longitude. Only available with enrichAgencyContact on.
agency_name['string', 'null']Agency/lister name, from the search page on every run.
agency_phone['string', 'null']Not exposed anywhere in idealista's page markup — revealing it requires an authenticated AJAX call this Actor does not…
listing_owner_type['string', 'null']'particular' or 'professional'. Not reliably derivable from idealista's current page markup — always null rather than…
agent_reference_id['string', 'null']Agency's own reference code. Only available with enrichAgencyContact on.
listed_date['string', 'null']ISO YYYY-MM-DD. Not currently resolvable from idealista's own page markup — always null.
updated_date['string', 'null']ISO YYYY-MM-DD. Not currently resolvable from idealista's own page markup — always null.
description_snippet['string', 'null']First ~300 chars. From the search page on every run.
image_urlsarrayGallery photos. 1-3 from the search page on every run; the full gallery with enrichAgencyContact on.
scraped_atstringISO-8601 UTC row-creation timestamp.

Example output

{
"listing_id": "111433413",
"url": "https://www.idealista.com/inmueble/111433413/",
"country": "ES",
"operation": "sale",
"property_type": "homes",
"title": "Piso en Calle del Barco, Malasaña-Universidad, Madrid",
"price": 750000.0,
"currency": "EUR",
"price_per_sqm": 7352.94,
"area_sqm": 102.0,
"rooms": 2,
"bathrooms": 2,
"floor": "1ª planta interior con ascensor",
"energy_rating": "D",
"location_address": null,
"location_neighborhood": "Malasaña-Universidad",
"location_city": "Madrid",
"location_province": null,
"latitude": 40.4232645,
"longitude": -3.7037263,
"agency_name": "Gilmar Centro",
"agency_phone": null,
"listing_owner_type": null,
"agent_reference_id": "AG222680",
"listed_date": null,
"updated_date": null,
"description_snippet": "GILMAR Consulting Inmobiliario pone a su disposición este sofisticado y acogedor piso de 102 m², ubicado en el corazón del emblemático barrio de Chueca, en pleno centro de Madrid.",
"image_urls": [
"https://img4.idealista.com/blur/591_420_mq/0/id.pro.es.image.master/6c/dd/2c/1441278735.jpg",
"https://img4.idealista.com/blur/189_120_mq/0/id.pro.es.image.master/46/b8/f4/1437239139.jpg"
],
"scraped_at": "2026-09-22T09:30:26+00:00"
}

💰 Pricing

Pay-Per-Event — you pay only when these events fire:

EventUSDWhat it is
actor-start$0.2One-off warm-up charge per run
result-row$0.005Per unique dataset item

Example: 1 000 results at the rates above ≈ $5.20. No subscription, no minimum, no card to start — Apify gives every new account $5 of free credit.

🚧 Limitations

v1 covers Spain, Italy, and Portugal only — Idealista doesn't operate in other markets. New-development/promoter microsites, the mortgage calculator, area-guide pages, and saved-search/alert features behind an agency login are out of scope. agency_phone and listing_owner_type (professional vs. private) are not exposed anywhere in idealista's own page markup on any of the three sites and always ship null — revealing a phone number requires an authenticated request this Actor does not make. location_address (a clean street), location_province, listed_date, and updated_date are likewise not resolvable from the page and always ship null. bathrooms, energy_rating, latitude/longitude, and agent_reference_id only populate with enrichAgencyContact on — see Pricing for the cost trade-off. floor stays a raw label — market-specific floor conventions aren't normalized across countries.

❓ FAQ

Do I need an Idealista account or API key?

No. This Actor scrapes Idealista's own publicly listed property data across all three TLDs — no login, no API key.

Why does this default to a residential proxy pinned per country?

Idealista localizes by IP — a mismatched exit can silently return a different country's listings. We default every request to a RESIDENTIAL proxy pinned to the target country so ES/IT/PT runs never cross-contaminate.

Can I mix countries in one run?

Yes — set countries to any combination of ES/IT/PT (or supply direct searchUrls), and each country is fetched independently; one blocked country never stops the others.

Does agency_phone ever populate?

No — idealista doesn't expose a phone number in any page's static markup on any of the three sites; revealing one requires an authenticated request this Actor doesn't make. agency_name and agent_reference_id (with enrichAgencyContact on) are the reliable contact fields instead.

💬 Your feedback

Spotted a bug, hit a weird edge case, or need a new field? Open an issue on the Actor's Issues tab on Apify Console — we ship fixes weekly and we read every report.