eyayaw
  • about
  • research
  • blog
  • til
  • my setup

Contents

  • Installation
  • A first rake
  • Descriptions and other details
  • Using jobrake from Python
  • What if …?
  • Appendix
    • Output formats
    • Place name resolution
  • View source
  • Edit this page
  • Report an issue

jobrake for the job

package
jobrake
python
cli
A simple CLI tool & Python package for raking job postings off LinkedIn & Indeed
Author

Eyayaw Beze

Published

September 7, 2026

I’ve been looking for a simple tool for getting new job postings from job boards, because I was tired of doomscrolling on the LinkedIn Jobs tab. Oh yeah, [sg]etting job alerts is equally overwhelming.1

Who to blame, but I’ve not found any that is “reliable”, simple, and free.2

Tip

I spend bonkers amount of time trying to “automate” my job search, but less on actually searching. So, heed my advice on this matter. 😅

So jobrake () is an ambitious attempt to address these challenges.

It’s a simple CLI tool and Python package that fetches job postings from Indeed and LinkedIn and returns every result as the same small Job dictionary. There is no login, no browser automation, just simple requests via httpx.

I intend jobrake to be simple and light3. It searches, normalizes, and returns jobs. That is it. It helps you swing the rake at the big piles—LinkedIn and Indeed. So, currently, it does not support other boards such as Glassdoor or ZipRecruiter.

Installation

jobrake is not on PyPI so install it from GitHub with uv. Please read the installation guides for your system.

I assume unix-based systems hereafter, sorry Windows-(or dare I say WSL-) people, you’re on your own—read the uv docs, adapt all the code wherever necessary; you can do it!

I personally use jobrake through the CLI, so you can install it as a tool, too. uv installs jobrake and adds it to your ${PATH}.

uv tool install git+https://github.com/eyayaw/jobrake
# For ephemeral use
# uvx git+https://github.com/eyayaw/jobrake

A first rake

Say you’re an economist looking for data science roles in the Netherlands, just like me4.

Code
jobrake linkedin \
        --query "economist OR data scientist" \
        --location "amsterdam, netherlands" \
        --max-age 24 \
        --results 5 \
        --output data/jobs-linkedin.csv \
        --details 2>/dev/null
Code
jobrake indeed \
        -q "economist OR data scientist" \
        -c "netherlands" \
        -l "amsterdam" \
        -a 24 \
        -n 5 \
        -o data/jobs-indeed.json 2>/dev/null

Note: If you’re new to CLI lingo, left and right are the same interface twice: long flags spelled out for LinkedIn, and their short aliases for Indeed. Remove the redirect (2>/dev/null) to see progress updates and other info.

Expand for the results
  • LinkedIn
  • Indeed
Code
# The first three rows, some fields, description truncated
duckdb --markdown <<quack
select
    date,
    title: printf('[%s](%s)', title, url),
    company: printf('[%s](%s)', company, company_url),
    location,
    employment_type,
    applicants,
    description: regexp_replace(description, '\s+', ' ', 'g')[:500] || '...'
