Idealista Property Scraper avatar

Idealista Property Scraper

Pricing

Pay per event

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

Pay per event

Rating

0.0

(0)

Developer

DevilScrapes

DevilScrapes

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 hours 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, it enriches each listing with agency and lister details (name, phone when publicly exposed, particular vs. professional, agent reference id) that 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, phone numbers (when public), and agent reference codes behind active listings.
  • 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.
enrichAgencyContactbooleannoTrueFetch each listing's detail page for agency/agent fields (name, phone when exposed, particular vs. professional, agent…
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": true,
"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.
bathrooms['integer', 'null']Bathroom count.
floor['string', 'null']Raw label, not normalized (per-market variance).
energy_rating['string', 'null']EU EPC letter A–G.
location_address['string', 'null']Full address, when public.
location_neighborhood['string', 'null']Neighborhood, when public.
location_citystringCity.
location_province['string', 'null']Province/region.
latitude['number', 'null']WGS-84 map pin latitude.
longitude['number', 'null']WGS-84 map pin longitude.
agency_name['string', 'null']Enrichment field.
agency_phone['string', 'null']Only if publicly exposed.
listing_owner_type['string', 'null']'particular' or 'professional'.
agent_reference_id['string', 'null']Agency's own reference code.
listed_date['string', 'null']ISO YYYY-MM-DD.
updated_date['string', 'null']ISO YYYY-MM-DD.
description_snippet['string', 'null']First ~300 chars.
image_urlsarrayGallery photos (empty OK).
scraped_atstringISO-8601 UTC row-creation timestamp.

Example output

{
"listing_id": "34567890",
"url": "https://www.idealista.com/inmueble/34567890/",
"country": "ES",
"operation": "sale",
"property_type": "homes",
"title": "Piso en Malasa\u00f1a, Madrid",
"price": 425000.0,
"currency": "EUR",
"price_per_sqm": 5312.5,
"area_sqm": 80.0,
"rooms": 2,
"bathrooms": 1,
"floor": "3\u00ba ext",
"energy_rating": "D",
"location_address": null,
"location_neighborhood": "Malasa\u00f1a-Universidad",
"location_city": "Madrid",
"location_province": "Madrid",
"latitude": 40.4265,
"longitude": -3.7038,
"agency_name": "Example Inmobiliaria",
"agency_phone": "+34910000000",
"listing_owner_type": "professional",
"agent_reference_id": "REF-8891",
"listed_date": "2026-07-02",
"updated_date": "2026-08-05",
"description_snippet": "Precioso piso reformado a estrenar en pleno barrio...",
"image_urls": [
"https://img.idealista.com/example1.jpg"
],
"scraped_at": "2026-08-11T12:00:00+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 ships verbatim, unverified, only when publicly rendered on the listing. 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 always populate?

Only when enrichAgencyContact is true and the number is publicly exposed on the listing; otherwise it's null.

💬 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.