feat: add scrapers for vandriel, vanherk, vanoord

- vandriel (Schiedam): OG Online API, filtered by city=schiedam
- vanherk (Schiedam): SURE WordPress plugin (card-house), detail page kenmerken
- vanoord (Delft + Schiedam): Elementor WordPress, two filtered listing URLs, rw-object-features-list detail parsing
- makelaars.md: mark all three as done, add TODO for API scraper detail page enrichment

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-11 19:31:08 +02:00
parent 9149d11a06
commit 1011d9cf87
3 changed files with 332 additions and 0 deletions

View File

@@ -436,6 +436,69 @@ def fetch_doen() -> list[RawListing]:
return listings
# ---------------------------------------------------------------------------
# Vandriel Makelaardij (Schiedam) — OG Online / realtime-listings
# ---------------------------------------------------------------------------
_VANDRIEL_BASE = "https://www.vandrielmakelaardij.nl"
_VANDRIEL_SKIP = {"rented", "rented_ur"}
_VANDRIEL_STATUS_MAP = {
"available": "beschikbaar",
"under_bid": "onder_bod",
"under_option": "onder_bod",
"sold": "verkocht",
"sold_ur": "verkocht",
}
def fetch_vandriel() -> list[RawListing]:
data = fetch_json(
f"{_VANDRIEL_BASE}/nl/realtime-listings/consumer",
headers={"X-Requested-With": "XMLHttpRequest"},
)
listings = []
for item in data:
if not item.get("isSales"):
continue
if item.get("statusOrig") in _VANDRIEL_SKIP:
continue
if (item.get("city") or "").lower() != "schiedam":
continue
if item.get("salesPrice", 0) > config.MAX_PRICE:
continue
postcode = (item.get("zipcode") or "").replace(" ", "") or None
perceel = item.get("plotSurface") or None
if perceel == 0:
perceel = None
raw_year = item.get("dateOfConstruction") or ""
bouwjaar = int(raw_year) if raw_year.isdigit() else None
listings.append(RawListing(
url=_VANDRIEL_BASE + item["url"],
source_makelaar="vandriel",
status=_VANDRIEL_STATUS_MAP.get(item.get("statusOrig", ""), "beschikbaar"),
adres=item.get("address") or None,
postcode=postcode,
stad=item.get("city") or None,
prijs=item.get("salesPrice") or None,
woningtype=item.get("type") or None,
woonoppervlak=item.get("livingSurface") or None,
perceeloppervlak=perceel,
kamers=item.get("rooms") or None,
slaapkamers=item.get("bedrooms") or None,
bouwjaar=bouwjaar,
energielabel=item.get("energyLabel") or None,
hero_image_url=item.get("photo") or None,
))
log.info("vandriel: %d koopwoningen opgehaald", len(listings))
return listings
# ---------------------------------------------------------------------------
# SCRAPERS — exporteer hier alle actieve API adapters
# ---------------------------------------------------------------------------
@@ -447,4 +510,5 @@ SCRAPERS = {
'vandaal': fetch_vandaal,
'elzenaar': fetch_elzenaar,
'doen': fetch_doen,
'vandriel': fetch_vandriel,
}