from 'data/jobs-linkedin.csv'
order by date desc
limit 3;
quack
date title company location employment_type applicants description
2026-09-07 Data Scientist i4talent detachering Amsterdam, North Holland, Netherlands full_time 25 Als Data Scientist bij i4talent werk je aan opdrachten bij organisaties in de Randstad. Je verdient tussen de €3.500 en €5.720 bruto per maand en komt in dienst bij i4talent, terwijl je als consultant werkt aan voorspellende modellen, machine learning, Python en cloudomgevingen zoals Azure of AWS. Je werkt op projecten waar data echt verschil kan maken. Denk aan forecasting, klantgedrag, risicoanalyse, optimalisatie of automatisering. Wij kijken samen welke opdracht past bij jouw ervaring, inter…
2026-09-07 Short Term Forecasting Data Scientist Eneco Rotterdam, South Holland, Netherlands full_time 25 Good to know: you can easily save this vacancy using the print button at the top of the page. After the closing date, this vacancy will be removed from our website. Combine operational responsibility with long-term data science and forecasting projects Develop and improve forecasting products that directly support short-term energy trading Work closely with traders in a fast feedback environment, where you monitor performance, answer questions, and resolve incidents Why choose Eneco? The energy …
2026-09-07 Senior Data Science Consultant Sia Rotterdam, South Holland, Netherlands full_time 25 Sia is a next-generation, global management consulting group born digital, augmented by data, enhanced by creativity, and driven by responsibility. We partner with clients to resolve challenges and capitalize on opportunities. We believe that in today’s world of change and disruption, optimism is a force multiplier. Job Description To support its development, Sia is recruiting senior consultants within its data science team whose vocation will be to take charge, in synergy with our different pra…
Code
# The first three jobs, all fields, description truncated
echo '```json'
duckdb -json <<quack | jq
select * replace (regexp_replace(description, '\s+', ' ', 'g')[:500] || '...' as description)
from 'data/jobs-indeed.json'
order by date desc
limit 3;
quack
echo '```'
[
  {
    "site": "indeed",
    "id": "2911e6df5f3ebd6e",
    "url": "https://nl.indeed.com/viewjob?jk=2911e6df5f3ebd6e",
    "title": "Commercial Data & AI Lead",
    "company": "Schuberg Philis",
    "location": "Schiphol, NH, NL",
    "date": "2026-09-07",
    "description": "Helping organizations turn data ambition into decisions they can stand behind The Commercial Data & AI Lead at Schuberg Philis is a commercially driven technologist who bridges proposition strategy and customer execution. Embedded in Greater Customer Teams (GCTs), the Commercial Data & AI Lead translates customer challenges into compelling, standardized data and AI solutions, accelerates sales cycles through technical expertise, and ensures that what we propose is both desirable for customers an...",
    "company_url": "https://nl.indeed.com/cmp/Schuberg-Philis",
    "company_logo": "https://d2q79iu7y748jz.cloudfront.net/s/_squarelogo/256x256/44e5b2f3c02ec88d3444a9c6e2e00c00",
    "city": "Schiphol",
    "region": "NH",
    "country_code": "NL",
    "latitude": 52.27497,
    "longitude": 4.750813,
    "posted_at": "2026-09-07 05:00:00",
    "apply_url": "https://schubergphilis.com/careers/7652253003?greenhouse=1&gh_jid=7652253003",
    "employment_type": null
  },
  {
    "site": "indeed",
    "id": "a4e73cd1582140e9",
    "url": "https://nl.indeed.com/viewjob?jk=a4e73cd1582140e9",
    "title": "Data Consultant",
    "company": "Incentro",
    "location": "Utrecht, UT, NL",
    "date": "2026-09-07",
    "description": "Wil jij niet alleen met data werken, maar vooral begrijpen wat een organisatie nodig heeft en hierover adviseren? Hoe zorg je ervoor dat cateringbedrijven precies genoeg maaltijden bereiden zonder onnodige verspilling? Hoe optimaliseer je een logistiek netwerk zodat vrachtwagens minder kilometers rijden? Of hoe help je een organisatie om AI-ready te worden met een stevig datafundament? Dit zijn voorbeelden van vraagstukken waar jij als Data Consultant bij Incentro mee aan de slag kunt. Data comb...",
    "company_url": "https://nl.indeed.com/cmp/Incentro",
    "company_logo": "https://d2q79iu7y748jz.cloudfront.net/s/_squarelogo/256x256/78dcf2090eeff9c0e3df827d29eb63fe",
    "city": "Utrecht",
    "region": "UT",
    "country_code": "NL",
    "latitude": 52.06974,
    "longitude": 5.076462,
    "posted_at": "2026-09-07 05:00:00",
    "apply_url": "https://careers.incentro.com/jobs/8328148-data-consultant",
    "employment_type": "part_time"
  },
  {
    "site": "indeed",
    "id": "c7e5ba843602ed0e",
    "url": "https://nl.indeed.com/viewjob?jk=c7e5ba843602ed0e",
    "title": "Model & Governance Specialist Anti-Financial Crime",
    "company": "ASN Bank",
    "location": "Utrecht, UT, NL",
    "date": "2026-09-07",
    "description": "Plaats Utrecht Werktijden 36 uur Education HBO € 5.179,72 € 6.906,29 Als Model & Governance Specialist bij ASN Bank in Utrecht draag jij bij aan verantwoorde AI-inzet tegen financiële criminaliteit, met impact op mens én maatschappij. Wat ga je doen Jij speelt een sleutelrol in het verantwoord ontwikkelen en beheren van AI-modellen binnen het Anti-Financial Crime domein. Met jouw kennis van AI, modelrisico's en wet- en regelgeving zorg jij ervoor dat innovatie én integriteit hand in hand gaan. J...",
    "company_url": "https://nl.indeed.com/cmp/Asn-Bank",
    "company_logo": "https://d2q79iu7y748jz.cloudfront.net/s/_squarelogo/256x256/8384201f53ab16ae688d4779f9f5a1b6",
    "city": "Utrecht",
    "region": "UT",
    "country_code": "NL",
    "latitude": 52.09083,
    "longitude": 5.12222,
    "posted_at": "2026-09-07 05:00:00",
    "apply_url": "https://werkenbij.asnbank.nl/nl/nl/job/6977/Model-Governance-Specialist-Anti-Financial-Crime",
    "employment_type": "full_time"
  }
]

By default, results are compact JSON on stdout:

Code
jobrake linkedin \
-q "data scientist" \
-l "london, england" -n 5 2>/dev/null \
| jq -r '"```json\n\(.)\n```"'
[{"site":"linkedin","id":"4460492939","url":"https://uk.linkedin.com/jobs/view/data-scientist-or-senior-data-scientist-at-hoare-lea-4460492939","title":"Data Scientist or Senior Data Scientist","company":"Hoare Lea","location":"London Area, United Kingdom","date":"2026-09-03"},{"site":"linkedin","id":"4437696372","url":"https://uk.linkedin.com/jobs/view/data-scientist-ai-advanced-analytics-public-sector-at-ibm-4437696372","title":"Data Scientist - AI & Advanced Analytics (Public Sector)","company":"IBM","location":"London, England, United Kingdom","date":"2026-09-03"},{"site":"linkedin","id":"4451513631","url":"https://uk.linkedin.com/jobs/view/data-scientist-maidenhead-%C2%A340-45k-at-solas-it-recruitment-4451513631","title":"Data Scientist - Maidenhead (£40-45k","company":"Solas IT Recruitment","location":"Maidenhead, England, United Kingdom","date":"2026-09-02"},{"site":"linkedin","id":"4463387995","url":"https://uk.linkedin.com/jobs/view/data-scientist-at-clearscore-4463387995","title":"Data Scientist","company":"ClearScore","location":"London, England, United Kingdom","date":"2026-09-04"},{"site":"linkedin","id":"4459327487","url":"https://uk.linkedin.com/jobs/view/data-scientist-maidenhead-%C2%A340-45k-at-solas-it-recruitment-4459327487","title":"Data Scientist - Maidenhead (£40-45k)","company":"Solas IT Recruitment","location":"Maidenhead, England, United Kingdom","date":"2026-09-02"}]

Descriptions and other details

Every job result includes the same identity and summary fields, with null for unavailable summary values. Detail fields appear only when the job board supplies a value5. This keeps the common fields predictable, while keeping optional details compact.

The two sites differ in how much info they display upfront. Indeed includes every supported detail field in its search results. However, LinkedIn search cards contain only basic summaries, so jobrake “hydrates” them—fetches each posting page—when you ask for details such as the job description with --details | -d:

jobrake linkedin \
  -q "economist" \
  -l "amsterdam, north holland, netherlands" \
  -d

The difference also affects speed. Indeed searches are fast because we use its mobile app API. LinkedIn’s guest search API is rate-limited, so jobrake uses a token bucket to pace requests. The LinkedIn scraper takes longer by design, so keep blinking at the progress bar.6

jobrake caches fetched details in your user cache directory. Repeated searches can reuse those details. If the cache is missing or damaged, jobrake fetches them again. Use --no-cache to disable caching.

Using jobrake from Python

Add it to your project dependencies with uv.

# create a .venv (uv venv .venv) or init a project uv init
uv add git+https://github.com/eyayaw/jobrake

The package entry point is asynchronous:

import asyncio

from jobrake import scrape


async def main():
    jobs = await scrape(
        "indeed",
        query="data scientist",
        country="netherlands",
        location="amsterdam",
        results=10,
    )

    for job in jobs:
        print(job["date"], job["title"], job["company"])

asyncio.run(main())

What if …?

WarningA caveat

Breaking in no time: Scrapers do not make promises, right? 🙃 jobrake pings unofficial(ly) (api) endpoints and relies on small HTML markups, so it lives at the mercy of LinkedIn and Indeed. Changes of API endpoints or markups can break it any day. If a request fails, it’s probably them, not us. File an issue, and offer fixes.

The code is available at github.com/eyayaw/jobrake.

Happy searching, I mean, raking!


Appendix

Output formats

Explicit output-format selection:

jobrake ... --format json
jobrake ... -f jsonl
jobrake ... -f csv

Files still infer their format from the extension.

jobrake ... -o jobs.csv
jobrake ... -o jobs.jsonl

An explicit --format overrides that inference, i.e., you can do -f jsonl -o jobs.txt but you get JSON Lines in a .txt file.

Place name resolution

jobrake can also resolve place names from the CLI. LinkedIn needs an unambiguous location to return results. Look up the place first, then use its display name in your search:

jobrake places linkedin "amsterdam"
# Then search with -l "Amsterdam, North Holland, Netherlands"

For Indeed, include the country:

jobrake places indeed -c netherlands "amsterdam"

Footnotes

  1. Indeed’s interface is annoying as hell anyway.↩︎

  2. I tried jobspy for some time. However, the API is unstable and bundles unnecessary downstream dependencies such as pandas and numpy. Unfortunately, it also appears not actively maintained. Nonetheless, jobrake owes a lot to jobspy.↩︎

  3. It depends on httpx and beautifulsoup. I leave it to you if you need downstream poking with the job search data with pandas and co. I had to point this because jobspy depends on lots of such packages.↩︎

  4. Btw, seriously looking for a job. Hire me.↩︎

  5. However, if you request CSV via --format csv or --output jobs.csv, all fields appear as columns.↩︎

  6. Hey, let’s talk LinkedIn at its own pace, as slow as we can. 😅 As they say, “If you want to go fast, go alone. If you want to go far, go together.”↩︎

© 2026 Eyayaw Beze | እያያው ተካ

  • View source
  • Edit this page
  • Report an issue

Made with ❤️ + R + Quarto