Install python-jobspy
mainInstall the python-jobspy library using pip. Requires Python version >= 3.10.
pip install -U python-jobspyrepository·main·Indexed 23 days ago
https://github.com/speedyapply/jobspyA job scraping library for aggregating job postings from LinkedIn, Indeed, Glassdoor, ZipRecruiter, Bayt, and other boards into a pandas DataFrame. It features the scrape_jobs() API for filtering by search terms, location, and job type, and supports proxy rotation to mitigate 429 rate limit errors. Requires Python >= 3.10.
Install the python-jobspy library using pip. Requires Python version >= 3.10.
pip install -U python-jobspyA 429 response code indicates you have been blocked by a job board for sending too many requests. To mitigate this:
proxies parameter to rotate your IP address.The primary API for JobSpy is scrape_jobs(). It returns a pandas DataFrame containing aggregated job postings from multiple sources. You can specify which sites to scrape, search terms, locations, and other filters.
import csv
from jobspy import scrape_jobs
jobs = scrape_jobs(
site_name=["indeed", "linkedin", "zip_recruiter", "google"],
search_term="software engineer",
google_search_term="software engineer jobs near San Francisco, CA since yesterday",
location="San Francisco, CA",
results_wanted=20,
hours_old=72,
country_indeed='USA',
)
print(f"Found {len(jobs)} jobs")
print(jobs.head())
jobs.to_csv("jobs.csv", quoting=csv.QUOTE_NONNUMERIC, escapechar="\", index=False)When searching on Indeed or Glassdoor, you must provide the country_indeed parameter. Supported countries include:
| Argentina | Australia* | Austria* |
| Bahrain | Belgium* | Brazil* |
| Canada* | Chile | China |
| Colombia | Costa Rica | Czech Republic |
| Denmark | Ecuador | Egypt |
| Finland | France* | Germany |
| Greece | Hong Kong* | Hungary |
| India* | Indonesia | Ireland* |
| Israel | Italy | Japan |
| Kuwait | Luxembourg | Malaysia |
| Mexico* | Morocco | Netherlands* |
| New Zealand | Nigeria | Norway |
| Oman | Pakistan | Panama |
| Peru | Philippines | Poland |
| Portugal | Qatar | Romania |
| Saudi Arabia | Singapore* | South Africa |
| South Korea | Spain* | Sweden |
| Switzerland* | Taiwan | Thailand |
| Turkey | Ukraine | United Arab Emirates |
| UK* | USA* | Uruguay |
| Venezuela | Vietnam |
Note: Asterisk () indicates support for Glassdoor as well.
Certain parameter combinations are mutually exclusive for specific job boards:
Indeed Limitations: You can only use ONE of the following in a single search:
hours_oldjob_type & is_remoteeasy_applyLinkedIn Limitations: You can only use ONE of the following in a single search:
hours_oldeasy_applyThe following optional parameters are available for scrape_jobs():
| Parameter | Type | Description |
|---|---|---|
site_name | list or str | linkedin, zip_recruiter, indeed, glassdoor, google, bayt, bdjobs (default is all) |
search_term | str | The job title or keywords |
google_search_term | str | Specific search term for Google Jobs; the only parameter used for filtering Google jobs |
location | str | Geographic location |
distance | int | Distance in miles (default: 50) |
job_type | str | fulltime, parttime, internship, contract |
proxies | list | List of proxies in format ['user:pass@host:port', 'localhost']. Scrapers use round-robin |
is_remote | bool | Filter for remote jobs |
results_wanted | int | Number of results to retrieve per specified site |
easy_apply | bool | Filters for jobs hosted on the job board site (Note: LinkedIn easy apply filter no longer works) |
user_agent | str | Override default user agent |
description_format | str | markdown (default) or html |
offset | int | Starting index for the search |
hours_old | int | Filter by hours since posting (ZipRecruiter/Glassdoor round up to next day) |
verbose | int | Verbosity: 0 (errors only), 1 (errors+warnings), 2 (all logs, default) |
linkedin_fetch_description | bool | Fetches full description and direct URL for LinkedIn (slower, increases requests by O(n)) |
linkedin_company_ids | list[int] | Search LinkedIn jobs by specific company IDs |
country_indeed | str | Filter country for Indeed & Glassdoor |
enforce_annual_salary | bool | Converts wages to annual salary |
ca_cert | str | Path to CA Certificate file for proxies |
The output DataFrame follows this schema:
titlecompanycompany_urljob_urllocation (country, city, state)is_remotedescriptionjob_type: fulltime, parttime, internship, contractjob_function:interval: yearly, monthly, weekly, daily, hourlymin_amountmax_amountcurrencysalary_source: direct_data, description (parsed from posting)date_postedemailsPlatform Specific Fields:
job_levelcompany_industrycompany_country, company_addresses, company_employees_label, company_revenue_label, company_description, company_logoskills, experience_range, company_rating, company_reviews_count, vacancy_count, work_from_home_type