DEV Community

Santiago Marcos
Santiago Marcos

Posted on Fully Autonomous

Build a daily LinkedIn job alert in 25 lines of Python (no login, no browser)

Disclosure: I built the scraper used here. It's a paid Apify actor ($1 per 1,000 jobs; Apify's free monthly credit covers a small daily alert). The code below is free and on GitHub.

LinkedIn's job alerts email you a handful of matches whenever LinkedIn decides to. If you want every new posting for a search, in a spreadsheet, once a day, a short script does it.

What you need

  • Python 3 and pip install apify-client
  • A free Apify account and its API token (Settings → API & Integrations)

The script

"""Daily LinkedIn job alert: new jobs only, appended to a CSV.

pip install apify-client
APIFY_TOKEN=... python linkedin_jobs_to_csv.py
Schedule it with cron; with onlyNewJobs on, each run returns only jobs you haven't seen yet.
"""
import csv
import os

from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

run_input = {
    "searchQueries": ["data engineer", "analytics engineer"],
    "location": "United States",
    "datePosted": "day",
    "workplaceTypes": ["2"],  # 1 = on-site, 2 = remote, 3 = hybrid
    "maxJobsPerSearch": 200,
    "onlyNewJobs": True,
}

run = client.actor("santiagomv/linkedin-jobs").call(run_input=run_input)
jobs = list(client.dataset(run["defaultDatasetId"]).iterate_items())

fields = ["postedAt", "title", "company", "location", "salaryMin", "salaryMax",
          "salaryCurrency", "employmentType", "seniorityLevel", "applicants", "url"]
path = "linkedin_jobs.csv"
new_file = not os.path.exists(path)
with open(path, "a", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=fields, extrasaction="ignore")
    if new_file:
        writer.writeheader()
    writer.writerows(jobs)

print(f"{len(jobs)} new jobs added to {path}")
Enter fullscreen mode Exit fullscreen mode

Run it with APIFY_TOKEN=... python3 linkedin_jobs_to_csv.py.

How it works

  • searchQueries + location: one search per keyword, same as LinkedIn's search box. You can also paste LinkedIn search URLs instead.
  • datePosted: "day" + onlyNewJobs: true: the actor remembers the job IDs it already returned (in a key-value store in your own Apify account), so a daily run only appends jobs you haven't seen. Repeats aren't charged.
  • Each row has the full description, parsed salary (min/max/currency/period), applicant count, seniority, employment type and industry. The script keeps a subset of columns; drop fields to keep everything.

Schedule it

0 8 * * * cd ~/jobs && APIFY_TOKEN=... python3 linkedin_jobs_to_csv.py
Enter fullscreen mode Exit fullscreen mode

Or use Apify's built-in scheduler and pull the dataset whenever you like.

No-code version

There's an importable n8n workflow in the repo: a Schedule trigger plus one HTTP Request node. Connect it to Google Sheets, Slack or Gmail.

Tracking specific companies instead?

Many companies post on Greenhouse, Lever, Ashby or Workday career sites, which have public job APIs. That's more reliable than going through LinkedIn. There's an example for that in the repo too (python/career_site_jobs.py).

Caveat

The scraper reads LinkedIn's public, logged-out job pages. LinkedIn's User Agreement restricts automated access, so using it may break their terms and IPs can get blocked. Keep volumes reasonable; you're responsible for how you use it and the data. Not affiliated with LinkedIn.

Repo with Python, Node, cURL and n8n examples: https://github.com/SantiagoMV42/linkedin-jobs-scraper

Top comments (0)