Documentation Index
Fetch the complete documentation index at: https://mintlify.com/speedyapply/JobSpy/llms.txt
Use this file to discover all available pages before exploring further.
You can filter jobs at two stages: before scraping by passing parameters to scrape_jobs(), and after scraping by querying the returned DataFrame.
Filtering before scraping
These parameters are sent to the job boards and reduce the number of results fetched.
Job type
Use the job_type parameter to restrict results to a specific employment type.
from jobspy import scrape_jobs
jobs = scrape_jobs(
site_name=["indeed", "linkedin"],
search_term="software engineer",
location="New York, NY",
job_type="fulltime",
)
Accepted values: "fulltime", "parttime", "internship", "contract".
Remote jobs
Set is_remote=True to filter for remote positions.
jobs = scrape_jobs(
site_name=["indeed", "linkedin"],
search_term="frontend developer",
location="United States",
is_remote=True,
)
Location and distance
The location parameter accepts a city, state, or country string. The distance parameter sets the search radius in miles (default 50).
jobs = scrape_jobs(
site_name="zip_recruiter",
search_term="nurse practitioner",
location="Boston, MA",
distance=25, # within 25 miles
)
Recency
Use hours_old to return only jobs posted within the last N hours.
jobs = scrape_jobs(
site_name="linkedin",
search_term="product designer",
location="Los Angeles, CA",
hours_old=48,
)
Easy apply
Set easy_apply=True to filter for jobs hosted directly on the job board (i.e. you apply without leaving the site).
jobs = scrape_jobs(
site_name="indeed",
search_term="marketing manager",
location="Chicago, IL",
easy_apply=True,
)
The LinkedIn Easy Apply filter no longer works on LinkedIn’s end. Setting easy_apply=True with site_name="linkedin" has no effect.
Offset
Use offset to start results from the Nth position. This is useful for paginating through results across multiple calls.
# First batch
jobs_1 = scrape_jobs(
site_name="indeed",
search_term="data analyst",
location="Denver, CO",
results_wanted=25,
offset=0,
)
# Second batch
jobs_2 = scrape_jobs(
site_name="indeed",
search_term="data analyst",
location="Denver, CO",
results_wanted=25,
offset=25,
)
Indeed only supports one of the following per search:
hours_old
job_type and/or is_remote
easy_apply
Combining them will not raise an error, but only one filter will take effect.
LinkedIn only supports one of the following per search:
Filtering after scraping
After scrape_jobs() returns a DataFrame, you can use standard pandas operations to further narrow results.
Filter by column value
import pandas as pd
from jobspy import scrape_jobs
jobs = scrape_jobs(
site_name=["indeed", "linkedin"],
search_term="software engineer",
location="Austin, TX",
results_wanted=50,
)
# Remote jobs only
remote_jobs = jobs[jobs["is_remote"] == True]
# Full-time jobs only
fulltime_jobs = jobs[jobs["job_type"] == "fulltime"]
Filter by salary range
# Jobs with a minimum salary above $100,000/year
high_paying = jobs[
(jobs["min_amount"] >= 100_000) & (jobs["interval"] == "yearly")
]
# Jobs within a salary band
banded = jobs[
(jobs["min_amount"] >= 80_000) &
(jobs["max_amount"] <= 150_000) &
(jobs["interval"] == "yearly")
]
Drop duplicates
The same posting can appear on multiple boards. Use job_url or title + company to deduplicate.
# Deduplicate by exact job URL
jobs = jobs.drop_duplicates(subset=["job_url"])
# Deduplicate by title and company (catches cross-board duplicates)
jobs = jobs.drop_duplicates(subset=["title", "company"])
Filter by keyword in title
# Only jobs with "senior" in the title (case-insensitive)
senior_jobs = jobs[jobs["title"].str.contains("senior", case=False, na=False)]
Filter by site
# Only LinkedIn results
linkedin_jobs = jobs[jobs["site"] == "linkedin"]