Adondevivir Peru Property Scraper
Pricing
from $0.40 / 1,000 results
Adondevivir Peru Property Scraper
Property listings search across Peru's largest real-estate portal. Structured records: price, area, rooms, address, images and listing URLs. Part of a multi-country real-estate scraper fleet.
Pricing
from $0.40 / 1,000 results
Rating
0.0
(0)
Developer
Philip Kirkbride
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
4 days ago
Last modified
Categories
Share
Navent Real-Estate Scraper (Adondevivir + ZonaProp + Inmuebles24)
A conservative, plain-HTTP Apify Actor that extracts public property listings from the Navent real-estate family across three countries into one normalized dataset. One codebase, two parser dialects, one output contract — per-country Apify records are push-time decisions, not code forks (same pattern as the VTEX fleet in actors/metro-peru-scraper/).
Supported portals
portal | API host | Country | Local currency | Parser dialect |
|---|---|---|---|---|
adondevivir (default) | api.adondevivir.com | PE | PEN | product-dom |
zonaprop | api.zonaprop.com.ar | AR | ARS | realestate-ldjson |
inmuebles24 | api.inmuebles24.com | MX | MXN | realestate-ldjson |
All three lanes were verified live (2026-09-04, issue #25). The portal input determines the API host, country, local currency, parser dialect and search-URL grammar of every record by construction — country/currency/dialect are never inputs. A record's currency is parsed from the listing's own price tag (S//MN/bare $ → the portal's local currency; USD stays USD — dollar pricing is common on PE/AR listings), because the first currency shown on dual-priced PE cards (S/ 2,010,000 · USD 600,000) is the local one.
Access lane
www.<domain> returns 403 (gzip challenge) on all three portals; the api.<domain> subdomain serves the full site over plain HTTP — no proxy, no challenge solving — but requires a browser-grade User-Agent (a generic client UA gets 403 there too). Listing URLs emitted on records use the api subdomain (the verified plain-HTTP lane); the same paths resolve in a browser on www.<domain>.
Two dialects, one schema
The family shares one listado platform ("RPLIS"): identical DOM card markup everywhere, so cards (price, features, location, gallery) are the record base on every portal. The JSON-LD side differs and is dispatched per config:
product-dom(PE) — JSON-LD is an aggregateProduct+ per-listingSellActionblocks (url, title, floor size, structured address, bedroom/bathroom counts). No per-listing image or date exists in PE JSON-LD, soimageUrlcomes from the card andpostedAtisnull.realestate-ldjson(AR/MX) — per-listingRealEstateListing.mainEntity(url, image, publisher name,datePosted) plusApartment-style unit blocks (title, postal address) joined by image URL.postedAtis normalized from US-formattedM/D/YYJSON-LD dates.
Both dialects map into one output schema; tests/test_scraper.py::CrossDialectParityTest guards that the three per-country datasets stay field-for-field compatible.
Search-URL grammar also rides in SITE_CONFIG: Argentina drops the en- infix (departamentos-venta.html, departamentos-alquiler.html) while PE/MX keep it (departamentos-en-venta.html, casas-en-alquiler.html). Pagination is -pagina-N.html on all three.
Input
portal: one of the three slugs above (defaultadondevivir)operation:sale(default) orrentalpropertyType:departamentos(default) orcasasmaxPages: 1–5 search-result pages (30 postings per page)maxResults: 1–200 total listings (default 50)requestDelaySecs: 0.5–10 seconds between page requests (default 1.0)
Exactly these inputs are implemented; tests/test_actor_schemas.py guards the schema ↔ normalize_input() contract (no phantom inputs).
Output
Each dataset item contains the posting id, a composite listingKey (source:id, e.g. zonaprop.com.ar:59132079), the listing URL on the api subdomain (tracking parameters removed), title, price + parsed currency, areaM2 (upper bound for ranges like 100 a 129 m² lote), rooms (Argentinian ambientes; null where the portal lacks the concept), bedrooms (dorm./rec.), bathrooms, parkings, address line, publisher (AR/MX; null on PE, whose cards carry only a logo), postedAt (ISO date on AR/MX; null on PE), image URL, the run's operation/propertyType, and portal/country/dialect/source provenance plus collectedAt. Unavailable fields are null; "Consultar precio" listings carry price: null.
Join on listingKey, never the bare id — posting id spaces overlap across portals of the family.
Local development
uv sync --devPYTHONPATH=src .venv/bin/python -m unittest discover -s tests -v
The dialect fixtures are captured from the live api-subdomain pages (descriptions truncated). Deployment: APIFY_TOKEN=... python tools/navent_fanout_push.py from the repo root — see tools/navent_fanout_push.py --dry-run and docs/FINDINGS.md.
Crawl policy
- Public search pages on the api subdomain only, no login or private APIs
- Maximum five search-result pages per run
- At least 0.5 seconds between page requests; short exponential backoff (2s/4s) on transient transport errors and 429/5xx only
- No anti-bot bypasses (the api lane needs none)