Scrape normalized sale and rent listings from Funda.nl, the leading Dutch property portal. Get clean price, living area, energy label, room counts, and photo data per listing while we handle blocks, retries, and fingerprint rotation for you.
Initial local-green build (T02–T11, T13) on top of the T01 scaffold and
T12 icon. Single-market Actor for funda.nl (Netherlands), sale (koop)
and rent (huur), summary (enrich=False) and full-detail
(enrich=True) modes.
src/config.py — search/detail URL templates, koop/huur slug map,
kenmerken Dutch-label map, and the load-bearing listing_id_from_url
rule (REQ-9): the numeric ID always comes from the detail-page URL
path, never the page's own ld+json internal id, which the spec
confirms can diverge on the same page.
src/geo_guard.py — single-marker geo-splash guard (www.funda.nl
host + lang="nl prefix) — funda.nl has no og:locale meta tag,
unlike idealista-property-scraper's two-marker table.
src/parser.py — pure ld+jsonItemList search extraction with
card-text price/area regex, Product/BreadcrumbList + kenmerken
dt/dd detail-page merge, REQ-9 regression-tested against a fixture
whose URL-path ID deliberately diverges from its ld+json internal id.
src/scraper.py — FundaSession (one curl-cffi session per run,
impersonation-profile + session rotation on 408/429/503/network
error/challenge page/geo-guard mismatch, exponential backoff 2s→30s
capped, max 5 attempts), REQ-8's two fault-isolation granularities
(page-fetch-exhausted-retries continues to the next page; a
genuinely-empty page stops pagination; a bad listing is skipped),
max_results pagination stop (REQ-16), run-wide dedup by listing_id
(REQ-14).
src/main.py — SDK wiring, country_code="NL" pinned as a literal
module constant (REQ-10, never read from input), actor-start/
result-row PPE charging, zero-rows-across-the-run fail-loud
(REQ-13) with a raw-HTML KVS dump for debugging.
tests/fixtures/input.qa.json authored (not executed — local-green
scope gate, Apify account over its $5/mo cap until 2026-08-15).
README.md (Devil Scrapes brand voice, 10 canonical H2 sections,
names both incumbents — easyapi/funda-nl-scraper,
ivanvs/funda-scraper) and promo.json (GTM manifest).
104 unit tests, all local — ruff check clean, pyright clean.
Deferred to publish time (on/after 2026-08-15, per the account's
budget cap): apify push, apify call, cloud QA. No cloud/network
calls were made building this Actor.