Immoweb.be [Only $1.2πŸ’°] Scraper avatar

Immoweb.be [Only $1.2πŸ’°] Scraper

Pricing

from $1.20 / 1,000 results

Go to Apify Store
Immoweb.be [Only $1.2πŸ’°] Scraper

Immoweb.be [Only $1.2πŸ’°] Scraper

πŸ’°$1.2/1K Scrape real estate listings from Immoweb.be effortlessly. This actor extracts properties for sale or rent. You get comprehensive data, including prices, precise addresses, property types, bedrooms, living areas, EPC scores, image URLs and agency contact details. Perfect for market analysis

Pricing

from $1.20 / 1,000 results

Rating

5.0

(2)

Developer

Muhamed Didovic

Muhamed Didovic

Maintained by Community

Actor stats

1

Bookmarked

35

Total users

8

Monthly active users

9 days ago

Last modified

Share

Immoweb.be Scraper

Immoweb Scraper - How It Works

The fastest, cheapest, most accurate Immoweb.be scraper on Apify β€” $1.20 per 1,000 listings, 50+ items/minute on residential proxies, and exact maxItems compliance with no overshoot. Whether you're monitoring rental markets, tracking sale prices, or building a property database for Flanders, Wallonia, or Brussels, this scraper delivers complete, structured data in JSON or CSV.

"From houses and apartments to office blocks and investment projects, we turn Immoweb's real estate data into your competitive advantage."

Why this scraper

FeatureThis actorTypical competitor
Price per 1,000 listings$1.20$1.50–$4.00
Locale support (en / fr / nl / de input URLs)βœ… auto-normalized❌ English only
Project sub-unit expansion (house_group)βœ… opt-in❌
Stale-listing fast-fail (no 60-retry waste on 404s)βœ…βŒ
Exact maxItems (no over/undershoot)βœ… atomic cap❌ usually overshoots
Periodic status heartbeat in logsβœ… every 10s❌ logs go silent on stuck fetches
Live per-item dataset pushβœ…varies
Single actor handles both search URLs and direct listingsβœ…many split into two paid actors
Project listings (HOUSE_GROUP / APARTMENT_GROUP)βœ…rarely supported

Supported Inputs

The scraper accepts a mix of URLs in startUrls. Any Immoweb locale is fine β€” French, Dutch, German, or English URLs are auto-normalized internally.

βœ… Supported:

  • Search Pages: https://www.immoweb.be/en/search/house/for-sale?countries=BE&page=1
  • French search: https://www.immoweb.be/fr/recherche/appartement/a-louer?countries=BE&maxPrice=700
  • Dutch search: https://www.immoweb.be/nl/zoeken/huis/te-koop?countries=BE&minPrice=300000
  • Filtered Searches: https://www.immoweb.be/en/search-3-rooms/house/for-rent/bruxelles/district
  • Direct Listings: https://www.immoweb.be/en/classified/office-block/for-rent/houthalen-helchteren/3530/21064580
  • Project Listings: https://www.immoweb.be/en/classified/house_group/for-sale/poperinge/8970/21513540

❌ Not Supported:

  • User account dashboards or saved favorites (/my-immoweb/)
  • URLs outside the immoweb.be domain

Quick Start

  1. Open the actor on Apify, paste one or more URLs into startUrls, set maxItems, click Run.
  2. Wait. Items stream into the dataset live β€” you don't have to wait until the run finishes to start downloading.
  3. Export as JSON, CSV, Excel, HTML, or RSS.

Input Configuration

{
"startUrls": [
"https://www.immoweb.be/fr/recherche/appartement/a-louer?countries=BE&maxPrice=700&postalCodes=1000,1050,1180",
"https://www.immoweb.be/en/classified/house_group/for-sale/poperinge/8970/21513540"
],
"maxItems": 100,
"locale": "fr",
"expandProjectUnits": true,
"maxConcurrency": 10,
"maxRequestRetries": 60,
"proxy": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"]
}
}

