NewSearch millions of jobs from your AI agent with MCP
All posts
ComparisonJobSpy
Comparison·Jul 13, 2026·7 min read

JobSpy review: the Python job scraper tested, and where it breaks

JobSpy scrapes Indeed, LinkedIn, Glassdoor, ZipRecruiter and Google with one Python call - until it gets blocked. An honest review, and the no-scraper path: JobsPipe's free tier and keyless sandbox for normalized postings.

Dvir Atias

Dvir Atias

Founder, JobsPipe

JobSpy is the most popular open-source job scraper in the Python ecosystem: one pip install python-jobspy, one function call, and you get postings from Indeed, LinkedIn, Glassdoor, ZipRecruiter, Google, and more back as a pandas DataFrame. We build a commercial jobs API, so we are exactly the vendor you’d expect to trash it. We’re not going to - JobSpy is genuinely good at what it is for. This review covers what it does well, where it breaks, and how to make the scraper-vs-API call honestly.

What JobSpy does well

The core loop is hard to beat for exploratory work:

from jobspy import scrape_jobs

jobs = scrape_jobs(
    site_name=["indeed", "linkedin", "zip_recruiter", "glassdoor"],
    search_term="data engineer",
    location="Austin, TX",
    results_wanted=100,
)
print(jobs.head())
  • One interface over many boards. The same call shape works across every supported site, and results land in a DataFrame ready for analysis.
  • Free and open source. For a student project, a one-off market analysis, or a weekend prototype, the cost argument ends here.
  • Actively maintained. The project keeps pace with board layout changes better than most scraping libraries, and the proxy support is built in rather than bolted on.

Where it breaks

  • Blocking, immediately at scale. LinkedIn rate-limits unauthenticated scraping within a few hundred results; Indeed and Glassdoor run serious bot management. Past toy volumes you are buying rotating residential proxies and babysitting 429s - the costs the “free” framing hides.
  • Query-shaped, not feed-shaped. You get results per search term per location, capped per run. Comprehensive or continuous coverage means enumerating a large query matrix on a schedule you maintain.
  • No dedup, no change tracking. The same role appears on three boards as three rows, and nothing tells you when a posting closed. Both become your code.
  • Maintenance transfers to you. When a board re-skins, your pipeline is down until the library updates and you upgrade. Fine for research; a pager problem in production.

Scraper or API: the actual decision

The decision is not about tool quality - it is about whether the collection layer is your product. If you are running a one-off analysis, learning scraping, or prototyping, JobSpy is the right tool and you should use it. If jobs data feeds something with users, revenue, or an SLA, the DIY pipeline math turns against you fast - we’ve run the numbers for Indeed and Glassdoor, and proxies plus maintenance plus on-call time reliably clears $3,000 a month before opportunity cost.

There is also a structural difference in what you can collect. JobSpy reads consumer job boards. JobsPipe reads the upstream ATS layer - Workday, Greenhouse, Lever, Ashby, and 30+ more - where postings appear first, with stable IDs, structured salary, and webhook delivery on changes:

curl https://api.jobspipe.dev/v1/jobs/search \
  -H "Authorization: Bearer jp_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "job_title_or": ["data engineer"], "posted_at_gte": "2026-07-12" }'

A reasonable path many teams take: prototype the idea on JobSpy, and switch the collection layer to an API when the prototype earns production status.

Skip the proxy bill - normalized postings from 30+ sources, free tier included.

Get a free API key

Skip the scraper - try the API right now

Live, normalized postings from 30+ ATS feeds and job boards in one JSON schema. No key, no signup - this sandbox returns sample data in the exact live shape.

Results

Press Test search to see normalized job records rendered here, and the raw JSON on the right.

JSON responsePOST /v1/sandbox/jobs/search
{
  "job_title_or": [
    "software engineer"
  ],
  "limit": 3,
  "remote": true
}
Advanced: edit the raw request, or copy it as curl
curl -X POST https://api.jobspipe.dev/v1/sandbox/jobs/search \
  -H "Content-Type: application/json" \
  -d '{"job_title_or":["software engineer"],"remote":true,"limit":5}'

For live results, get a free key (1,000 jobs/month) and swap /v1/sandbox/jobs/search for /v1/jobs/search with an Authorization: Bearer header - request and response shapes are identical.

FAQs

Frequently Asked Questions

Is JobSpy free?

Yes, JobSpy is free and open source - you install it with pip install python-jobspy. What the free framing hides is infrastructure cost: past toy volumes you are buying rotating residential proxies and babysitting 429s, because LinkedIn rate-limits unauthenticated scraping within a few hundred results and Indeed and Glassdoor run serious bot management. For a student project, a one-off analysis, or a weekend prototype, free really is free.

Does JobSpy still work?

Yes. JobSpy is actively maintained and keeps pace with board layout changes better than most scraping libraries, with proxy support built in rather than bolted on. One scrape_jobs call pulls from Indeed, LinkedIn, Glassdoor, ZipRecruiter, and Google into a pandas DataFrame. Its limits are operational rather than functional: blocking at scale, query-shaped results capped per run, no dedup, and no change tracking when a posting closes.

When should I use a jobs API instead of JobSpy?

Use an API when jobs data feeds something with users, revenue, or an SLA. JobSpy is the right tool for one-off analyses, learning scraping, and prototypes, and you should use it there. Past that you own the proxies, the query matrix, the dedup, and the downtime when a board re-skins, which reliably clears $3,000 a month before opportunity cost. Many teams prototype on JobSpy and swap the collection layer later.