How to Scrape Imovirtual Portugal Real Estate Data (2026)
Extract Portuguese property listings from Imovirtual — prices, €/m², T-typology, full address and agency data — via its embedded Next.js JSON. No API key.
Imovirtual.com is one of Portugal’s largest property portals and part of the OLX Group, with hundreds of thousands of active listings from Lisboa and Porto down to the Algarve. There’s no open public listings API, so building a Portuguese real-estate dataset usually means scraping the site — and if you go at the rendered HTML, you’ll fight a moving DOM and mild bot protection for every field. Imovirtual is built on Next.js, though, which means every search page ships its full listing data as a server-side JSON blob embedded in the page. Read that blob and you get clean, structured records without rendering a browser. This guide covers what’s in that payload, how the location model works, and the friction you’ll actually hit.
What’s worth extracting
Imovirtual’s embedded __NEXT_DATA__ payload carries a rich record per listing. The useful fields group into a few clusters:
- Pricing —
price(headline price),priceCurrency(EUR),pricePerSqm(€/m²), andmonthlyRent(the recurring rent for rentals, returned separately from the headlineprice). - Physical attributes —
areaSqm(surface area),terrainAreaSqm(plot area),rooms(parsed from the Portuguese T-typology),floorandtotalFloors. - Full Portuguese address —
province(distrito),county(concelho / município),city(freguesia / city label),district(bairro) andstreet. On detail pages,postalCode,latitudeandlongitudeare also available, plus a composedfullAddress. - Classification —
propertyType,estate(the raw enum:FLAT,HOUSE,TERRAIN,COMMERCIAL_PROPERTY,HALL,GARAGE,ROOM,INVESTMENT),market(PRIMARYnew-build orSECONDARYresale),transactionTypeandadvertType. - Agency & owner data —
agencyId,agencyName,agencySlug,agencyLogoUrl,agencyType,contactName, andisPrivatefor direct-owner listings. - Listing flags —
isExclusive,isFeatured,isPromoted,hasOpenDay, plusdevelopmentNameandinvestmentStatefor primary-market projects. - Media & timestamps —
mainImageUrl,imageUrls,imageCount,totalPossibleImages,dateCreated,dateCreatedFirstandpushedUpAt(last bump). - Amenities —
labels, an array of feature tags such asAIR_CONDITIONING,BALCONY,PARKING_SPOT.
For a €/m² study you need price, areaSqm and the address fields. For yield work you also want monthlyRent. The labels array and market flag let you segment by amenity or by new-build vs. resale without extra requests.
How the source actually works
Imovirtual belongs to the same OLX Group platform family as Otodom (Poland) and shares the same Next.js server-side rendering model. Each search results page embeds its listing data in a __NEXT_DATA__ script tag. The scraper fetches the page over plain HTTP, parses that JSON, and emits one row per listing — no browser, no GraphQL token, no DOM walking.
Locations are addressed through URL slugs that follow Portugal’s administrative hierarchy (distrito → concelho → freguesia):
- District:
lisboa,porto,faro,braga,setubal - Council:
lisboa/cascais - Parish:
lisboa/cascais/cascais-e-estoril - All of Portugal:
todo-o-pais
To find a slug, browse imovirtual.com, apply a location filter, and copy the path between /resultados/{transaction}/{type}/ and the ? in the URL. A realistic run — Lisbon and Porto apartments for sale — looks like this:
{
"locationSlugs": ["lisboa", "porto"],
"transaction": "sale",
"propertyType": "apartment",
"priceMin": 200000,
"priceMax": 600000,
"areaMin": 50,
"areaMax": 120,
"roomsMin": 2,
"roomsMax": 3,
"market": "SECONDARY",
"ownerType": "ALL",
"sort": "latest",
"limit": 72,
"maxListings": 500,
"maxPagesPerTask": 10,
"requestDelay": 800,
"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "PT" }
}
Each entry in locationSlugs becomes its own task, so you can benchmark several cities in one run and every row is tagged with its searchLocation. Property types cover apartment, house, plot, commercial, warehouse, garage, room, development and studio. The distanceRadius option (0, 5, 10, 15, 25, 50 or 75 km) expands a search into neighboring areas, and limit sets page size to 24, 36, 48 or 72.
▶ Run the Imovirtual Scraper on Apify — one run pulls thousands of Portuguese listings with price, €/m², T-typology, full district/council/parish address and agency data. No API key, no login. Export to JSON, CSV, Excel or XML.
The access reality
No key or login is required, but Imovirtual deploys mild bot protection, so a few things matter:
- Datacenter IPs get blocked. Plain datacenter proxies frequently draw a block. Residential Apify Proxy with
apifyProxyCountry: "PT"is strongly recommended for reliable access. - Pace requests. Keep
requestDelayat 600 ms or higher. The scraper runs cleanly at that pace; faster invites throttling. - Rotate on failure.
maxRetriesrotates the proxy IP on HTTP errors so a transient block doesn’t kill the whole task. - Deep pagination needs narrowing. Imovirtual paginates large filter sets, but the deepest inventory is easier to reach by narrowing with price and area filters than by paging endlessly through one broad query. Split by price band or drill into a council slug for dense markets.
- GPS and postal code are detail-page only. The search-results JSON gives you the full administrative breakdown (
province/county/city) but not exact coordinates.latitude,longitudeandpostalCodepopulate on detail pages. If you don’t need door-level positioning, the parish-level address is enough for most analysis.
The reason not to scrape the rendered HTML is the same as with any Next.js site: the listings you want are already in the page as JSON before the DOM finishes hydrating. Parsing __NEXT_DATA__ is both faster and far more stable than chasing CSS selectors that change with every front-end release.
Example output
One representative record (trimmed) from a Lisbon sale search:
{
"adId": "68812345",
"detailUrl": "https://www.imovirtual.com/pt/anuncio/apartamento-t2-lisboa-...",
"title": "Apartamento T2 · Lisboa, Alvalade",
"transactionType": "sale",
"propertyType": "apartment",
"estate": "FLAT",
"market": "SECONDARY",
"price": 385000,
"priceCurrency": "EUR",
"pricePerSqm": 5138,
"areaSqm": 75,
"rooms": 2,
"province": "Lisboa",
"county": "Lisboa",
"city": "Alvalade",
"advertType": "AGENCY",
"agencyId": "12345",
"agencyName": "Prime Imobiliária",
"isExclusive": true,
"labels": ["BALCONY", "AIR_CONDITIONING", "PARKING_SPOT"],
"dateCreated": "2026-07-03",
"scrapedAt": "2026-07-06T12:00:00Z"
}
Use cases
What Portuguese property data at this granularity supports:
- €/m² market research — build price-per-square-meter heatmaps by distrito, concelho and freguesia.
pricePerSqmis already parsed per listing. - Investment screening — scrape both
saleandrent, then compute rental yield (monthlyRentagainst comparableprice) per area, from Lisboa and Porto to the Algarve. - Lead generation — set
ownerType: "PRIVATE"to find direct-owner listings, or cluster agency listings byagencyIdto map the most active agencies in a market. - Price and activity tracking — re-run on a schedule and diff against prior datasets using
dateCreatedandpushedUpAtto detect price changes and re-listings. - Primary-market monitoring — use
propertyType: "development"ormarket: "PRIMARY"to track new developer offers and theirinvestmentState. - Cross-city comparison — pass multiple
locationSlugsin one run to benchmark prices and inventory across Portuguese cities.
Build-it-yourself vs. managed actor
Parsing __NEXT_DATA__ yourself is feasible — the payload is right there in the HTML. What accumulates:
- Portuguese residential proxy. Datacenter IPs get blocked, so you need a residential PT pool (a few hundred dollars a month for a decent one). The managed actor bundles Apify residential proxy and charges per row.
- Slug and pagination handling. You’ll replicate the distrito/concelho/freguesia slug logic and the pagination cursor, and keep them working as the site evolves.
- T-typology parsing. Portuguese listings encode bedroom count as
T0–T10; you need to parse that into a numeric field. The actor already maps it intorooms. - Rotation and retry. Getting IP rotation to fire on the right responses at a polite pace is the usual time sink.
The managed actor is pay-per-result — a few thousand listings across several cities lands in the low single dollars including proxy. The real saving is skipping the reverse-engineering of the OLX-family payload shape and the proxy tuning before you see your first clean row.
Common pitfalls
Specific gotchas for Imovirtual data:
- Rent lives in a separate field. For rentals, read
monthlyRent, not justprice. Branch ontransactionTypebefore aggregating so you never mix rents into sale-price averages. - T-typology counts bedrooms, not rooms. T2 means two bedrooms, not two total rooms —
roomsreflects the T-number. Filter withroomsMin/roomsMaxaccordingly and don’t confuse it with total-room counts from other portals. estatevs.propertyType.propertyTypeis the friendly type;estateis the raw enum (FLAT,HOUSE,TERRAIN, …). If you’re joining across sources, key on the raw enum, which is stable.- Coordinates require detail pages. Don’t expect
latitude/longitudeorpostalCodefrom a results-page scrape — those are detail-page fields. Useprovince/county/cityfor spatial grouping. - Promoted/featured listings repeat.
isPromotedandisFeaturedads can appear at the top of multiple pages. Dedup onadIdso a boosted listing isn’t counted several times. - Primary-market listings differ. New-build (
PRIMARY) entries may carry adevelopmentNameandinvestmentStateand behave differently from resale stock — segment onmarketbefore you compare prices.
Wrapping up
For a single city snapshot, parsing __NEXT_DATA__ with a Portuguese residential IP is a reasonable weekend project. For a refreshed, multi-region Portuguese property feed — for yield models, market dashboards or agency lead lists — a managed actor that already solves the slug model, proxy and rotation problems will get you to clean rows in minutes instead of days.
▶ Open the Imovirtual Scraper on Apify — reads Imovirtual’s embedded
__NEXT_DATA__JSON to return price, €/m², T-typology, full Portuguese address, agency data and image galleries per listing. No API key, no login, residential-PT proxy ready. Export to JSON, CSV, Excel or XML. Start on Apify’s free monthly credit.
Related guides
EU Company Registry Data Export — Germany, France, Netherlands
How to extract company-registry records from Handelsregister, INPI, and KvK in a unified schema — for KYC, B2B lead generation, and compliance workflows.
How to Scrape Allabolag.se Sweden Company Leads in 2026
Extract Swedish company data from allabolag.se — org number, revenue, CEO, phone and email — without an API key. A guide to bulk firmographics and B2B leads.
How to Scrape the Australia Business Register (ABN/ABR)
Bulk-export Australian business names, ABNs, status and registration dates from the official data.gov.au CKAN register — no API key, no browser, no captcha.