add scrapers: 88makelaars, Borgdorff (SSR) + Elzenaar, DOEN (OG Online API) for Den Haag
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -307,6 +307,135 @@ def fetch_vandaal() -> list[RawListing]:
|
||||
return listings
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Elzenaar NVM Makelaars (Den Haag) — OG Online platform
|
||||
# ---------------------------------------------------------------------------
|
||||
# Zelfde platform als bjornd/moerman/vandaal.
|
||||
|
||||
_ELZENAAR_BASE = "https://www.elzenaar.com"
|
||||
_ELZENAAR_SKIP = {"rented", "rented_ur"}
|
||||
_ELZENAAR_CITIES = {"Den Haag", "Voorburg", "Rijswijk"}
|
||||
|
||||
_ELZENAAR_STATUS_MAP = {
|
||||
"available": "beschikbaar",
|
||||
"under_bid": "onder_bod",
|
||||
"under_option": "onder_bod",
|
||||
"sold": "verkocht",
|
||||
"sold_ur": "verkocht",
|
||||
}
|
||||
|
||||
|
||||
def fetch_elzenaar() -> list[RawListing]:
|
||||
data = fetch_json(
|
||||
f"{_ELZENAAR_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 _ELZENAAR_SKIP:
|
||||
continue
|
||||
if item.get("city") not in _ELZENAAR_CITIES:
|
||||
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=_ELZENAAR_BASE + item["url"],
|
||||
source_makelaar="elzenaar",
|
||||
status=_ELZENAAR_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("elzenaar: %d koopwoningen opgehaald", len(listings))
|
||||
return listings
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# DOEN NVM Makelaars (Den Haag / Leiden / Voorburg) — OG Online platform
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
_DOEN_BASE = "https://www.doenmakelaars.com"
|
||||
_DOEN_SKIP = {"rented", "rented_ur"}
|
||||
_DOEN_CITIES = {"Den Haag", "Leiden", "Voorburg", "Leidschendam", "Rijswijk", "Wassenaar", "Zoetermeer"}
|
||||
|
||||
_DOEN_STATUS_MAP = {
|
||||
"available": "beschikbaar",
|
||||
"under_bid": "onder_bod",
|
||||
"under_option": "onder_bod",
|
||||
"sold": "verkocht",
|
||||
"sold_ur": "verkocht",
|
||||
}
|
||||
|
||||
|
||||
def fetch_doen() -> list[RawListing]:
|
||||
data = fetch_json(
|
||||
f"{_DOEN_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 _DOEN_SKIP:
|
||||
continue
|
||||
if item.get("city") not in _DOEN_CITIES:
|
||||
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=_DOEN_BASE + item["url"],
|
||||
source_makelaar="doen",
|
||||
status=_DOEN_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("doen: %d koopwoningen opgehaald", len(listings))
|
||||
return listings
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# SCRAPERS — exporteer hier alle actieve API adapters
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -316,4 +445,6 @@ SCRAPERS = {
|
||||
'ooms': fetch_ooms,
|
||||
'moerman': fetch_moerman,
|
||||
'vandaal': fetch_vandaal,
|
||||
'elzenaar': fetch_elzenaar,
|
||||
'doen': fetch_doen,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user