Notable input fields

  • locale (en / fr / nl / de, default en) β€” language for SEOUrl in each output record. Input URLs in any locale are accepted regardless.
  • expandProjectUnits (boolean, default false) β€” when a project listing (HOUSE_GROUP / APARTMENT_GROUP) is scraped, also export each of its sub-units as separate dataset records. Sub-units count toward maxItems.
  • maxItems β€” strict cap. The scraper exits exactly at this count, never one over. Tested at 1, 5, 10, 15, 30, 33, 75, 90, 100, 120 β†’ 0 overshoot across all values.
  • maxConcurrency (default 10) β€” how many listings to fetch in parallel.
  • maxRequestRetries (default 100) β€” per-request retry budget. Stale 404 CLASSIFIED_NOT_FOUND responses skip immediately instead of consuming the budget.

Sample Output

{
"id": 21064580,
"url": "https://www.immoweb.be/en/classified/office-block/for-rent/houthalen-helchteren/3530/21064580",
"original_request_url": "https://www.immoweb.be/en/classified/office-block/for-rent/houthalen-helchteren/3530/21064580",
"SEOUrl": "https://www.immoweb.be/en/ad/office-block/for-rent/houthalen-helchteren/3530/21064580",
"customers": [
{
"id": 1248059,
"type": "AGENCY",
"email": "info@agency.be",
"phoneNumber": "+3211800000",
"name": "Vestio",
"website": "http://www.vestio.com",
"location": {
"country": "Belgium",
"province": "Limburg",
"locality": "Hasselt",
"postalCode": "3500",
"street": "20 Kolonel Dusartplein"
},
"ipiNo": "206808",
"isOwner": true
}
],
"media_pictures": [
{ "smallUrl": "...", "largeUrl": "...", "extralargeUrl": "..." }
],
"property_type": "OFFICE",
"property_subtype": "OFFICE_BLOCK",
"property_title": "Flexibele kantoorruimtes in bedrijvencentrum",
"property_location_country": "Belgium",
"property_location_region": "Flanders",
"property_location_locality": "Houthalen-Helchteren",
"property_location_postalCode": "3530",
"property_location_latitude": 51.0256269,
"property_location_longitude": 5.3723637,
"property_hasLift": true,
"transaction_type": "FOR_RENT",
"price_mainValue": 34,
"publication_creationDate": "2025-10-03T10:04:27.998Z",
"publication_lastModificationDate": "2026-04-13T18:38:28.747Z"
}

Each record has 60–120+ flattened fields depending on the listing type. Nested objects are flattened with _ separators so they fit cleanly into CSV / Excel columns.

Performance

Measured locally on Apify residential proxies, maxConcurrency=10, broad Belgian house search:

maxItemsWall timeItems / minute
517 s18
3021 s86
7572 s63
10094 s64
12081 s89

A specific French rental URL with 73 unique listings: 73 items in 94 seconds (47 items/min) end-to-end including pagination, mobile-API fetches, and dataset export.

Output Fields Reference

This section provides a detailed breakdown of all key fields. The output is flattened so nested objects fit cleanly into CSV/Excel columns.

Core Listing Details

  • id (Number): Internal Immoweb listing ID.
  • url (String): The direct URL to the listing.
  • original_request_url (String): The URL the user supplied (or the search page where this listing was discovered).
  • SEOUrl (String): Canonical localized URL (language controlled by the locale input field).

Agency / Customer Details

  • customers (Array): Real estate agency or seller details.
    • type (String): Usually "AGENCY".
    • email, phoneNumber, name, website β€” direct contact info.
    • location (Object): Agency address (country, province, locality, postalCode, street).
    • ipiNo (String): Belgian BIV/IPI license number.
    • isOwner (Boolean): Whether the agency owns the listing directly.

