Skip to main content
scrape_jobs() scrapes job data from one or more job boards concurrently and returns the results as a sorted pandas DataFrame.

Signature

Parameters

str | list[str] | Site | list[Site] | None
default:"None"
The job board(s) to scrape. You can pass a single site as a string or Site enum, or a list of either. When None, all supported sites are scraped.Accepted string values: "linkedin", "indeed", "zip_recruiter", "glassdoor", "google", "bayt", "naukri", "bdjobs".
str | None
default:"None"
The job title or keyword to search for. Used by all sites except Google (which uses google_search_term instead).
str | None
default:"None"
The search query used exclusively for Google Jobs. Google requires a very specific query syntax — copy the query string directly from the Google Jobs search box in your browser after applying your desired filters.
The search_term parameter has no effect on Google searches. You must use google_search_term to filter Google results.
str | None
default:"None"
The geographic location to search within. Used by LinkedIn, Indeed, Glassdoor, and ZipRecruiter. For Indeed and Glassdoor, pair this with country_indeed to narrow results to a specific city or state.
int | None
default:"50"
Search radius in miles from the specified location. Defaults to 50 miles.
bool
default:"False"
When True, filters results to remote jobs only.
For Indeed, you can only use one of the following per search: hours_old, job_type + is_remote, or easy_apply. Combining them is not supported.
str | None
default:"None"
Filters results by employment type. Accepted values: "fulltime", "parttime", "contract", "temporary", "internship".
For Indeed, you can only use one of the following per search: hours_old, job_type + is_remote, or easy_apply.
bool | None
default:"None"
When True, filters for jobs that are hosted directly on the job board site (one-click apply). Note that LinkedIn Easy Apply filtering no longer works reliably.
For Indeed, you can only use one of the following per search: hours_old, job_type + is_remote, or easy_apply. For LinkedIn, you can only use one of: hours_old or easy_apply.
int
default:"15"
Number of job results to retrieve per site. For example, if you pass results_wanted=20 with three sites, you may receive up to 60 total results.
All job board endpoints are capped at approximately 1,000 jobs per search, regardless of this value.
str
default:"usa"
The country to search on Indeed and Glassdoor. Pass the country name as a string (e.g., "usa", "uk", "canada", "germany"). See the full list of supported countries.
LinkedIn searches globally and ignores this parameter. ZipRecruiter only searches the US and Canada.
list[str] | str | None
default:"None"
One or more proxy addresses. Each scraper rotates through the list in a round-robin fashion. Supports HTTP, HTTPS, and SOCKS5 proxies.
Proxies are essential for LinkedIn, which rate-limits aggressively (typically after the 10th page per IP).
str | None
default:"None"
Path to a CA certificate file, used to verify SSL connections when routing through a proxy.
str
default:"markdown"
The format in which job descriptions are returned. Accepted values: "markdown", "html", "plain".
bool | None
default:"False"
When True, fetches the full job description and direct job URL for each LinkedIn result. This makes an additional HTTP request per job, so it increases total requests by O(n) and is significantly slower.
list[int] | None
default:"None"
Restricts the LinkedIn search to jobs posted by specific companies, identified by their LinkedIn company IDs.
int | None
default:"0"
Starts the search from a specific result index. For example, an offset of 25 skips the first 25 results and begins from result 26. Useful for paginating through large result sets.
int
default:"None"
Filters jobs by how recently they were posted, in hours. For example, hours_old=72 returns jobs posted within the last 3 days.
ZipRecruiter and Glassdoor round up to the next full day, so results may include jobs slightly older than the specified threshold.
For Indeed, you can only use one of: hours_old, job_type + is_remote, or easy_apply. For LinkedIn, you can only use one of: hours_old or easy_apply.
bool
default:"False"
When True, converts all salary values to annual equivalents. Hourly wages are multiplied by 2,080, monthly by 12, weekly by 52, and daily by 260.
int
default:"0"
Controls how much logging output is printed at runtime.
str
default:"None"
Overrides the default HTTP User-Agent string used when making requests. Useful if the default agent has been blocked or is outdated.

Return value

Returns a pd.DataFrame sorted by site ascending and date_posted descending. Each row represents a single job posting. If no jobs are found across all specified sites, an empty pd.DataFrame() is returned. The DataFrame columns are ordered as follows:
See JobPost schema for a description of each field.

Example

results_wanted is applied per site. With results_wanted=20 and four sites, you may receive up to 80 total results.