Hoe bouw je een Job Board Aggregator: Bronnen, Deduplicatie en Versheid

Een goede job aggregator bestaat uit drie technische uitdagingen: waar je vacatures vandaan haalt, hoe je ze dedupliceert en hoe je ze vers houdt. Los die op en het scrapen is het makkelijke deel — hier is het stappenplan.

Een job board aggregator is een zoekmachine voor vacatures: het haalt lijsten van veel bronnen en toont ze op één plek. De moeilijke delen zijn niet de HTTP-verzoeken — ze zijn het kiezen van de juiste bronnen, het dedupliceren van dezelfde vacature die op vijf sites verschijnt, en alles vers houden zodat je geen functies toont die vorige maand al vervuld zijn. Krijg die drie goed en je hebt een verdedigbaar product; krijg ze fout en je hebt een verouderde, duplicaatrijke feed die het vertrouwen ondermijnt. Deze gids is het technische stappenplan: bronmix, canonieke deduplicatie, versheid, de jobs SERP vertical en de juridische lijnen om te respecteren. Het is informatief, geen juridisch advies.

Bron niveau 1: openbare ATS eindpunten

De schoonste vacaturegegevens op het internet staan niet op job boards — ze staan op de carrièresites van bedrijven die worden aangedreven door applicant tracking systems, waarvan de meeste gestructureerde JSON blootstellen. Greenhouse, Lever, Ashby, BambooHR, iCIMS, Paylocity en Workday bieden allemaal lijsten die je direct kunt opvragen, zonder HTML-parsing. Een open-source aggregator die van alle zeven haalt, haalt ze parallel op en stemt het aantal werkers af op de snelheidslimieten van elk platform — ongeveer 50 gelijktijdig voor Workday, 30 voor Greenhouse/Lever/iCIMS, 10 voor BambooHR en 5 voor de strengste limieten. Dit niveau geeft je canonieke titels, locaties, salarisschalen en sollicitatie-URL's direct van de werkgever, wat het de ruggengraat van elke serieuze aggregator maakt.

import httpx

# Greenhouse exposes a public board JSON endpoint per company slug
def fetch_greenhouse(slug: str) -> list[dict]:
    url = f"https://boards-api.greenhouse.io/v1/boards/{slug}/jobs?content=true"
    r = httpx.get(url, timeout=20)
    r.raise_for_status()
    jobs = r.json().get("jobs", [])
    return [{
        "source": "greenhouse",
        "external_id": str(j["id"]),
        "title": j["title"],
        "company": slug,
        "location": (j.get("location") or {}).get("name"),
        "apply_url": j["absolute_url"],
        "updated_at": j.get("updated_at"),
    } for j in jobs]

rows = fetch_greenhouse("examplecompany")
print(len(rows), "roles")

Om bedrijven te vinden om te peilen, oogst ATS slugs op schaal van een webindex in plaats van met de hand — het scannen van Common Crawl's URL-archieven voor ATS-domeinpatronen kan tienduizenden bedrijfsidentificaties opleveren. Die ontdekkingscrawl is zelf een scraping-taak; routeer het door een datacenter proxy pool aangezien de index soepel is en snelheid daar belangrijker is dan IP-reputatie.

Bron niveau 2: de jobs SERP vertical

ATS-feeds missen alles wat alleen op aggregator-sites, regionale borden of Google's eigen jobervaring wordt geplaatst. De efficiënte manier om die lange staart te dekken zonder een dozijn borden individueel te scrapen is de jobs SERP vertical — een gestructureerde query die de banen retourneert die Google voor een rol en locatie naar voren brengt, al genormaliseerd. Onze SERP API biedt een jobs vertical naast nieuws, afbeeldingen en winkelen, zodat je rolvermeldingen kunt ophalen op trefwoord en geo als JSON en ze in dezelfde pijplijn kunt vouwen:

import httpx