Media

  • media_pictures (Array): Image URLs at smallUrl, mediumUrl, largeUrl, extralargeUrl resolutions.
  • media_virtualTourUrl (String|null), media_floorPlans (Array|null), media_documents (Array).

Property

  • property_type, property_subtype β€” e.g. HOUSE / HOUSE_GROUP, APARTMENT / FLAT_STUDIO, OFFICE / OFFICE_BLOCK.
  • property_title, property_description.
  • property_bedroomCount, property_bathroomCount, property_roomCount.
  • property_netHabitableSurface (mΒ²).
  • property_monthlyCosts.

Location

  • property_location_country, property_location_region, property_location_province, property_location_district, property_location_locality, property_location_postalCode, property_location_street, property_location_number.
  • property_location_latitude, property_location_longitude (GPS).

Building & Construction

  • property_building_condition (e.g. GOOD, AS_NEW, TO_RENOVATE).
  • property_building_constructionYear, property_building_facadeCount, property_building_floorCount.
  • property_hasLift, property_constructionPermit_isObtained.

Features

  • property_hasGarden, property_gardenSurface.
  • property_hasTerrace, property_terraceSurface.
  • property_hasSwimmingPool, property_hasAirConditioning.
  • property_kitchen_type (e.g. HYPER_EQUIPPED, INSTALLED).
  • property_parkingCountIndoor, property_parkingCountOutdoor.

Energy / EPC

  • property_energy_epcScore (A, B, ... G).
  • property_energy_heatingType (GAS, ELECTRIC, PELLET, ...).
  • property_energy_primaryEnergyConsumptionPerSqm (kWh/mΒ²/year).

Transaction & Pricing

  • transaction_type (FOR_SALE, FOR_RENT), transaction_subtype.
  • price_mainValue (€), price_type.
  • flags_isNewlyBuilt, flags_isPublicSale, flags_isUnderOption.

Publication & Statistics

  • publication_creationDate, publication_lastModificationDate (ISO 8601).
  • statistics_viewCount, statistics_bookmarkCount.

Project-Specific (when property_type is HOUSE_GROUP or APARTMENT_GROUP)

  • cluster_projectInfo_groupId, cluster_projectInfo_name, cluster_projectInfo_totalHousingUnitsCount.
  • cluster_priceRange_min, cluster_priceRange_max.
  • cluster_surfaceRange_min, cluster_surfaceRange_max.
  • cluster_bedroomCountRange_min, cluster_bedroomCountRange_max.
  • cluster_units (Array): each unit type group with its individual sub-units (each has its own id).
  • Use expandProjectUnits: true to also export each sub-unit as a separate record.

FAQ

How does this avoid getting blocked? The scraper fetches data through Immoweb's own structured JSON endpoints rather than scraping HTML pages. The success rate on the first attempt is high; a small retry loop with proxy rotation handles transient failures. The HTML page is used only as a fallback when the JSON endpoint returns unexpected data.

What does the flattened output look like? Nested properties like property: { location: { street: "Main St" } } are flattened into single-level keys: property_location_street: "Main St". Arrays (like media_pictures) remain as lists.

Can I mix search URLs and direct listings? Yes β€” put any combination into startUrls. The scraper detects each URL type automatically. You can also mix locales: a French search URL alongside an English direct listing works fine.

What is expandProjectUnits? Immoweb's "house_group" or "apartment_group" entries represent new-build developments. By default the scraper exports one record per project (with a cluster_units array containing the sub-unit IDs). When expandProjectUnits is true, the scraper also fetches each sub-unit individually and exports it as its own record. Useful when you want every house in a development as a separate row.

Does maxItems actually stop exactly at the cap? Yes. The cap reservation is atomic (single-threaded JS), so concurrent in-flight fetches can't push past the limit. Tested at 1, 5, 10, 15, 30, 33, 75, 90, 100, 120 β€” zero overshoot. Several competing actors silently overshoot by up to maxConcurrency-1 items per run.

