Serbia Real Estate Scraper — 4zida & Halooglasi avatar

Serbia Real Estate Scraper — 4zida & Halooglasi

Pricing

from $1.50 / 1,000 unique listings

Go to Apify Store
Serbia Real Estate Scraper — 4zida & Halooglasi

Serbia Real Estate Scraper — 4zida & Halooglasi

Scrape Serbian property listings from 4zida.rs and Halooglasi with cross-portal duplicates collapsed into one row per unique flat.

Pricing

from $1.50 / 1,000 unique listings

Rating

0.0

(0)

Developer

Stanislav Shupilkin

Stanislav Shupilkin

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

2

Monthly active users

8 hours ago

Last modified

Categories

Share

Pay for unique listings, not duplicate rows. Serbia's two big property portals are scraped in one run, and the same flat advertised on both of them — by the owner, by three agencies, and once more with a different photo — comes back as one row, with every other posting attached to it. In a live Vračar run 47 raw listings collapsed to 37 unique flats: 21% of what a normal scraper would have billed you for, and then made you deduplicate yourself. Collapsed duplicates are charged at $0.0002 instead of $0.0015, so the cleanup is not just free, it's most of your bill removed.

No browser, no API keys. Give it a city and press start. Halooglasi is fetched through the Apify Residential proxy by default — that is the one moving part, and it is explained under Proxy and Halooglasi below.

What you get

  • Both portals in one dataset4zida.rs and Halooglasi.com, the same fields, the same shape, already merged.
  • Cross-portal deduplication — the hard part. Matching is done on metadata (price, area, rooms, floor, distance, street) and on the perceptual hash of the cover photo, so a repost with a rewritten title and a different price still lands in the same row.
  • Every duplicate's URL kept — the duplicates array shows where else the flat is listed and at what price, which is exactly where you see one agency quoting €5,000 more than the owner.
  • Price per m² computed for you, plus coordinates, municipality, street, floor, seller type (owner or agency) and photo URLs.

Example output

One row is one flat, no matter how many portals were advertising it:

{
"portal": "halooglasi",
"url": "https://www.halooglasi.com/nekretnine/prodaja-stanova/cubura-21m2-renoviran-ta/5425647609842",
"title": "Čubura, 21m2, renoviran, ta",
"price_eur": 84000,
"area_m2": 21.0,
"price_per_m2": 4000,
"rooms": 0.5,
"floor": null,
"floor_num": null,
"floor_total": null,
"municipality": "Vračar",
"address": "Daničareva",
"lat": 44.7982,
"lon": 20.4861,
"deal": "sale",
"property_type": "apartment",
"seller": "agency",
"photos": [
"https://img.halooglasi.com/slike/oglasi/Thumbs/260831/l/cubura-21m2-st-renoviran-ta-5425647609842-71816870839.jpg"
],
"posted_at": "2026-08-31T18:22:52+00:00",
"duplicate_count": 1,
"duplicates": [
{
"portal": "4zida",
"url": "https://www.4zida.rs/prodaja-stanova/crveni-krst-vracar-vracar-beograd/garsonjera/6a959e7a7bfd40f29403ed46",
"price_eur": 84000
}
],
"is_duplicate": false,
"duplicate_of": null
}

That row is from a real run: the same 21 m² studio at €84,000 was on Halooglasi as "Čubura, renoviran" and on 4zida as a "garsonjera" in Crveni krst — two names, two portals, one flat, one row.

Export it as JSON, CSV, Excel or XML, or pull it from the Apify API into your own pipeline.

How to run it

  1. Put a city or a Belgrade municipality into City or municipalityBeograd, Novi Sad, Niš, Vračar, Zemun, Novi Beograd. Serbian diacritics are optional: vracar finds Vračar.
  2. Leave both portals selected. That is where cross-portal duplicates come from — one portal alone still deduplicates agency reposts, but you lose half the point.
  3. Choose sale or rent, the property type, and optional price and area ranges.
  4. Set Max unique listings and run it.

Input

