<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Tidy Data]]></title><description><![CDATA[Tidy Data]]></description><link>https://tidydata.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Thu, 12 Nov 2026 08:19:09 GMT</lastBuildDate><atom:link href="https://tidydata.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to monitor new Nordic job postings automatically (NAV, Platsbanken, EURES)]]></title><description><![CDATA[If you are looking for work in Norway, Sweden, Finland or Denmark, or you recruit there, you probably check several job sites every day. Norway's public…]]></description><link>https://tidydata.hashnode.dev/how-to-monitor-new-nordic-job-postings-automatically-nav-platsbanken-eures</link><guid isPermaLink="true">https://tidydata.hashnode.dev/how-to-monitor-new-nordic-job-postings-automatically-nav-platsbanken-eures</guid><category><![CDATA[Python]]></category><category><![CDATA[automation]]></category><category><![CDATA[webscraping ]]></category><category><![CDATA[jobs]]></category><category><![CDATA[slack]]></category><dc:creator><![CDATA[Tidy Data]]></dc:creator><pubDate>Wed, 04 Nov 2026 19:49:42 GMT</pubDate><content:encoded><![CDATA[<p>If you are looking for work in Norway, Sweden, Finland or Denmark, or you recruit there, you probably check several job sites every day. Norway's public listings live on NAV Arbeidsplassen, Sweden's on Arbetsförmedlingen's Platsbanken, and Finland, Denmark and Iceland publish to EURES, the EU's job portal. Each has its own format, language and search quirks.</p>
<p>In this tutorial we'll set up a daily alert that checks all of them and sends only the <em>new</em> jobs to Slack, a webhook or your e-mail. It takes about ten minutes and no servers.</p>
<p>Full disclosure: I maintain the scraper used here, published on Apify under the name Tidy Data.</p>
<h3>What we're using</h3>
<p>The <a href="https://apify.com/tidy-data/nordic-jobs-scraper">Nordic Jobs Scraper &amp; Alerts</a> Actor on Apify. It reads official public sources only: NAV's public job feed and search, the JobTech open-data API behind Platsbanken, and the public EURES search. There is no login and no browser automation. Every ad comes out in the same schema: title, standardized job title/occupation, employer, location, posted date, deadline, employment type, description and apply link.</p>
<p>Pricing is pay-per-result: $0.90 per 1,000 jobs plus a $0.00005 start fee per run. Apify's free plan includes monthly credit, so a daily alert for a few keywords typically costs nothing at all.</p>
<h3>Step 1: Get an API token</h3>
<p>Create a free Apify account and copy your token from <strong>Console → Settings → API &amp; Integrations</strong>. Store it in an environment variable:</p>
<pre><code class="language-bash">export APIFY_TOKEN=your_token_here
pip install apify-client
</code></pre>
<h3>Step 2: Try a small search</h3>
<pre><code class="language-python">import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("tidy-data/nordic-jobs-scraper").call(run_input={
    "countries": ["NO", "SE"],
    "searchTerms": ["developer"],
    "postedWithinDays": 7,
    "maxItems": 3,
})
for job in client.dataset(run.default_dataset_id).iterate_items():
    print(job["country"], "|", job["title"], "|", job["company"], "|", job["url"])