What happens to listings that have been removed? A 404 CLASSIFIED_NOT_FOUND response triggers an immediate skip (single log line, no retries). This is especially important for project sub-units, which can go stale faster than regular listings. Competing actors typically retry 60 times per stale ID, burning proxy budget and run time.

The run looks stuck β€” how do I tell? Status heartbeat lines fire every 10 seconds regardless of what's happening: [internal-handler-impit] status queue=N (listing=X search=Y) active=Z queuedListings=Q exported=E/maxItems. If active is non-zero and exported is incrementing, the run is healthy. If you see no change across multiple heartbeats, a fetch is wedged β€” wait or abort.

Why am I still getting blocked? For high-volume scraping use Apify's Residential Proxies (apifyProxyGroups: ["RESIDENTIAL"]). Datacenter proxies are flagged by Belgian real estate sites.


Integrations & Webhooks

The actor stores results in the default dataset, accessible via:

  • Direct download: JSON, CSV, Excel, HTML, RSS from the Apify Console.
  • Apify API: programmatic access to the dataset.
  • Built-in webhooks (Apify platform): configure in Apify Console β†’ Actor β†’ Integrations β†’ Webhooks. Apify will POST to your URL on ACTOR.RUN.SUCCEEDED, ACTOR.RUN.FAILED, or ACTOR.RUN.ABORTED with run metadata (run ID, dataset ID). Your endpoint can then fetch the dataset.
  • Custom completion webhook (this actor): set completionWebhookUrl in input β€” see below.
  • Pre-built integrations: Google Sheets, Slack, Email, Zapier, Make, Airtable.

Custom completion webhook (completionWebhookUrl)

If you set the completionWebhookUrl input field, the actor POSTs a rich JSON payload to that URL when the run finishes (success or failure). Compared to Apify's built-in webhooks this payload includes the item count, a property-type breakdown, a sample record, and a sanitized echo of your input β€” so you can decide whether to fetch the full dataset without a second round-trip.

Retries: up to 3 attempts with 1s/3s backoff. Timeout: 15s per attempt. All webhook errors are logged and swallowed β€” they cannot fail or stall the actor run.

Example payload:

{
"status": "SUCCEEDED",
"actorRunId": "UgKgANdBaGOHiy29J",
"actorId": "7hrExNTiDRs0nPUXh",
"userId": "ngn8vRESTkseyWE6p",
"defaultDatasetId": "...",
"startedAt": "2026-05-27T20:50:11.000Z",
"finishedAt": "2026-05-27T20:51:45.000Z",
"durationSeconds": 94,
"itemCount": 100,
"breakdown": {
"byPropertyType": { "APARTMENT": 97, "APARTMENT_GROUP": 3 },
"byTransactionType": { "FOR_SALE": 100 }
},
"sample": {
"id": 21597303,
"SEOUrl": "https://www.immoweb.be/fr/annonce/rez-de-chaussee/a-vendre/braine-le-comte/7090/21597303",
"property_type": "APARTMENT",
"price_mainValue": 285000,
"...": "(full first record, ~90 fields)"
},
"inputSummary": {
"startUrls": ["https://www.immoweb.be/en/search/apartment/for-sale?countries=BE&orderBy=newest"],
"maxItems": 100,
"locale": "fr",
"expandProjectUnits": false
}
}

On failure, status is "FAILED" and an "error" field contains the message. itemCount and breakdown reflect whatever was exported before the failure β€” so partial runs are still useful to your downstream system.

Receivers that work out of the box:

  • Make / Zapier / n8n webhook triggers
  • Slack incoming webhook (pipe breakdown.byPropertyType into a chat message)
  • Your own service (itemCount β†’ decide whether to pull the dataset)

Explore More Scrapers

If you found this scraper useful, check out the rest at memo23's Apify profile. We build scrapers for a wide range of platforms.

Support

Additional Services