def fetch_jobs_serp(query: str, location: str) -> list[dict]:
    r = httpx.get(
        "https://api.quantumproxies.io/serp",
        params={"engine": "google_jobs", "q": query,
                "location": location, "api_key": "QP_API_KEY"},
        timeout=30,
    )
    jobs = r.json().get("jobs", [])
    return [{
        "source": "jobs_serp",
        "external_id": j.get("job_id"),
        "title": j.get("title"),
        "company": j.get("company_name"),
        "location": j.get("location"),
        "apply_url": (j.get("apply_options") or [{}])[0].get("link"),
    } for j in jobs]

serp_rows = fetch_jobs_serp("react developer", "Austin, TX")

Voer dezelfde query uit in je doelsteden op een schema en je hebt geo-dekking die geen enkele ATS-feed biedt. Omdat SERP-resultaten per locatie verschuiven, richt je elke query op geo — ons bericht over hoe SERP scraping werkt in 2026 behandelt de geo- en pagineringmechanismen.

Haal de jobs vertical uit de SERP API

Pijplijndiagram dat vacaturegegevens laat zien die afkomstig zijn van ATS API's, jobs SERP en directe borden, vervolgens genormaliseerd, gededupliceerd en ververst
Drie bronlagen voeden één schema; deduplicatie en een versheidsvenster veranderen ruwe lijsten in een betrouwbare aggregator.

Dedupliceren met een canonieke sleutel

Dezelfde vacature verschijnt routinematig op de bedrijfswebsite, twee aggregators en een Google jobs-kaart. Het vier keer tonen is de snelste manier om defect te lijken. De standaardoplossing is een canonieke sleutel: normaliseer en hash de combinatie van functietitel, bedrijf, locatie en — indien beschikbaar — de externe vacature-ID van de bron. Zet alles in kleine letters, verwijder interpunctie en voeg witruimte samen voordat je gaat hashen, zodat "Sr. Software Engineer" en "senior software engineer" samenvallen.

import re, hashlib

def canonical_key(job: dict) -> str:
    def norm(s):
        return re.sub(r"[^a-z0-9]+", " ", (s or "").lower()).strip()
    basis = "|".join([
        norm(job.get("title")),
        norm(job.get("company")),
        norm(job.get("location")),
        (job.get("external_id") or ""),
    ])
    return hashlib.sha1(basis.encode()).hexdigest()

def dedupe(rows: list[dict]) -> list[dict]:
    seen, out = set(), []
    for job in rows:
        k = canonical_key(job)
        if k not in seen:
            seen.add(k)
            out.append(job)
    return out

Versheid is een functie, geen bijzaak

De geloofwaardigheid van een job board is zijn versheid. Twee mechanismen houden het eerlijk: haal elke bron op een schema opnieuw op (elk uur voor ATS-feeds met hoog volume, dagelijks voor de lange staart), en snoei alles wat je niet opnieuw hebt gezien binnen een rollend venster — 30 dagen is een verstandige standaard, korter voor snel bewegende markten. Volg een per-bron laatst-gezien tijdstempel en een dagelijkse telling zodat je kunt zien wanneer een bron stilletjes breekt; een aggregator die zijn eigen volume bewaakt kan een waarschuwing openen zodra de cijfers van een platform van een klif vallen. Onze notitie over het draaien van scrapers als productiesoftware behandelt planning, drift-detectie en alarmering.

De juridische lijnen om te respecteren

