Halooglasi.com Property Scraper — Serbia Real Estate
Pricing
from $2.00 / 1,000 results
Halooglasi.com Property Scraper — Serbia Real Estate
Scrape real estate listings from Halooglasi.com — Serbia's #1 property portal. Extract apartments, houses, land, commercial, garages and rooms (sale or rent) by location, EUR price, m², rooms and owner type. Returns price, area, GPS-ready address, advertiser and image gallery per ad.
Pricing
from $2.00 / 1,000 results
Rating
0.0
(0)
Developer
Logiover
Actor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Halooglasi.com Property Scraper
Scrape real estate listings from Halooglasi.com — Serbia's #1 property portal — into a clean, structured Apify dataset.
This actor extracts apartments, houses, land, commercial space, garages and rooms (sale or rent) by location, transaction type, EUR price, m², rooms and owner type. Each record includes price (EUR), surface area, full Serbian address (city → municipality → district → micro-location), advertiser, image gallery and listing labels.
Features
- 🇷🇸 Serbia-wide coverage — every Halooglasi location slug is supported (Beograd municipalities, Novi Sad, Niš, Kragujevac, etc.).
- 💰 Native EUR pricing with auto-computed
pricePerSqm. - 🏘️ Four-level location chain — city, municipality (
opština), district, and micro-location parsed separately. - 🛏️ Serbian room-count handling in 0.5 increments (
garsonjera,jednosoban,dvosoban,troiposoban, …) returned as both numeric value and Serbian label. - 🏢 Advertiser data — agency name, profile URL, agency ID and owner type (
Agencija/Vlasnik/Investitor). - 🖼️ Image gallery per listing (logo banners auto-filtered).
- 🏷️ Card tier labels (
Premium,Top,VIP, …). - 🛡️ Cloudflare-resilient — direct HTTP fetch via residential proxy with automatic retry on 403/429/503.
- 🔁 De-duplication & loop detection across paginated pages.
Architecture
Halooglasi is a Sitecore + ASP.NET site. Each listing page server-side embeds an inline JS variable carrying the full ad payload:
window.QuidditaEnvironment.serverListData = {Ads: [...], // up to 20 ads per pageTotalCount: 9198,TotalPages: 460,...};
The actor:
- Regex-extracts the
serverListDataJSON blob from the response HTML. - Walks
Ads[]— each ad givesId,Title,RelativeUrl,AdvertiserId, andListHTML. - HTML-entity-decodes
ListHTML(the visible product card markup) and parses withcheerioto extract price (from<span data-value>), area, rooms, floor, location chain, images and advertiser. - De-duplicates by
adIdacross pages and detects pagination loops.
If the JSON envelope is missing (rare), a cheerio-based HTML fallback parses .product-item cards directly.
No browser, no GraphQL, no Cloudflare-bypass tricks — just
got-scraping+cheerioover residential IPs.
Input
| Field | Type | Default | Notes |
|---|---|---|---|
locationSlugs | string[] | ["beograd"] | One slug per task. Examples: beograd, novi-sad, nis, kragujevac, beograd-novi-beograd, beograd-vracar, beograd-savski-venac-beograd-na-vodi, beograd-zvezdara, beograd-vozdovac, beograd-cukarica, beograd-zemun, beograd-palilula, beograd-stari-grad. Find more by browsing halooglasi.com and copying the path between /nekretnine/{txn}/ and ? from the URL. |
transaction | sale | rent | sale | Maps to prodaja / izdavanje. |
propertyType | enum | apartment | apartment (stan) / house (kuća) / land (zemljište) / commercial (poslovni prostor) / garage (garaža) / room (soba). |
priceMin / priceMax | int (EUR) | 0 | 0 = no bound. |
areaMin / areaMax | int (m²) | 0 | 0 = no bound. |
roomsMin / roomsMax | num | 0 | Halooglasi uses 0.5 increments (garsonjera = 0.5, dvosoban = 2, 5+ = 5). 0 = no bound. |
ownerType | enum | all | all / agency / owner / investor. |
sort | enum | latest | latest / price_asc / price_desc / area_asc / area_desc. |
maxListings | int | 200 | Total cap across all tasks. 0 = unlimited. |
maxPagesPerTask | int | 10 | Pagination depth per location (≈ 20 listings per page). Narrow with price/area for deeper inventory. |
requestDelay | int (ms) | 1000 | Inter-request delay. ≥ 800 ms recommended. |
maxRetries | int | 3 | Per-request retries on 403 / 429 / 503 (rotates proxy IP). |
proxyConfiguration | proxy | RESIDENTIAL + RS | Residential proxy strongly recommended — Halooglasi sits behind Cloudflare and datacenter IPs frequently get blocked. Country RS is prefilled. |
Example input
{"locationSlugs": ["beograd-novi-beograd", "beograd-vracar"],"transaction": "sale","propertyType": "apartment","priceMin": 80000,"priceMax": 250000,"areaMin": 40,"areaMax": 80,"roomsMin": 1.5,"roomsMax": 3,"ownerType": "agency","sort": "latest","maxListings": 500,"maxPagesPerTask": 25,"proxyConfiguration": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"],"apifyProxyCountry": "RS"}}
URL pattern (decoded)
https://www.halooglasi.com/nekretnine/{prodaja|izdavanje}-{stanova|kuca|zemljista|...}/{location-slug}?cena_d_from=<int>&cena_d_to=<int>&cena_d_unit=4 ← EUR (RSD = different code)&kvadratura_d_from=<int>&kvadratura_d_to=<int>&kvadratura_d_unit=1 ← m²&broj_soba_order_i_from=<num>&broj_soba_order_i_to=<num>&oglasivac_nekretnine_s=Agencija|Vlasnik|Investitor&order=1|3|4|5|6 ← latest / price asc / price desc / area asc / area desc&page=<N>
Output
One Apify dataset record per listing:
| Field | Type | Description |
|---|---|---|
adId | string | Halooglasi 13-digit listing ID |
detailUrl | string | Full listing URL |
title | string | Listing title |
shortDescription | string | Card-level description snippet |
transactionType | string | sale / rent |
propertyType | string | apartment / house / land / … |
advertType | string | Raw Agencija / Vlasnik / Investitor |
price | number | Total price in EUR |
priceCurrency | string | EUR |
pricePerSqm | number | Price per m² (read from card or computed price / areaSqm) |
areaSqm | number | Usable surface area (kvadratura) |
terrainAreaSqm | number | Plot/terrain area (houses, land) |
rooms | number | 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5 |
roomsLabel | string | garsonjera / jednosoban / dvosoban / troiposoban / … |
floor | string | Floor number/label (III, PR, VPR, …) |
totalFloors | string | Total floors in building |
buildingType | string | Stara gradnja / Novogradnja / … |
heatingType | string | CG / EG / TA / podno / … |
yearBuilt | int | Construction year |
country | string | Srbija |
city | string | City |
municipality | string | Opština |
district | string | District |
microLocation | string | Mikrolokacija (neighborhood) |
street | string | Ulica |
fullAddress | string | Composed street, microLocation, district, municipality, city, Srbija |
latitude / longitude | number | List endpoint does not expose GPS — always null (would need per-ad detail fetch). |
mainImageUrl | string | Cover photo |
imageUrls | string[] | All listing photos (agency logos filtered) |
imageCount | int | Number of listing images |
advertiserId | string | Halooglasi advertiser ID |
advertiserName | string | Advertiser display name |
advertiserUrl | string | Advertiser profile page |
advertiserType | string | Agencija / Vlasnik / Investitor |
isRegistered hasElevator hasParking hasGarage hasTerrace hasBalcony isFurnished | boolean | Detail-only on Halooglasi list endpoint — typically null (would need per-ad detail fetch). |
isExclusive | boolean | True when card carries the Ekskluziva tier tag |
datePosted | string | Most recent post date (when available) |
dateValidFrom | string | Listing valid-from date (when available) |
labels | string[] | Tier tags (Premium, Top, VIP, …) |
searchTransaction searchPropertyType searchLocation searchUrl | string | Echoes of the input search parameters |
scrapedAt | string | ISO-8601 scrape timestamp |
Two dataset views are pre-configured:
- Overview — compact card-style table (ID, type, price, area, rooms, location, advertiser).
- Full Detail — every field above.
Sample record
{"adId": "5425647088741","detailUrl": "https://www.halooglasi.com/nekretnine/prodaja-stanova/fontana-svetao-za-adaptaciju/5425647088741?kid=4","title": "Fontana, svetao, za adaptaciju","shortDescription": "Na prodaju izuzetno svetao stan na jednoj od najtraženijih lokacija – Fontana...","transactionType": "sale","propertyType": "apartment","advertType": "Agencija","price": 220000,"priceCurrency": "EUR","pricePerSqm": 3548,"areaSqm": 62,"rooms": 2,"roomsLabel": "dvosoban","floor": "IX","totalFloors": "9","country": "Srbija","city": "Beograd","municipality": "Opština Novi Beograd","district": "Fontana","microLocation": "Pariske komune","fullAddress": "Pariske komune, Fontana, Opština Novi Beograd, Beograd, Srbija","mainImageUrl": "https://img.halooglasi.com/slike/oglasi/Thumbs/260429/m/fontana-svetao-za-adaptaciju-...jpg","imageCount": 1,"advertiserId": "5587725","advertiserName": "BELIGRAD","advertiserUrl": "https://www.halooglasi.com/oglasi/BELIGRAD","advertiserType": "Agencija","isExclusive": false,"labels": ["Premium"],"searchLocation": "beograd","scrapedAt": "2026-05-05T14:22:17.392Z"}
Important notes
- Cloudflare protection — Halooglasi explicitly blocks several AI crawlers in
robots.txtand serves403from datacenter IPs. Use Apify Residential Proxy with countryRSfor reliable runs (prefilled in input). The actor automatically retries403/429/503responses with a fresh proxy session. - Currency is always EUR (
cena_d_unit=4). Halooglasi does internally support RSD but its UI defaults to EUR. - Room counts are returned both as numbers (
0.5,1,1.5,2,2.5,3,3.5,4,4.5,5) and as Serbian labels (garsonjera,jednosoban,dvosoban,troiposoban, …) for convenience. - Coordinates and feature flags (lift, parking, garage, terrace, balcony, furnished, registered) are populated by Halooglasi's detail endpoint, not the list endpoint this scraper uses. They are kept in the schema (always
nullhere) so downstream consumers can merge in detail-page enrichment if needed. - Pagination cap — Halooglasi displays up to ~9,000 results per location; if you need a deep historical sweep, narrow with
priceMin/priceMax/areaMin/areaMaxranges and run multiple tasks. - Throughput — ~200 listings / ~70 seconds with residential proxy, including Cloudflare retries.
Common location slugs
Beograd municipalities — beograd-novi-beograd, beograd-vracar, beograd-savski-venac-beograd-na-vodi, beograd-zvezdara, beograd-vozdovac, beograd-cukarica, beograd-zemun, beograd-palilula, beograd-stari-grad, beograd-rakovica, beograd-mladenovac, beograd-grocka, beograd-obrenovac, beograd-surcin, beograd-lazarevac, beograd-barajevo, beograd-sopot, beograd-zvezdara-mirijevo
Other major cities — novi-sad, nis, kragujevac, subotica, pancevo, cacak, kraljevo, leskovac, zrenjanin, smederevo, valjevo, vranje, uzice, sabac, sombor, pozarevac, zajecar
To find more, browse a result page on halooglasi.com and copy the slug from the URL between /nekretnine/{txn-type}/ and ?.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
Repeated 403 warnings, 0 results | Datacenter proxy or no proxy | Switch to Residential with country RS |
Two empty pages — stopping early | Filters too narrow for that location | Loosen price/area/rooms or split into multiple tasks |
Pagination loop detected | Halooglasi caps result set ~9k per query | Narrow with price/area ranges to slice the inventory |
floor / totalFloors null on some rows | Listing didn't include a floor feature | Expected — not every Halooglasi ad provides this field |
latitude / longitude always null | List endpoint doesn't expose coordinates | Expected — would require per-ad detail fetch |
License
Apache-2.0