</code></pre>
<p>(This uses apify-client 3.x for Python. A Node.js and curl version are in the <a href="https://github.com/tidy-data/apify-examples">example repo</a>.)</p>
<p>You'll get lines like <code>NO | Backend Developer | Example Company AS | https://arbeidsplassen.nav.no/...</code>.</p>
<h3>Step 3: Make the keyword match strict</h3>
<p>The job sites' own search is loose. EURES, for example, returns any ad containing "develop" anywhere in the text when you search for "developer", so you'd get construction and finance ads. The Actor's <code>keywordMatch</code> option fixes this:</p>
<ul>
<li><code>"title"</code> (default): keep only jobs whose title, standardized job title or occupation contains your term. Common job words also match their Nordic forms, so "developer" matches <em>utvikler</em>, <em>utvecklare</em>, <em>kehittäjä</em> and <em>udvikler</em>.</li>
<li><code>"fullText"</code>: the term may appear anywhere in the ad.</li>
<li><code>"source"</code>: whatever the source search returns.</li>
</ul>
<p>Jobs that don't match are dropped before they're stored, so you don't pay for them.</p>
<h3>Step 4: Turn it into an alert</h3>
<p>Here is the input for a daily alert:</p>
<pre><code class="language-json">{
  "countries": ["NO", "SE", "FI", "DK"],
  "searchTerms": ["developer", "data engineer"],
  "keywordMatch": "title",
  "location": "Oslo",
  "postedWithinDays": 1,
  "onlyNewJobs": true,
  "alertName": "oslo-developers",
  "slackWebhookUrl": "https://hooks.slack.com/services/XXX/YYY/ZZZ",
  "notifyTopN": 10
}
</code></pre>
<p>What the alert fields do:</p>
<ul>
<li><code>onlyNewJobs</code> + <code>alertName</code>: the Actor remembers which jobs this alert has already delivered and returns only new ones. Use a different <code>alertName</code> for each alert you run.</li>
<li><code>slackWebhookUrl</code>: posts a message with the newest jobs (up to <code>notifyTopN</code>), each linked to its apply page.</li>
<li><code>webhookUrl</code>: POSTs a JSON summary with the full job list (up to 500 jobs, without descriptions). This works with Zapier, Make, n8n, Pipedream or your own server.</li>
<li><code>emailTo</code>: sends an e-mail via Apify's free send-mail Actor. Note that it only delivers to the e-mail address of your own Apify account.</li>
</ul>
<p>Notifications are only sent when a run finds at least one new job, so you won't get empty messages.</p>
<p>Save this input in Apify Console as a <strong>task</strong>, then open <strong>Schedules</strong> and run it daily, for example at 07:00. That's it: each morning you get only the jobs that appeared since yesterday.</p>
<h3>Step 5 (optional): Build a dataset</h3>
<p>For labour-market research, drop <code>onlyNewJobs</code> and raise the limits (<code>maxItemsPerCountry</code>, default 100). In my tests, about 1,000 jobs from four countries with full descriptions took under 3 minutes on 256 MB of memory. Export as JSON, CSV or Excel, or pick fields with the API:</p>
<pre><code>https://api.apify.com/v2/datasets/&lt;DATASET_ID&gt;/items?format=csv&amp;fields=country,title,company,city,postedAt,url
</code></pre>
<h3>A note on personal data</h3>
<p>Job ads often name a contact person with a personal e-mail or phone number. By default (<code>redactContacts: true</code>), e-mail addresses and phone numbers in the text are replaced with <code>[email removed]</code> / <code>[phone removed]</code>. Apply links, company websites and organisation numbers are kept. Contact names can still appear in the ad text, so treat the descriptions with care under GDPR.</p>
<h3>Limitations</h3>
<ul>
<li>Only public-API sources are covered (no LinkedIn).</li>
<li>Occupation fields are less complete for Finland and Denmark than for Norway and Sweden.</li>
<li>Some fields (salary, employment type) are only filled when the source provides them.</li>
</ul>
<h3>Wrap-up</h3>
<p>With one scheduled task you get a single, de-duplicated feed of new Nordic jobs, filtered to what you actually want, in Slack or your own tools. The code is in the <a href="https://github.com/tidy-data/apify-examples">example repo</a>, and the Actor is here: <a href="https://apify.com/tidy-data/nordic-jobs-scraper">https://apify.com/tidy-data/nordic-jobs-scraper</a>.</p>
<p>Feedback and feature requests are welcome in the Actor's Issues tab.</p>
]]></content:encoded></item></channel></rss>