Vacaturegegevens zijn waar de scraping-wet echt wordt, omdat berichten persoonlijke gegevens kunnen bevatten (recruiter namen, contactgegevens) en gedetailleerde beschrijvingen auteursrechtelijk beschermd kunnen zijn. De Franse gegevensbeschermingsautoriteit beboette het bedrijf KASPR met €240.000 voor het scrapen van LinkedIn-contactgegevens zonder de juiste toestemming; GDPR-boetes kunnen oplopen tot €20 miljoen of 4% van de wereldwijde omzet, en auteursrechtelijke schadevergoedingen hebben in Amerikaanse zaken $150.000 per werk bereikt. De veiligere houding is structureel: geef de voorkeur aan geautoriseerde ATS-feeds en de jobs SERP boven brute-force login-afgeschermde borden, sla feitelijke velden op (titel, bedrijf, locatie) in plaats van volledige auteursrechtelijk beschermde beschrijvingen opnieuw te publiceren, en verwijder persoonlijke gegevens die je niet nodig hebt. Ons overzicht van de legaliteit van webscraping in 2026 en de LinkedIn compliance saga gaan dieper.

Statistiekenpaneel met zeven ATS-platforms, een 30-dagen versheidsvenster en de KASPR boete van 240.000 euro voor LinkedIn-scraping
Gestructureerde ATS-feeds plus canonieke deduplicatie verslaan brute-force HTML-scraping op kosten, dekking en juridische blootstelling.

Waar proxies passen

De ATS-laag heeft zelden residentiële IP's nodig, maar de ontdekkingscrawl, de SERP vertical en elke directe board scraping wel — Google en de grotere borden beperken op basis van IP en variëren hun resultaten per geo. Routeer die via roterende residentiële proxies met rotatie per verzoek en geo-targeting zodat elke stadsquery uit een bijpassende locatie komt. Houd de lagen gescheiden: goedkope datacenter voor de soepele index, residentieel voor de gevoelige doelen.

Veelgestelde vragen

Wat is een job board aggregator?

Het is een zoekmachine voor vacatures die lijsten verzamelt van veel bronnen — bedrijfs carrièresites, ATS-platforms, andere borden en de jobs SERP — ze normaliseert in één schema, duplicaten verwijdert en ze aan werkzoekenden presenteert op één doorzoekbare plek. Het technische werk zit in sourcing, deduplicatie en versheid, niet alleen het scrapen.

Hoe dedupliceer je vacatures van meerdere bronnen?

Bouw een canonieke sleutel door functietitel, bedrijf, locatie en de externe vacature-ID van de bron te normaliseren en te hashen. Zet alles in kleine letters, verwijder interpunctie en voeg witruimte samen zodat varianten samenvallen. Bewaar het eerste voorkomen en verwijder overeenkomsten. Dit vangt dezelfde rol op die verschijnt op de werkgeverssite, aggregators en Google jobs.

Is het legaal om job boards te scrapen?

Het hangt af van de bron, de gegevens en je jurisdictie. Openbare feitelijke lijstvelden zijn minder risicovol dan persoonlijke gegevens of volledige auteursrechtelijk beschermde beschrijvingen, en het omzeilen van login-muren verhoogt CFAA-achtige blootstelling. Geautoriseerde ATS-feeds en de jobs SERP zijn de schonere routes. Bedrijven zijn zwaar beboet voor het scrapen van persoonlijke gegevens — vraag juridisch advies voor commercieel gebruik.

Hoe vers moeten geaggregeerde vacaturegegevens zijn?

Haal bronnen met hoog volume zoals ATS-feeds elk uur opnieuw op en de lange staart dagelijks, en snoei elke lijst die je niet opnieuw hebt gezien binnen een rollend venster — 30 dagen is een gebruikelijke standaard. Volg een laatst-gezien tijdstempel per vacature en monitor het volume per bron zodat je een gebroken bron kunt vangen voordat gebruikers verouderde rollen zien.

Behandel aggregatie als drie problemen — bronnen, deduplicatie, versheid — en het scrapen wordt een ondersteunend detail. Begin met schone ATS-feeds en de jobs SERP vertical, dedupliceer op een canonieke sleutel, snoei agressief, en houd de gevoelige crawls op roterende residentiële IP's. Dat is het verschil tussen een product dat mensen vertrouwen en een kerkhof van dode links.

Voed je aggregator met de Scraper API