Google Jobs Scraper - Most Comprehensive
Pricing
from $0.04 / 1,000 jobs
Google Jobs Scraper - Most Comprehensive
🔥 ~$0.5/1K jobs 🔥 Collect public Google Jobs results by keyword, location, date, job type, remote status, education signal and employer's website. Export normalized job details and application links without a Google account.
Pricing
from $0.04 / 1,000 jobs
Rating
0.0
(0)
Developer
Kai
Maintained by CommunityActor stats
0
Bookmarked
7
Total users
3
Monthly active users
9 days ago
Last modified
Categories
Share
Google Jobs Scraper
Collect public Google Jobs results by job title, skill, location, or Google Jobs search URL. Get descriptions, salary data, qualifications, benefits, employer information, and application links when Google supplies them.
Find emails, phone numbers, and social profiles on employer websites. Search in a selected country and language. Save each job as an Apify Dataset item. No Google account is required.
Use cases
- Recruitment research: find open roles by skill, employer, employment type, and location.
- Vacancy monitoring: repeat a search and compare the saved job datasets.
- Salary research: collect published pay ranges, currencies, and pay periods.
- Employer research: collect company websites, ratings, and published website contacts.
- Job data collection: build a dataset of descriptions, qualifications, benefits, responsibilities, and application links.
Choose how to search
| Starting point | Input | Use it for |
|---|---|---|
| A job title or skill | keyword and optional location | Search for jobs in an area. |
| An existing Google Jobs search | searchUrl | Keep the search text and URL filters. |
Each run accepts one keyword and one location, or one search URL. If you supply searchUrl, its search text takes priority over keyword and location.
Choose what to collect
| Option | Default | Effect |
|---|---|---|
includeJobDetails | false | Request extra job details, including descriptions, employer websites, and ratings when available. Details already in the search results are kept with this option off. |
enrichContacts | false | Read employer websites for emails, phone numbers, and social profiles. |
Website contacts work with either setting of includeJobDetails. A job must have an employer website supplied in the search results or extra job details. Contact collection is off by default.
Search jobs in a location
{"keyword": "software engineer","location": "Bengaluru","maxItems": 100,"locale": {"countryCode": "IN","languageCode": "en"}}
The location is part of the search text. For this example, the Actor searches for software engineer jobs in Bengaluru. Google selects the matching jobs. The location does not set a strict geographic boundary.
The Actor gets more result pages when needed. maxItems is an upper limit, not a required result count. It accepts a positive integer with no fixed upper cap. Google can return fewer jobs than requested.
Use a Google Jobs URL
{"searchUrl": "https://www.google.com/search?q=certified+nursing+assistant+jobs+Fresno+CA&udm=8&gl=us&hl=en","maxItems": 50,"includeJobDetails": true}
Use an HTTPS Google search URL with a non-empty q parameter and either udm=8 or ibp=htl;jobs. A selected-job URL fragment does not request that specific job. The Actor uses the search.
Country and language come from URL gl and hl values unless locale supplies them. The search text and encoded filters are kept. locale, googleDomain, and filters.radiusKm can replace URL settings.
Set the country, language, and Google domain
{"keyword": "software engineer","location": "Berlin","googleDomain": "google.de","locale": {"countryCode": "DE","languageCode": "de"},"maxItems": 50}
locale.countryCode controls Google gl. locale.languageCode controls Google hl. Use "auto" for the language to let Google select it. googleDomain changes the search host. These are separate controls.
Filter recent jobs by employment type
{"keyword": "certified nursing assistant","location": "Fresno, CA","locale": {"countryCode": "US","languageCode": "en"},"maxItems": 50,"filters": {"datePosted": "week","jobTypes": ["full-time"],"radiusKm": 30,"salaryOnly": true}}
Date, employment type, remote work, and no-degree filters use Google search controls. Salary, posting age, employer name, and source name filters use the returned job fields. The radius is a Google search setting. Jobs outside that radius can appear.
Find employer contacts
{"keyword": "nurse","location": "Fresno, CA","locale": {"countryCode": "US","languageCode": "en"},"maxItems": 20,"includeJobDetails": true,"enrichContacts": true}
This example requests job details and reads available employer websites for contacts. Contact collection can increase run time. A website error does not remove the job.
Input reference
Supply keyword or searchUrl. Fields not listed here are not accepted. Each run saves its own results without checking jobs from previous runs.
| Field | Type | Default | Effect |
|---|---|---|---|
keyword | string | none | Job title, skill, or search text. Required without searchUrl. Between 1 and 200 characters. |
location | string | none | One city, region, country, or other location label. Up to 200 characters. |
searchUrl | string | none | One HTTPS Google Jobs search URL. Its search text takes priority. |
googleDomain | string | URL host or google.com | A supported Google search host, such as google.com, google.co.uk, or google.co.in. Supply the host without a URL scheme. |
maxItems | integer, 1 or more | 10 | Requested maximum jobs. No fixed upper cap. |
includeJobDetails | boolean | false | Request extra Google job details. A successful detail result has an additional charge. |
enrichContacts | boolean | false | Read employer websites for emails, phone numbers, and social profiles. |
proxyConfiguration | object | {"useApifyProxy":true} | Proxy used to resolve job apply links and to read employer websites. The default Apify Proxy works. |
locale.countryCode | string | URL gl or IN | Two-letter country code. Converted to uppercase. |
locale.languageCode | string | URL hl or en | Google language code, such as en, de, or zh-CN. Converted to lowercase. auto lets Google select the language. |
fetchDetails | boolean | true | No effect. Kept for older saved inputs. Use includeJobDetails to request extra details. |
Filter reference
| Field | Type or values | Default | Effect |
|---|---|---|---|
filters.datePosted | any, past-day, 3-days, week, month | any | Use Google's date filter. |
filters.jobTypes | string[] | [] | Use full-time, part-time, contract, and/or internship. Search each selected type. |
filters.remoteOnly | boolean | false | Use Google's remote work filter. |
filters.noDegreeMentionedOnly | boolean | false | Use Google's no-degree filter. |
filters.radiusKm | positive number | none | Send the requested radius to Google in kilometres. |
filters.postedWithinHours | positive number | none | Keep known posting dates within this age. Jobs with an unknown posting date are excluded. Relative dates are estimates. |
filters.salaryOnly | boolean | false | Keep jobs with a salary label or salary amounts. |
filters.companyFilter | string[] | none | Keep employers whose names contain at least one supplied value. Matches ignore letter case. |
filters.excludeCompanies | string[] | none | Remove employers whose names contain any supplied value. Matches ignore letter case. |
filters.viaFilter | string[] | none | Keep source names that contain at least one supplied value, such as LinkedIn. Matches ignore letter case. |
Output
Each Dataset item is one job. Google redirect links are replaced with their destination URLs when possible. Website contacts are added when you request them.
Field groups
| Group | Fields |
|---|---|
| Job identity | id, title, company, location |
| Description and highlights | description, highlights, metadata, signals |
| Employment and education | employment, workArrangement, education |
| Pay and dates | salary, dates |
| Employer and location details | companyDetails, locationDetails |
| Applications and sources | links, applyOptions, applyUrl, applyLinkCount, source, sourceLinks |
| Website contacts | emails, phoneNumbers, socialProfiles, contactsStatus |
| Collection context | meta, optional jobDetails, optional structuredData |
Field types
| Field | Type | Contents |
|---|---|---|
id | string | Google job ID. |
title | string | Job title. |
company | string or null | Employer name. |
location | string or null | Original location label. Separate city, state, and country fields are not added. |
metadata, signals | string[] | Job labels supplied by Google. |
description | object | text and html, each a string or null. |
highlights | object | qualifications, benefits, and responsibilities, each a string array. |
employment | object | types: string[]. Labels are kept as supplied. |
workArrangement | object | type: remote, hybrid, on-site, or unknown; label: string or null. |
education | object | label: string or null. |
salary | object | Original pay text and available structured values. See below. |
dates | object | Posting label, posting date, estimate flag, and closing date. See below. |
companyDetails | object | Employer links, logo, and ratings. See below. |
locationDetails | object | additionalCount, latitude, and longitude: number or null. Coordinates are available for some jobs only. |
links, sourceLinks | object[] | Each link has label: string or null, and url: string. Some links remain relative or unresolved. |
applyOptions | object[] | Each option has provider: string or null, url: string, and direct: boolean or null. |
applyUrl | string or null | Main application URL. |
applyLinkCount | number | Number of distinct application URLs. |
source | object | name, url, and domain: string or null. A matching application link supplies the URL when available. |
meta | object | Collection time, result position, page count, and search context. See below. |
jobDetails | optional object | status: loaded or failed. Added when extra details are requested. |
structuredData | optional object | Job posting data in the schema.org JobPosting format, when available. Its child fields vary by job. |
emails | optional string[] | Ranked email addresses from the employer website, up to ten. |
phoneNumbers | optional string[] | Distinct published website phone numbers. Separators are removed. A supplied + prefix and ;ext= extension are kept. Country codes are not guessed. |
socialProfiles | optional object | Profile URLs grouped by network, up to three per network. |
contactsStatus | optional string | Website visit result. See Website contacts. |
Nested field types
| Object | Fields |
|---|---|
salary | text: string or null; disclosed: boolean; min, max: number or null; currency: string or null; period: hour, day, week, month, year, or null. |
dates | postedText, postedAt, validThrough: string or null; postedAtEstimated: boolean or null. Dates use ISO format. |
companyDetails | logoUrl, websiteUrl, websiteDomain, moreJobsUrl, webResultsUrl: string or null; ratings: object[]. |
companyDetails.ratings[] | source: string; value: number; count: number or null; url: string. |
socialProfiles | facebook, instagram, linkedin, twitter, youtube, tiktok, pinterest, whatsapp: string[] of profile URLs. twitter includes X profiles. |
meta | source: google-jobs; scrapedAt: ISO date string; position: number; pagesProcessed: number; search: object. |
meta.search | keyword, countryCode, languageCode: string; location: string or null. These describe the search, not the job's address. |
Selected job fields
This example shows some fields from one Fresno job. A full Dataset item has more fields.
{"id": "mBdGpYoWEsTQB2vIAAAAAA==","title": "Certified Nursing Assistant (CNA)","company": "Sunnyside Rehab of Fresno","location": "Fresno, CA","employment": {"types": ["Full-time"]},"salary": {"text": "$19 an hour","disclosed": true,"min": 19,"max": 19,"currency": "USD","period": "hour"},"highlights": {"benefits": ["Dental insurance", "Health insurance", "Paid time off"]},"education": {"label": "No Degree Mentioned"},"jobDetails": {"status": "loaded"}}
Phone values can use these formats:
{"phoneNumbers": ["+14155550123", "02079460958;ext=42"]}
This phone example shows the format only. It is not a contact record for the employer above.
Search and field limits
Result count and pagination
There is no fixed cap on the result count. The Actor stops when it reaches maxItems or when Google has no more new jobs. A very large search can fail if it takes too long. If this occurs, use a lower maxItems.
The Actor gets more result pages when needed and removes duplicate jobs. No page number or page token input is needed.
Optional job details
With includeJobDetails: false, you get the descriptions and other details that Google shows in the search results. With true, the Actor collects more details for each job. This can increase run time.
jobDetails.status: "loaded" means the Actor got usable extra details for the job. It does not guarantee a website, ratings, or a description. If the extra details cannot be loaded, the job keeps the details from the search results and reports failed.
Country, language, and job variation
Available fields can differ by job, country, and language. Empty arrays and null values can mean that the information is not available for that job. Optional fields can be absent.
The Actor reads job labels in many languages. A field can be empty when Google words a label in a way that the Actor does not recognize. applyOptions[].direct is set for English labels only. If Google changes its search filters, a filtered search can fail.
Salary amounts are null when the Actor cannot identify them. Posting dates calculated from relative labels have postedAtEstimated: true. Work arrangement and employment types are not taken from the description text. Benefit text is kept in highlights.benefits; separate benefit flags and seniority levels are not added.
Employer websites and application links
The Actor replaces Google redirect links with their destination URLs. If a link cannot be resolved, the Google link is kept. Links inside description text are not changed.
Employer websites come from the returned job data. The Actor does not search for a missing employer website. Jobs without a website remain in the output.
Website contacts
With enrichContacts, the Actor reads the employer website and up to three linked contact, legal, team, or about pages on the same site. Jobs with the same website share one visit per run.
It finds email addresses on these pages, including protected or written-out forms such as info [at] example [dot] com. Addresses on the website's own domain rank first, then free mailboxes, then other domains. Placeholder and platform addresses are removed. Addresses whose domain cannot receive mail are also removed.
It collects only numbers that the website marks as phone numbers. It does not collect other digit sequences from page text. It removes duplicate numbers across pages. Supported numbers have 7 to 15 digits, with an optional + prefix and an optional ;ext= extension of up to ten digits. Local numbers keep their local form.
It reads social profiles for Facebook, Instagram, LinkedIn, X, YouTube, TikTok, Pinterest, and WhatsApp. Job boards, directories, and social network pages are skipped as websites. A supported social website link can still be added as a profile.
A website can have no published contacts, or it can block automated access. The Actor stops reading a page that is too slow or too large. Contact arrays can therefore be empty.
contactsStatus | Meaning |
|---|---|
scraped | The Actor read the website. Contact arrays can still be empty. |
skipped | The website is a platform or social network page. It was not read for contacts. |
blocked | The website refused automated access. |
failed | The website did not load, returned an error, or did not return a usable page. |
Contact fields are added only to jobs with a website when enrichContacts is on. Jobs without a website stay unchanged. Turning enrichContacts off does not add contact fields.
Charges
You pay for each job saved to the Dataset. With includeJobDetails on, each job with jobDetails.status: "loaded" has an extra job-detail charge. Jobs whose extra details fail are not charged for details.
If the run reaches your maximum charge limit, the Actor stops saving jobs. The result can then contain fewer than maxItems jobs.