FieldWhat it doesDefault
locationCity or Belgrade municipality to searchBeograd
portals4zida, halooglasiboth
dealTypesale or rentsale
propertyTypeapartment, house, garage, commercialapartment
maxItemsHow many unique objects to output100
minPrice / maxPricePrice range in EUR (both portals quote in EUR)no limit
minArea / maxAreaArea range in m²no limit
includeDuplicatesAlso emit the collapsed duplicates as their own rowsfalse
maxPhotosHow many photo URLs to keep per row5
proxyConfigurationProxy for Halooglasi only (see below)Apify Residential

includeDuplicates changes the shape of the output, never the price: with it off you get one row per flat with a duplicates array; with it on the duplicates get their own rows flagged is_duplicate and pointing at the winner through duplicate_of. Either way you pay per object.

Pricing: pay per event

EventPrice
unique-listing — one unique flat in your dataset$0.0015
duplicate-collapsed — one duplicate found and merged away$0.0002

100 unique flats with 30 duplicates collapsed costs $0.156. The same 130 rows billed as unique listings would have been $0.195 — and you would still have to deduplicate them yourself.

Set a maximum spend on the run and the Actor stops the moment your limit is reached, finishing successfully with everything collected up to that point.

Proxy and Halooglasi

Halooglasi sits behind Cloudflare, and from Apify's datacenter IPs Cloudflare returns a challenge instead of the page — the block is on IP reputation, so a correct browser TLS handshake alone does not get through. The Actor therefore fetches Halooglasi through the Apify Residential proxy, and only Halooglasi: 4zida and every photo (from both portals' CDNs) go direct, because they are never challenged. That keeps paid proxy traffic to the Halooglasi HTML alone.

The trade-off is cost. Residential proxy is billed at $8/GB, and that traffic is paid by the Actor, not added to your per-event bill — it comes out of the developer's margin, so a Halooglasi-heavy run is deliberately kept lean (cover photo only, one request per listing). Your options in proxyConfiguration:

  • Apify Residential (default) — Halooglasi works, cross-portal deduplication works. Recommended.
  • Turn Apify Proxy off — the run drops to 4zida only. No Halooglasi, so nothing to deduplicate across portals; you still get 4zida's own agency-repost dedup. Cheapest, and honest about it.
  • Datacenter group — will almost certainly hit the same Cloudflare block as no proxy at all; not recommended for Halooglasi.

How the deduplication actually works

Two listings become one object when the portals agree on the flat, not on the wording:

  • Geo edge — within 70 m of each other, same floor, same street (where both state one), price within 35%, area within 4 m². On a coordinate where many different flats sit — a shared building entrance or a district centroid the portal falls back to — the area tolerance tightens to 1 m², because proximity there proves nothing.
  • Photo edge — the cover photos have a difference hash within 10 bits of each other and the metadata does not forbid the match. This is what catches listings that carry no coordinates at all, roughly a third of one portal's inventory. A photo shared by more than eight listings is treated as a building facade or a floor plan and ignored.
  • Sanity check — a merged group has to look like one flat: at most two distinct streets, area spread under 10 m², price spread under 1.5×. A group that fails is rebuilt on stricter rules, and if it still fails it is broken apart. Showing one flat twice is better than hiding two.
  • The winner is the most complete card — coordinates, street, area, price, date, most photos — not whoever posted first.

Thresholds come from a deduplication engine tuned on 18,404 live Belgrade listings, not from guesswork.

Limits worth knowing before you run it

  • Only the cover photo is hashed. A repost whose first photo is its own but whose third and seventh match will not be linked by photo — it can still be linked by metadata.
  • Deduplication is per run. The Actor does not remember yesterday's dataset; two separate runs are deduplicated separately.
  • A listing with no price is never merged by metadata alone — there is nothing left to check it against.
  • Halooglasi filters by city, not by municipality. Asking for Vračar fetches Belgrade pages and drops what is not Vračar, so a narrow municipality search costs more requests than a city-wide one.
  • Coordinates are the portal's, and portals sometimes drop a listing on the district centroid instead of the building. That is exactly what the hub rule above exists for.