Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

wa-job-scraper — multi-platform job scraper (Pierce/S.King County, WA + WA-hiring private sector)

Scrapes job portals across six platform families: NeoGov, AppliTrack, FastTrack, HRMplus (public sector, browser-driven) and Workday, Greenhouse (private sector, JSON API). Writes structured JSON + markdown output filtered by salary threshold. Includes a fit-scoring command that rates each job against a local candidate profile using haiku subagents.

Install

Requires Bun 1.0+.

bun install
bun playwright install chromium

Quickstart

bun run scrape

Writes to research/<YYYY-MM-DD>-scrape/scraped/ (the research/ dir is gitignored):

  • jobs.json — every job, full shape
  • jobs.md — human-readable all-jobs listing
  • filtered.md — jobs ≥ --min-salary + jobs with unknown salary
  • errors.json — per-portal errors
  • summary.md — per-portal count table

Flags

--out-dir <path>        default: research/<YYYY-MM-DD>-scrape/scraped
--min-salary <n>        default: 100000 (applied by filtered.md)
--include <regex>       case-insensitive title filter (keep matching)
--exclude <regex>       case-insensitive title filter (drop matching)
--portals <file>        path to JSON portal list (default: built-in)
--platforms <list>      comma-separated: neogov,applitrack,fasttrack,hrmplus,workday,greenhouse
--concurrency <n>       per-platform concurrent scrapes, default: 3
--headful               launch browser with UI (debug)
--timeout <ms>          per-navigation default: 30000
-h, --help              show this help

Examples

# Only admin/executive titles, higher threshold
bun run scrape --include "(administrat|coordinator|executive assistant|director)" --min-salary 120000

# Single platform while debugging
bun run scrape --platforms neogov --concurrency 1 --headful

# Custom region via JSON file
bun run scrape --portals ./my-region.json

Extending to a new region

Create a JSON file like:

[
  { "name": "City of Example",  "platform": "neogov",     "url": "https://www.governmentjobs.com/careers/example" },
  { "name": "Example SD",       "platform": "applitrack", "url": "https://www.applitrack.com/exampledistrict/onlineapp" }
]

Each entry needs name, platform (one of: neogov, applitrack, fasttrack, hrmplus, workday, greenhouse), and url. Pass via --portals path.json.

Private-sector portals

Workday portals use https://{tenant}.{region}.myworkdayjobs.com/{site}. Greenhouse portals use https://boards.greenhouse.io/{board_token}. Both adapters filter client-side to WA/Remote locations (Remote is rejected if a non-WA US state is named in the location text).

# Private sector only
bun run scrape --platforms workday,greenhouse --min-salary 135000

Architecture

  • src/config.js — argv parser
  • src/portals.js — built-in portal registry
  • src/lib/types.js — JSDoc typedefs
  • src/lib/browser.js — Playwright wrapper (launchBrowser, withContext)
  • src/lib/salary.jsparseSalary(text) → SalaryRange with period detection + annualization
  • src/lib/output.js — output formatters + writeResults(outDir, ...)
  • src/platforms/{neogov,applitrack,fasttrack,hrmplus,workday,greenhouse}.js — per-platform adapters; each exports scrape(browser, portal, config) → { jobs, errors }
  • src/score.js — fit-scoring CLI (prep / aggregate subcommands)
  • src/score/{prep,aggregate}.js — batching + merging logic
  • src/index.js — orchestrator

Scoring jobs against a candidate profile

Drop resume / skills / targets files into profile/ (gitignored; see profile/README.md for suggested structure).

From within a Claude Code session:

/score-jobs research/2026-XX-XX-scrape/scraped/jobs.json --min-salary 135000

The slash command runs bun src/score.js prep, dispatches haiku subagents in parallel batches of 8 (rides your Claude subscription — no metered API cost), then runs bun src/score.js aggregate. Output is scored.json + scored.md sorted by fit score.

The /score-jobs command ships in .claude/commands/ and runs inside a Claude Code session. Without Claude Code: run prep, send each batch-NNN.md prompt to any LLM, save each reply as response-NNN.json in the out dir, then run aggregate.

Underlying CLI (also usable directly):

bun run score prep --jobs <jobs.json> --profile profile --out .scoring
bun run score aggregate --jobs <jobs.json> --batches .scoring

Testing

bun test                 # pure-function unit tests (salary, output, score)

Adapters have no unit tests — they run against real Playwright / API instances only.

License

MIT. See LICENSE.

About

Multi-platform WA job scraper (NeoGov, AppliTrack, FastTrack, HRMplus, Workday, Greenhouse) with LLM fit-scoring

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages