Web Scraping Layers for AI & Automation

back to blog

Building a Salary Benchmarking Dataset From Public Job Postings, No Survey Required

ParseBird·19 Aug 2026

Key Takeaways

Can you actually build a usable comp dataset from job postings alone? Yes, with one caveat: only for roles and regions where salary transparency is common or legally required (most US states, the EU by 2026, and any board that surfaces a salaryMin/salaryMax field). It approximates the asking range, not final offer — treat it as a directional benchmark, not a payroll input.

Which sources give structured salary fields instead of free text? YC Jobs, Hiring.cafe, We Work Remotely (in detail mode), and RemoteOK all return numeric salaryMin/salaryMax/currency fields directly — no parsing required. Naukri returns salary as a string ("Not disclosed" is common) and needs its own filter to get transparent listings.

How do you normalize salary across currencies and pay periods? Convert everything to an annualized USD figure before comparing — a Workday listing might be an annual salary, a contract role might be hourly, and Naukri's Indian listings are frequently denominated in Lakhs (units of 100,000 INR), not raw rupees.

Why Job Postings Beat a Compensation Survey for Speed

A Radford or Mercer survey tells you what the market looked like when the data was collected — often a full quarter before you see the report, and gated behind a subscription most seed-to-Series-B companies don't have. Posted salary ranges are the opposite: live, public, and — since California's SB 1162, Colorado's Equal Pay for Equal Work Act, and the EU Pay Transparency Directive pushed employers to disclose ranges upfront — increasingly structured rather than buried in prose.

The tradeoff is real: postings show the offered range, not the accepted offer, and coverage skews toward roles and companies that post publicly rather than filling via referral. It's a directional signal, best used to sanity-check an internal band or catch when your offers have drifted out of market — not to replace a comp survey outright.

Which Actors Give You Structured Salary Data

Four sources return usable numbers with no scraping-your-own-regex-out-of-a-paragraph step:

// yc-jobs-scraper — startup range + equity
{ "title": "Software Engineer", "salaryMin": 125000, "salaryMax": 180000,
  "salaryCurrency": "USD", "equity": "0.25% - 1.00%", "experience": "3+ years" }

// hiring-cafe-scraper — cross-ATS, filterable to transparent-only
{ "title": "Senior Software Engineer, Backend", "seniorityLevel": "Senior Level",
  "salaryMin": 160000.0, "salaryMax": 220000.0, "salaryCurrency": "USD",
  "minYearsExperience": 5, "technicalTools": ["Python", "PostgreSQL", "Kubernetes"] }

// remoteok-jobs-scraper — tag-filterable remote roles
{ "title": "Founding Engineer", "salary_min": 180000, "salary_max": 220000,
  "currency": "USD", "tags": ["python", "react", "aws", "backend"] }

Hiring.cafe Scraper is the strongest single source for this specifically because its onlyTransparentSalaries input flag drops every listing that doesn't publish a real range before you even pull the data — you're not filtering junk out after the fact, you're not paying to scrape it in the first place.

Naukri Jobs Scraper is the outlier worth calling out: India's job market discloses salary far less consistently, so most salary fields come back as "Not disclosed". Use its salaryRange input filter (denominated in Lakhs, e.g. "10to15" for ₹10–15L) to pre-filter for postings that do publish a band, rather than pulling everything and discarding most of it downstream.

Normalizing Currency and Pay Period

Before any role-to-role comparison, get everything into one unit: annualized USD. Two gotchas that will quietly corrupt a dataset if you skip them:

  1. Pay period. A Workday listing's salary.period can be "year" or "hour" — an unconverted hourly contract rate will look like a rounding error next to a six-figure salaried role if you don't multiply it out.
  2. Non-USD currency and non-raw units. Naukri's Lakh-denominated ranges (1 Lakh = 100,000 INR) need both a unit conversion and an FX conversion — do the Lakh-to-INR multiplication before the currency conversion, not after.
const LAKH = 100000;
const FX_TO_USD = { USD: 1, INR: 0.012, EUR: 1.08 }; // refresh periodically

function annualizeUsd(min, max, currency, period = "year", isLakh = false) {
  let lo = isLakh ? min * LAKH : min;
  let hi = isLakh ? max * LAKH : max;
  if (period === "hour") {
    lo *= 2080; // 40hr/week * 52 weeks
    hi *= 2080;
  }
  const fx = FX_TO_USD[currency] ?? 1;
  return { min: Math.round(lo * fx), max: Math.round(hi * fx), currency: "USD" };
}

Building the Benchmark Table

Once every record is annualized to USD, group by normalized title + seniority and take the median of the midpoints — not the mean, which a single outlier equity-heavy YC listing will drag around:

Role (normalized)Sources pulled fromPostingsMedian range (USD)
Senior Backend EngineerHiring.cafe, YC, RemoteOK340$145K – $195K
Founding Engineer (early-stage)YC58$150K – $210K + equity
Remote Frontend EngineerRemoteOK, WWR210$110K – $150K

Refresh this weekly, not quarterly — the entire point of pulling from live postings instead of a survey is that the lag disappears. If you're already running the normalized job feed from aggregating multiple job boards, this is the same pipeline with one more transform step appended, not a separate project.

FAQ

Does this replace a formal compensation survey for legal/compliance purposes? No — pay-equity audits and formal comp bands still need a licensed survey methodology in most jurisdictions. Use posted-range data for market awareness and offer sanity-checks, not as your documented compliance basis.

What if a role has almost no transparent postings in your target market? That's itself a signal — thin structured-salary coverage for a role usually means either low posting volume generally, or a market/industry where disclosure norms haven't caught up yet (this shows up a lot outside the US/EU). Widen the source mix before concluding the benchmark is unreliable.

Browse the rest of the ParseBird actor directory for additional job-board sources by region if you need coverage beyond these four.