Nationale Vacaturebank Jobs Scraper avatar

Nationale Vacaturebank Jobs Scraper

Pricing

Pay per event

Go to Apify Store
Nationale Vacaturebank Jobs Scraper

Nationale Vacaturebank Jobs Scraper

Scrape Nationale Vacaturebank (nationalevacaturebank.nl) job listings by keyword: title, employer, city and province, contract type, salary range, working hours, education level, dates, full text and vacancy URL. Deduplicated rows.

Pricing

Pay per event

Rating

0.0

(0)

Developer

DevilScrapes

DevilScrapes

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Categories

Share

Devil Scrapes mark

Nationale Vacaturebank Jobs Scraper

💰 $3.00 / 1 000 vacancies  ·  plus a $0.20 start fee per run  ·  pay per vacancy delivered

The devil's in the data. 😈

Pull job listings from Nationale Vacaturebank (nationalevacaturebank.nl), one of the biggest Dutch job boards, as clean, deduplicated rows: title, employer, city and province, contract type, salary range, working hours, education and career level, dates, the full vacancy text and the public vacancy URL. Search by one keyword or many, and let us page through the results for you.

🎯 What this scrapes

Nationale Vacaturebank lists tens of thousands of Dutch vacancies and offers no anonymous export. This Actor runs a keyword search (for example python or verpleegkundige), walks the result pages 100 vacancies at a time, and returns one row per vacancy: the vacancy id and URL, title and normalised function title, employer (name, slug, type), work location (city, municipality, province, postal code, coordinates), contract type, salary minimum, maximum and period when the advert states one, working hours per week, education level, career level, categories, industries, start, end and expiry dates, the apply link, the source feed and the full vacancy text as HTML and as plain text. Each row also records the keyword that found it and the total number of vacancies the site reports for it.

🔥 Features

  • 🛡️ We rotate browser fingerprints (curl-cffi Chrome, Firefox and Safari profiles) when a request is refused, so the retry looks like a different browser.
  • 🔁 We retry with exponential backoff on rate limits and server errors, honouring Retry-After. Up to 5 attempts per page.
  • 🌐 We rotate Apify Proxy sessions on every retry, with a fresh exit each time.
  • 🧊 Run-wide deduplication. The same vacancy id never appears twice in your dataset, across pages or across keywords in one run.
  • 🧱 Fault isolation. A page that cannot be read after its retries is skipped and the walk continues; one keyword that fails doesn't end the others. The status message tells you what was skipped.
  • 💶 Structured salary. Minimum, maximum and period are separate numeric fields, and stay null when the advert does not state a salary.
  • 📝 Full text on tap. Switch includeDescription off for a lighter dataset.

💡 Use cases

  • Recruiters and staffing agencies: watch who is hiring for a role, and where, across the Netherlands.
  • Labour-market analysts: measure vacancy volume, contract mix, salary bands and required education per keyword and province.
  • Job aggregators: feed fresh Dutch vacancies into your own board.
  • HR-tech and salary teams: track demand for a skill over time with a scheduled run.

⚙️ How to use it

  1. Add one or more search terms to keywords, for example python and verpleegkundige.
  2. Set maxPages (100 vacancies per page) and maxItems to bound how much you pull.
  3. Run it, then export to JSON, CSV, or Excel, or pull the dataset straight from the Apify API.

📥 Input

FieldTypeRequiredDefaultNotes
keywordsarray<string>yesnoneJob titles, skills or employers. Blanks and duplicates are dropped.
maxPagesintegerno3Result pages per keyword, 100 vacancies each (1-100).
maxItemsintegerno100Hard cap on total rows across the run (1-10000).
includeDescriptionbooleannotrueInclude the full vacancy text (HTML and plain text).
proxyConfigurationobjectyesApify ProxyDatacenter by default; see Limitations.

Example input

{
"keywords": ["python", "verpleegkundige"],
"maxPages": 2,
"maxItems": 150,
"includeDescription": true,
"proxyConfiguration": { "useApifyProxy": true }
}

📤 Output

One row per deduplicated vacancy.

