Idealista Scraper
Pricing
from $0.005 / property listing
Idealista Scraper
DeprecatedFast Idealista scraper for Spain, Italy, and Portugal. Returns 100+ fields per listing including AI summaries, Q&A pairs, deal signals, engagement scores, and price tracking. Supports 60+ search filters, multiple locations per run, and outputs data optimized for RAG pipelines and answer engines.
Pricing
from $0.005 / property listing
Rating
0.0
(0)
Developer
Datacut
Actor stats
0
Bookmarked
6
Total users
2
Monthly active users
2 months ago
Last modified
Categories
Share
Fast, lightweight scraper for Idealista real estate listings in Spain, Italy, and Portugal. Extracts 100+ fields per listing with AI-ready enrichment for RAG, vector search, and answer engines.
Built by datacut — AI-first data extraction.
Features
- 60+ search filters — every filter Idealista supports (property type, price, size, features, rental criteria, and more)
- Full property details — floor plans, energy certificates, building characteristics, agent info
- Engagement stats — views, emails, favorites, shares per listing
- AI/LLM enrichment — 15+ computed fields for RAG, AEO, classification, and analytics
- Price tracking — cross-run price change detection with delta and percentage
- 3 countries — Spain (13,400+ locations), Italy, Portugal
- Multiple locations — search across multiple cities in a single run with deduplication
- Self-healing — adaptive pacing, circuit breaker, identity rotation, checkpoint/resume
- Proxy pool — rotate across multiple HTTP/HTTPS proxies on identity change
- Graceful shutdown — SIGINT/SIGTERM saves progress, resume from checkpoint
- Discord/Slack alerts — breaker trips, identity rotations, run summaries
- Low resource usage — ~15MB Docker image, 128MB RAM, no browser needed
Quick Start
# Buildgo build -o ./idealista-scraper .# Search by city nameAPIFY_INPUT='{"location":"Madrid","maxItems":10}' ./idealista-scraper# Search with filtersAPIFY_INPUT='{"location":"Barcelona","operation":"rent","maxItems":20,"minPrice":500,"maxPrice":1500,"bedrooms":"2","elevator":true}' ./idealista-scraper# Full details + stats (best for AI)APIFY_INPUT='{"location":"Madrid","maxItems":5,"fetchDetails":true,"fetchStats":true}' ./idealista-scraper# Multiple locationsAPIFY_INPUT='{"locations":["Madrid","Barcelona","Valencia"],"maxItems":100}' ./idealista-scraper# With proxy pool + Discord alertsAPIFY_INPUT='{"location":"Madrid","maxItems":50,"proxyUrls":["http://user:pass@proxy1:8080"],"webhookUrl":"https://discord.com/api/webhooks/..."}' ./idealista-scraper# Dockerdocker build -t idealista-scraper .docker run -e APIFY_INPUT='{"location":"Madrid","maxItems":5}' idealista-scraper
Input
Core
| Param | Type | Default | Description |
|---|---|---|---|
country | string | "es" | Country: es (Spain), it (Italy), pt (Portugal) |
operation | string | "sale" | sale or rent |
propertyType | string | "homes" | homes, offices, premises, garages, lands, bedrooms, storageRooms, buildings |
location | string | City name ("Madrid") or location ID ("0-EU-ES-28") | |
locations | string[] | Multiple locations, max 10 (searched sequentially, results deduplicated) | |
propertyCodes | string[] | Specific listing IDs to fetch (max 100) | |
maxItems | int | 50 | Max listings to collect (max 500 per run) |
sortBy | string | "relevance" | relevance, price_asc, price_desc, size_asc, size_desc, date_desc, price_per_m2_asc, price_drop |
Price & Size
| Param | Type | Description |
|---|---|---|
minPrice / maxPrice | float | Price range (EUR) |
minSize / maxSize | float | Size range (m²) |
bedrooms | string | Bedrooms (e.g. "2", "3+") |
bathrooms | string | Bathrooms |
Property Subtypes (boolean)
flat, penthouse, duplex, studio, chalet, countryHouse
Building Features (boolean)
airConditioning, elevator, garage, garden, swimmingPool, terrace, storeRoom, builtinWardrobes, exterior, heating, hotWater, security, corner, smokeVentilation, clotheslineSpace, accessible, luxury, seaViews
Multimedia (boolean)
virtualTour, pictures, professionalVideo, hasPlan
Building Details
| Param | Type | Description |
|---|---|---|
furnished | string | Furnishing status |
preservations | string | Conservation status |
floorHeights | string | Floor height filter |
buildingType | string | Building type |
buildingTypes | string[] | Multiple building types |
Listing Type (boolean)
bankOffer, newDevelopment, stateSubsidized, rentToOwn, finished, transfer
Owner
| Param | Type | Description |
|---|---|---|
ownerType | string | "privateOwner" or "professionalOwner" |
Rental / Roommate
| Param | Type | Description |
|---|---|---|
petsAllowed | bool | Pets allowed |
petsPolicy | string | Pet policy |
childrenAllowed | bool | Children allowed |
couplesAllowed | bool | Couples allowed |
gayPartners | bool | LGBTQ+ friendly |
newGender | string | Gender preference |
housemates | string | Housemate info |
occupation | string | Occupancy type |
ownerNotLiving | bool | Owner not living in property |
smokingPolicy | string | Smoking policy |
Other Filters
| Param | Type | Description |
|---|---|---|
sinceDate | string | Listing date filter (T=today, W=week, M=month, Y=year) |
distance | int | Distance radius (meters) |
promotionId | string | Promotion ID |
agency | string | Agency filter |
landTypes | string[] | Land type filter |
typologies | string[] | Property typologies |
subTypology | string[] | Sub-typologies |
Data Fetching
| Param | Type | Default | Description |
|---|---|---|---|
fetchDetails | bool | false | Full details per listing (energy cert, characteristics, comments). +1 API call/listing. |
fetchStats | bool | false | Engagement stats (views, emails, favorites). +1 API call/listing. |
Proxy & Notifications
| Param | Type | Description |
|---|---|---|
proxyUrl | string | Single proxy URL |
proxyUrls | string[] | Proxy pool — rotated on identity change |
webhookUrl | string | Discord/Slack webhook for real-time alerts |
Output
Base Listing Fields
Every listing includes all fields returned by Idealista's API:
propertyCode, propertyType, operation, country, price, priceByArea, size, rooms, bathrooms, floor, address, municipality, district, neighborhood, province, latitude, longitude, description, url, thumbnail, status, exterior, hasLift, numPhotos, contactInfo, features, parkingSpace, multimedia, suggestedTexts, priceDropPercentage, priceDropValue
With fetchDetails: true: moreCharacteristics, ubication, energyCertification, propertyComment, comments, priceReferenceIndex, labels
With fetchStats: true: stats (views, emails, favourites, shares)
AI/LLM Enrichment
Every listing is enriched with computed fields optimized for AI consumption:
| Field | Type | Description |
|---|---|---|
aiSummary | string | Natural language paragraph — reads like an analyst brief. Includes engagement, area pricing, amenities, market signals. |
llmContext | object | Flat, denormalized key-value map. No nested JSON to parse. Omits empty/null/zero values to save tokens. |
keyFacts | string[] | Scannable bullet-point array: ["3-bed/2-bath, 120m²", "€10/m²", "A/C", "Pool", "90 views, 27 saves"] |
qaReady | object[] | Pre-computed Q&A pairs for Answer Engine Optimization (AEO). Matches how people search: "How much is a 3-bedroom flat to rent in Sitges?" |
amenities | string[] | Flat, deduplicated amenity list extracted from all nested sources (features, characteristics, parking, energy cert). |
tags | string[] | Keyword array for faceted search and RAG classification. Covers: type, operation, features, price bracket, engagement tier, location, seller type. |
searchableText | string | Dense plain-text blob for vector embeddings and full-text search. Includes both metric and imperial, English translations from multilingual comments. |
engagementScore | float | Weighted 0-100 composite of views, favorites, contacts, shares. Log-scaled. |
priceContext | object | Area comparison: vsAreaMedianPercent, pricePosition (well-below-average to well-above-average), areaMedianPricePerM2. Falls back from municipality to province for small datasets. |
dataQuality | object | Completeness score (0-100) with weighted field breakdown and list of missing fields. |
rankInArea | object | Relative position within municipality: cheapest-in-area, largest-in-area, most-popular-in-area, priceRank, totalInArea. |
dealIndicator | string | Market timing signal: hot-deal, price-reduced, just-listed, trending, fresh, stable, aging, stale |
daysOnMarket | int | Multi-signal estimated listing age (engagement-based when API dates are unreliable) |
daysOnMarketEstimated | bool | true when age is estimated from engagement data rather than exact dates |
priceSegment | string | budget, mid, upper, premium, luxury (rent-aware thresholds) |
goldenVisaEligible | bool | Investment threshold check (>=500k in ES/PT) |
sizeInSqft | float | Imperial size conversion |
priceByAreaSqft | float | Price per sqft |
googleMapsUrl | string | Direct Google Maps link |
Price Tracking
On repeat runs, each listing gets:
| Field | Type | Description |
|---|---|---|
isNew | bool | true if listing wasn't in previous run |
priceChange | float | Absolute price change (EUR) |
previousPrice | float | Price from previous run |
priceChangePercent | float | Percentage change |
Example AI Summary
3-bedroom flat for rent at €1,600/month in Sitges, Barcelona. The property offers 102m² (1,098 sqft) with 3 bedrooms and 2 bathrooms on floor 1. Features include elevator, exterior-facing, parking available, and pets allowed. Very high interest: 2937 views, 236 saves. At €16/m², this is 10% above the area median. Seasonal rental — limited-term contract. Listed by ABC Inmobiliaria (agency).
Example keyFacts
["3-bed/2-bath, 102m²", "€16/m²", "Good condition", "Elevator", "Exterior", "Parking", "Pets OK", "Energy INPROCESS", "2937 views, 236 saves", "Seasonal rental"]
Example qaReady
[{"q": "How much is a 3-bedroom flat to rent in Sitges?", "a": "€1,600/month for a 102m² 3-bedroom flat (listing 109185499)."},{"q": "How big are 3-bedroom flats in Sitges?", "a": "This 3-bedroom flat in Sitges is 102m² (1,098 sqft)."},{"q": "What amenities does this flat in Sitges have?", "a": "This property includes: elevator, exterior-facing, parking available, and pets allowed."},{"q": "Are there pet-friendly flats for rent in Sitges?", "a": "Yes — this flat in Sitges allows pets. €1,600/month, 102m²."},{"q": "Is this flat in Sitges popular?", "a": "It has 2937 views and 236 saves, with an engagement score of 100/100."}]
Resilience
| Layer | Mechanism | Purpose |
|---|---|---|
| Timing | Poisson-distributed delays | Human-like, non-fingerpritable inter-request timing |
| Pacing | Adaptive pacer (sliding window) | Learn safe throughput from observed responses |
| Identity | UA rotation + device fingerprint | New identity on every rotation |
| Proxy | Pool rotation on identity change | Distribute traffic across IPs |
| Recovery | Circuit breaker with slow-start | Stop on repeated failures, probe cautiously |
| Lifecycle | Session retirement after N requests | Preemptive rotation before detection |
| Auth | Proactive token refresh | Refresh before expiry |
| Resumability | Checkpoint per page | Resume from crash without re-scraping |
| Shutdown | SIGINT/SIGTERM handler | Save partial results on graceful stop |
| Alerts | Discord/Slack webhooks | Real-time visibility into run events |
Tests
$go test ./...
Countries
| Code | Country | Locations |
|---|---|---|
es | Spain | 13,400+ |
it | Italy | Bundled |
pt | Portugal | Bundled |
Deployment
Docker
docker build -t idealista-scraper .docker run -e APIFY_INPUT='{"location":"Madrid","maxItems":5}' idealista-scraper
Apify
Set environment variables:
APIFY_TOKEN— API tokenAPIFY_DEFAULT_KEY_VALUE_STORE_ID— Input storeAPIFY_DEFAULT_DATASET_ID— Output dataset
Or use file-based I/O:
- Input:
storage/key_value_stores/default/INPUT.json - Output:
storage/datasets/default/*.json - Report:
storage/key_value_stores/default/REPORT.md
Recommended Settings
| Setting | Value | Why |
|---|---|---|
| Memory | 128 MB | Pure HTTP, no browser |
| Timeout | 3600s | Allows large multi-location runs |
| Proxy | Residential | Datacenter IPs are blocked |
fetchDetails | true | Unlocks energy cert, full descriptions, multilingual comments |
fetchStats | true | Unlocks engagement data (views, favorites) — powers AI enrichment |