Zonaprop is Argentina's largest property portal, and scraping it is less about parsing than about two constraints that decide whether a run returns anything at all: where your requests come from, and how much of a search the site will actually hand over.
What Zonaprop exposes without a login
Three entities, each with its own field set:
- Property listings — price with currency, expenses, total and covered area, rooms, bedrooms, bathrooms, parking, age in years, layout, orientation, condition, street address, exact coordinates, seller details and media counts.
- New developments — new-build projects, with their own feature set.
- Real estate agencies — profiles, including how many listings each holds.
No account is needed for any of it. What is needed is a proxy, and the reason is not the one people expect.
Step 1 — the proxy country is not optional
Zonaprop sits behind Cloudflare, and Argentine residential IPs are challenged. So a residential proxy is required and it must not be Argentine. Mexico measured best among the options tested and is the default.
Concurrency belongs to the same decision. The default of 3 is where runs measured clean; pushing harder gets sessions challenged, and recovering from a challenge costs more wall-clock time than the extra parallelism saves.
Step 2 — pick one entity type
entityType takes listings, developments or agencies, and it is one per run. That is deliberate: the three have genuinely different fields, so a dataset holding all of them would be one table with most columns empty on most rows. Run it once per type and each download has a single clean shape.
Step 3 — build the search
Either paste Zonaprop search URLs into startUrls, or let the Actor build the search from propertyType, operationType and location. The location slug is Zonaprop's own — capital-federal, palermo, cordoba, gba-norte.
{
"propertyType": "departamentos",
"operationType": "sale",
"location": "palermo",
"maxItems": 200,
"scrapeDetails": true,
"proxyCountry": "mx"
}Step 4 — plan around the coverage ceiling
This is the part that decides whether your dataset means anything. One search URL yields a few hundred results — about 270 — no matter how many properties match it. And Zonaprop's robots.txt is explicit about the compliant depth:
Allow: /*pagina-2.html$
Allow: /*pagina-3.html$
Allow: /*pagina-4.html$
Allow: /*pagina-5.html$
Disallow: /*pagina-*.htmlPages 2 to 5 are allowed and everything deeper is not, which at 30 listings a page caps a compliant crawler at 150 per search URL. Coverage therefore comes from more searches, not deeper ones — the Actor splits a large search into smaller ones by location automatically. Ask for a neighbourhood and an operation and you get near-complete coverage; ask for the whole country and no tool can deliver it.
Reading the output
One row per entity, with three dataset views projecting it for different jobs: overview is everything, location is the geospatial subset, and contacts is the seller subset.
Two fields deserve attention immediately. price_currency is USD or ARS depending on the listing, because this market genuinely quotes both — and no conversion is applied. seller_type carries Zonaprop's own distinction between an agency and a private owner, which decides what the Actor returns for the phone number.
When to turn on detail pages
scrapeDetails adds the publication date, every photo, floor plans, videos, virtual tours and the full description. It costs about ten times a search result, which is why it is off by default.
Turn it on when the description or the photo set is the point — a listings-quality audit, an image pipeline, anything that reads the text. Leave it off when you are building a price or inventory series, because none of the numeric fields need it.
What a run costs
$0.001 per property, $0.001 per development, $0.002 per agency profile, and $0.00001 to start. Two hundred listings is twenty cents. Failed requests go to the key-value store under ERRORS and are never charged.
Because the Actor runs with restricted permissions — it touches only its own default dataset and key-value store, never the rest of your account's storages — everything lands in one dataset, which is also why entity types are separated by run rather than by dataset name.
Three mistakes that waste a run
- An Argentine proxy, or none. The requests get challenged and the run returns little or nothing.
- One broad search with a big cap. You get the portal's first few hundred results, which is not a sample of the market — it is whatever was ranked first.
- Averaging price across currencies. A dollar sale price and a peso rent in the same mean is a number with no meaning.