FieldTypeNotes
jobIdstringVacancy UUID, dedupe key.
urlstring | nullPublic vacancy URL on nationalevacaturebank.nl.
title / functionTitlestringVacancy title and normalised function title.
company / companySlug / companyType / companyWebsitestring | nullEmployer or recruiter.
city / municipality / province / postalCode / street / countrystring | nullWork location.
latitude / longitudenumber | nullWork location coordinates.
contractType / contractTypesstring | null / arraye.g. Vast, Tijdelijk, Stage.
salaryMin / salaryMax / salaryTypenumber | null / string | nullNull when the advert states no salary.
workingHoursMin / workingHoursMaxnumber | nullHours per week.
educationLevel / educationLevels / careerLevelstring | null / arraye.g. WO, HBO, Ervaren.
categories / industriesarray<string>Site categories and industries.
startDate / endDate / expirationDatestring | nullISO 8601 UTC.
applyUrl / applyOptionstring | nullWhere and how to apply.
origin / referenceId / recruiterIdstring | nullSource feed identifiers.
numberOfAppliesinteger | nullApplications counted by the site.
description / descriptionTextstring | nullVacancy text as HTML and as plain text.
searchKeywordstringKeyword that found the vacancy.
totalResultsinteger | nullVacancies the site reports for that keyword.
pageNumber / positioninteger1-based page and position within the page.
sourcestringnationalevacaturebank.
scrapedAtstringUTC ISO-8601 run timestamp.

Example output record

{
"jobId": "4eedbe40-20f4-4c43-8b74-8b8ac205d627",
"url": "https://www.nationalevacaturebank.nl/vacature/4eedbe40-20f4-4c43-8b74-8b8ac205d627/data-scientist",
"title": "Data Scientist",
"company": "Stedin",
"companyType": "direct_employer",
"city": "Rotterdam",
"province": "Zuid-Holland",
"country": "Nederland",
"contractType": "Vast",
"salaryMin": 5085.0,
"salaryMax": 5085.0,
"salaryType": "monthly",
"workingHoursMin": 40.0,
"workingHoursMax": 40.0,
"educationLevel": "WO",
"careerLevel": "Ervaren",
"startDate": "2026-10-12T22:00:00Z",
"endDate": "2026-12-11T23:00:00Z",
"origin": "jobdigger",
"searchKeyword": "python",
"totalResults": 813,
"pageNumber": 1,
"position": 1,
"source": "nationalevacaturebank",
"scrapedAt": "2026-10-13T08:00:00Z"
}

💰 Pricing

Pay-Per-Event: you pay only when these events fire.

EventUSDWhat it is
actor-start$0.20One-off start charge per run
result-emitted$0.003Per deduplicated vacancy written to the dataset

Example: 1 000 rows = $3.20 per run ($0.20 start + 1000 x $0.003). The start charge applies to every run, including one that matches nothing. No subscription, no minimum.

🚧 Limitations

  • Keyword search only. Location, category and salary filters are not offered yet.
  • Overlapping keywords overlap. A vacancy matching two keywords is returned once, under the first keyword that found it.
  • Live ordering moves. Results are sorted newest first, so a new vacancy landing mid-run can shift the list; we dedupe by id, so a page may bring fewer new rows.
  • Salary is advert-dependent. Many vacancies state none; those rows carry null.
  • Datacenter proxy by default. If the site starts refusing it, switch proxyConfiguration to a residential group with a Dutch exit.
  • A keyword with no vacancies is a success. It finishes with zero rows and a status message naming what was searched.

❓ FAQ

Do I need a Nationale Vacaturebank account or API key? No. This reads the public vacancy search.

How many vacancies can I pull per keyword? As many as maxPages x 100, up to what the site lists for the keyword. The totalResults column tells you the keyword's full size.

Why did my run return fewer rows than maxItems? Either the keyword has fewer vacancies than your cap, maxPages stopped the run first, or another keyword already returned the same vacancies. The status message says which.

What happens if a page is blocked? We retry up to 5 times with a fresh browser fingerprint and proxy session each time. If a page still can't be read it is skipped and counted in the status message. The run ends as failed only when a keyword was blocked and nothing at all could be collected.

Can I run this on a schedule? Yes. Use Apify Schedules to re-run your keywords daily and catch newly posted vacancies.

💬 Your feedback

Found a bug, or need a field we don't return yet? Open an issue on the Actor's Issues tab. We read every one.