Google Jobs Scraper — Descriptions, Apply Links, Salaries avatar

Google Jobs Scraper — Descriptions, Apply Links, Salaries

Pricing

from $3.00 / 1,000 jobs

Go to Apify Store
Google Jobs Scraper — Descriptions, Apply Links, Salaries

Google Jobs Scraper — Descriptions, Apply Links, Salaries

Scrape Google Jobs by keyword, location and country: title, company, location, posted date, full description, direct apply links, salary, employment type, highlights, the employer's domain and ATS. 10 jobs per search, widened with related searches and de-duplicated.

Pricing

from $3.00 / 1,000 jobs

Rating

0.0

(0)

Developer

Berkan Kaplan

Berkan Kaplan

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

12 hours ago

Last modified

Share

Get the jobs Google shows in Google Jobs (the Jobs tab of Google Search) for any keyword, location and country. One row per job with the title, company, location, posted date, job description (the full text in the US; Google shows only a preview in some countries, flagged), direct apply links (LinkedIn, Indeed, the employer's careers site…), salary where Google shows it, employment type, highlights (qualifications, responsibilities, benefits), the employer's own domain and the ATS behind the posting (Lever, Greenhouse, Ashby, Workday…).

No Google account, no API key, no browser. Requests go through Apify's Google SERP proxy.

Quick start (API)

curl -X POST "https://api.apify.com/v2/acts/foxlabs~google-jobs-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"queries": ["registered nurse"], "locations": ["Texas"], "maxJobsPerQuery": 20}'

What you get

GroupFields
Jobtitle, companyName, location, postedText ("2 days ago"), postedAt (YYYY-MM-DD), postedDaysAgo, employmentType (FULL_TIME, PART_TIME, CONTRACTOR, INTERNSHIP, TEMPORARY), employmentTypeText, isRemote
PaysalaryText (as Google shows it), salaryMin, salaryMax, salaryCurrency, salaryCurrencyInferred, salaryPeriod (HOUR, DAY, WEEK, MONTH, YEAR)
ApplyapplyUrl (Google's first link for the job, never moved, tracking parameters removed), applyOptions[] (the job's apply links: source, URL, domain, shownByGoogle, googleRank, matchesEmployer, evidence, employerInUrl, titleInUrl), otherEmployerOptions[] (links Google grouped under the job that are another company's own ATS page or careers site — see below), via (the source Google credits)
EmployercompanyDomain (the employer's own domain, only when it carries the company's name; never a job board, ATS or hosting platform), atsProvider + atsUrl, companyLogoUrl
Contentdescription, descriptionIsPreview, qualifications[], responsibilities[], benefits[], otherHighlights[], perks[] ("Health insurance", "No Degree Mentioned", "Work from home")
ContextjobId (Google's job ID, unique per row), googleJobsUrl, query, searchLocation, country, language, searchText (the Google search that found the job), position, scrapedAt, error

Sample output

A real row from a test search on 2026-09-27, software engineer in New York, NY, as the current version reads it (trimmed: 3 of the job's 8 apply links shown):

{
"title": "Software Engineer, Systems ML - Compilers",
"companyName": "Meta",
"location": "New York, NY",
"postedText": "2 days ago",
"postedAt": "2026-09-25",
"employmentType": ["FULL_TIME"],
"isRemote": false,
"salaryText": "183,997–257,000 a year",
"salaryMin": 183997,
"salaryMax": 257000,
"salaryCurrency": "USD",
"salaryCurrencyInferred": true,
"salaryPeriod": "YEAR",
"applyUrl": "https://www.linkedin.com/jobs/view/software-engineer-systems-ml-compilers-at-meta-4470554281",
"applyOptions": [
{ "source": "LinkedIn", "url": "https://www.linkedin.com/jobs/view/software-engineer-systems-ml-compilers-at-meta-4470554281", "domain": "linkedin.com", "shownByGoogle": true, "googleRank": 1, "matchesEmployer": true, "evidence": "url-employer", "employerInUrl": null, "titleInUrl": true },
{ "source": "ZipRecruiter", "url": "https://www.ziprecruiter.com/c/Meta/Job/Software-Engineer,-Systems-ML-Compilers/-in-New-York,NY?jid=3441938ed51d43e7", "domain": "ziprecruiter.com", "shownByGoogle": true, "googleRank": 2, "matchesEmployer": true, "evidence": "url-employer", "employerInUrl": null, "titleInUrl": true },
{ "source": "talents.vaia.com", "url": "https://talents.vaia.com/companies/fiverr/software-engineer-search-engine-systems-38273373/", "domain": "talents.vaia.com", "shownByGoogle": false, "googleRank": 8, "matchesEmployer": false, "evidence": "url-employer", "employerInUrl": "fiverr", "titleInUrl": false }
],
"otherEmployerOptions": [],
"via": "LinkedIn",
"description": "Reality Labs (RL) focuses on delivering Meta's vision through Virtual Reality (VR), Augmented Reality (AR) and Wearable AI Devices. …",
"descriptionIsPreview": false,
"qualifications": [
"Bachelor's degree in Computer Science, Computer Engineering, relevant technical field, or equivalent practical experience",
"3+ years of experience in developing compilers, toolchains, or code optimization software"
],
"perks": ["Health insurance"],
"jobId": "UmM1Ljk7hQKcMQZZAAAAAA==",
"query": "software engineer",
"searchLocation": "New York, NY",
"country": "us"
}

How it works

  • 10 jobs per Google search. Google Jobs shows 10 jobs per search, and the search page has no page 2 (asking for start=10 returns "no Jobs matches"). To collect more, the Actor runs the related searches Google lists on the page and role-neutral variants ("… full time", "… senior", "… no degree"), removes duplicates by Google's job ID and stops when new searches stop finding new jobs. It does not promise "every job for a query"; measured runs are below.
  • What a location search returns (remoteJobs). Google mixes nationwide remote jobs — location "Anywhere" — into location searches, and the widening searches bring more of them: in a platform test of "software engineer" in New York, NY, 11 of 50 jobs were "Anywhere" (1 among Google's own first 10 results, 10 from the widening searches, most from "… part time"). So:
    • auto (default): with a location, "Anywhere" jobs are left out — a New York search returns jobs Google lists in New York (or in several places, one of them shown, e.g. "McLean, VA (+1 other)"). On the platform, run mroabOwxMJw1DXn5X returned 50 jobs: 45 in New York City, 4 listed in several places, 1 in Newark, NJ; 0 "Anywhere" jobs, 15 left out and counted in SOURCE_REPORT (filteredOut.remoteAnywhere). Without a location, remote jobs are kept.
    • include: keep them, also in location searches (and run "… remote" as a widening search).
    • exclude: always leave them out. only: search for remote jobs and keep only those (location "Anywhere", a work-from-home label, or a remote word such as "Remote" or "Homeoffice" in the title).
    • Leaving remote jobs out means more searches to reach maxJobsPerQuery (the same New York search took 10 searches for 50 jobs, 8 before remoteJobs existed; 2 instead of 1 for 10 jobs). Google's remote label is recognised as "Anywhere" (English), "Beliebiger Ort" (German, seen in Berlin runs zbISyf1BEvtKLFV5t and FNFvMce2rnGNcY7LP) and "Qualquer lugar" (Portuguese, 10 of 10 jobs in a Brazilian remote search). No such label was seen for the other languages the Actor reads, so none is assumed: Spanish and Dutch test searches showed a city for remote jobs, French and Italian remote searches returned no jobs, and Poland and Turkey returned ordinary web results instead of Google Jobs (2 of 2 searches each, 2026-09-28). If Google uses another label there, auto and exclude keep those jobs.
  • Direct apply links. The links Google shows are its own redirects; the Actor reads the direct posting URLs Google embeds in the page. applyUrl is Google's first link for the job — it is never moved to otherEmployerOptions, so it is only empty when Google lists no link at all (0 of 445 jobs in the 0.1.2 test runs).
  • Links that belong to another company are set apart — only on strong evidence. Google groups postings it considers the same job, and the group sometimes holds other employers' jobs: in one test, Google listed Paramount's and Capgemini's careers sites and Palantir's Lever page as "Apply" links for an Uber job, in Uber's own job panel. By default every link Google lists stays in applyOptions. A link moves to otherEmployerOptions only when it is another company's own ATS page (a Lever/Greenhouse/Workday… tenant with another company's name) or its own careers site (a careers./jobs.-style sub-domain outside .org/.edu/.gov and similar domains, or a corporate careers path such as /careers/… or /us-en/jobs/…), and the link does not show this job's title (for a site recognised only by its careers path, the link must show a different title). Google's first link never moves. Links on the job boards the Actor recognises stay, also when their URL names another company (they are flagged, see below), and so do links on sites it cannot place. Each link carries:
    • matchesEmployer: true when the link's domain, ATS tenant, sub-domain or URL names this company; false when the URL names another company (an ATS tenant, or a job-board URL such as LinkedIn "…-at-baseten-…" or ZipRecruiter "/c/Medix/") or the link is another company's careers site as defined above; null when the Actor finds no employer name in the URL — job boards whose URL format it does not read (indeed.com/viewjob?jk=…; the company part of StepStone URLs is not read either), ATS links without a tenant and sites it cannot place.
    • evidence: employer-domain, employer-hosted-page (a sub-domain named after this company on a hosting or careers platform, e.g. remotehub.my-board.org), ats, url-employer, url-mentions-employer (the URL path contains the company's name), job-board, other-company-site or unknown-site. employerInUrl is set only when matchesEmployer is false: the other company's name as found in the URL (ATS tenant or board slot; LinkedIn's keeps the job number, e.g. "baseten-4380548115") — for other-company-site only the site's domain name (e.g. "paramount").
    • titleInUrl: true when every word of the job title appears in the link, false when some do not, null when there is nothing to compare (titles of fewer than three words, links with almost no words); numbers are ignored, and work-mode words ("Remote", "Remoto", "Homeoffice") need not appear. A board link that names another employer but shows this job's title is usually the same job posted under a parent company or agency name (Tenet Healthcare for Valley Baptist).
    • shownByGoogle: Google showed an "Apply on …" button for the link (it lists some links without one); googleRank is its place in Google's list.
    • Measured on 445 jobs from 12 platform test runs (build 0.1.2, re-read with the current rules and checked against an independent review): links set apart went from 213 to 40, and jobs whose first Google link was set apart from 2 to 0 (one of them had been left without an applyUrl). Of 77 links the review labelled by hand, the 19 still set apart are all other companies' (Paramount, Capgemini, HCA Healthcare, Comcast, staffing agencies…); none of the 50 job-board links and not the one employer's own site among them is set apart. 7 other-company links stay: 5 whose URL carries no title to compare (for example voyagesolutions.com/jobs/469134/) and 2 staffing-agency pages with a bare /job/… path, the pattern job boards use too. The other 21 links set apart are ATS pages whose tenant is another company (Palantir, Blue Origin, Comcast…; checked by the tenant name). Part of this relies on the Actor's list of job boards, which was extended from the same review; a board it does not know that runs on a jobs. sub-domain can still be set apart (9 of the 50 labelled board links without the new entries).
  • The ATS is read only from the job's own link or from an ATS link whose tenant carries the company's name.
  • Only delivered jobs are charged. A search with no result, or where the filters removed everything, leaves one free row with an error explaining why. The SOURCE_REPORT record in the key-value store lists every search used and counts the duplicates and the filtered jobs (per reason) for each query.

Input & filters

InputWhat it doesDefault
queriesJob searches, one per line ("software engineer", "registered nurse", "Softwareentwickler")—
locationsCity, state or region, one per line. Each search runs once per location. Empty = no location in the search: Google then shows nationwide remote jobs plus jobs near the proxy's location (a US test, run fqRAZzRKpIkoJsWtO: 16 "Anywhere", 10 of the other 14 in Colorado/Wyoming/New Mexico). Add locations for real coverage—
countryWhich Google Jobs to search (39 countries). Poland and Turkey were removed on 2026-09-28: Google showed ordinary web results there instead of Google Jobs (2 of 2 test searches each). A country where Google shows no jobs ends with the free explanatory rowus
languageInterface language; empty = the country's main language—
maxJobsPerQueryJobs per search and location (up to 300). The Console form starts at 1050
datePostedany, today, 3days, week, month. Jobs Google shows without a date are left out when a window is setany
employmentTypeKeep only these types. Jobs without a type label are keptall
remoteJobsauto, include, exclude, only — what to do with remote jobs Google lists as "Anywhere" (see How it works). auto leaves them out when a location is set and keeps them otherwiseauto
includeDescription / includeHighlightsTurn the long text fields off for smaller datasetson
maxSearchesPerQueryUpper bound on Google searches used to widen one search (each returns up to 10 jobs)30

Invalid input (unknown country, date window or employment type, a non-integer limit) is rejected by Apify before the run starts: the API answers HTTP 400 with the reason and no run is created. Values the input form cannot check (for example a malformed language code) stop the run with the reason in its status message.

Example inputs (copy & paste)

Nurses in Texas, full-time only, last 7 days:

{ "queries": ["registered nurse"], "locations": ["Texas"], "employmentType": ["FULL_TIME"], "datePosted": "week", "maxJobsPerQuery": 100 }

Software jobs in Berlin, German Google:

{ "queries": ["Softwareentwickler"], "locations": ["Berlin"], "country": "de", "maxJobsPerQuery": 50 }

Remote data jobs across the US, without descriptions (smaller dataset; run time is unchanged — it depends on the number of Google searches):

{ "queries": ["data analyst", "data engineer"], "remoteJobs": "only", "includeDescription": false, "includeHighlights": false, "maxJobsPerQuery": 50 }

Several cities in one run (duplicates across searches are delivered once):

{ "queries": ["electrician"], "locations": ["Houston, TX", "Dallas, TX", "Austin, TX"], "maxJobsPerQuery": 50 }

Use cases

  • Recruiting and staffing: who is hiring for a role in an area, with the direct link to the posting and the date.
  • Sales prospecting (hiring signals): companies hiring for a role, their domain (companyDomain) for enrichment and the ATS they use.
  • Job boards and HR tech: full descriptions, highlights, pay and type, de-duplicated by Google's job ID.
  • Labour-market research: pay ranges and employment types by role, city and country.

Performance & coverage

Measured on the Apify platform on 2026-09-28 (1 GB memory, build 0.1.2, default remoteJobs: auto). 0.1.3 changes how apply links, company domains, pay and remote labels are read; the searches are the same, except that the same words in another order no longer run as a second search:

SearchJobsGoogle searchesTimeRun
software engineer, New York, NY5010171 smroabOwxMJw1DXn5X
registered nurse, Texas507160 shMbq3ZsZCiAt0WXHd
Softwareentwickler, Berlin (Germany)304127 szbISyf1BEvtKLFV5t
software engineer, New York, NY, 10 jobs (the form's starting input)10237 sAUpPjxT74NdQKh9eZ

50 jobs took 160–171 seconds in these runs (103 s for 50 Berlin jobs in run FNFvMce2rnGNcY7LP). Run time depends mostly on Google's response time through the proxy: a single search took up to 66 seconds, and the median per run ranged from 3 to 43 seconds (18 s New York, 22 s Texas, 43 s Berlin). Peak memory in the four runs above was 109–236 MiB. No run of that build returned a duplicate jobId (12 runs, 445 jobs). The New York runs left out 15 and 1 "Anywhere" jobs and searched further to reach the requested number. Before the platform runs, a local test capped at 8 searches returned 39 jobs — 35 in New York City, 3 listed in several places with another city shown, 1 in Newark, NJ — and left out 11 remote ones; on the platform, run mroabOwxMJw1DXn5X reached 50 jobs with 10 searches and left out 15.

Data quality

Share of jobs with a value in the three platform runs above (build 0.1.2, n = 50 / 50 / 30; company domain recounted with the 0.1.3 rules on the same rows):

FieldSWE, New YorkNurse, TexasBerlin (Germany)
title, company, location, source, apply link100%100%100%
posted date86%84%67%
description100% full98% full100% preview
employment type100%100%100%
salary44%18%37%
qualifications / responsibilities98% / 96%88% / 94%—
company domain22%34%10%
  • Posted date: we aimed for 90% of jobs with a posting date, but Google itself shows one on only 50–93% of jobs in the test runs without a date filter (86% New York, 84% Texas, 67% Berlin; 50% in a second Berlin run, 93% in Paris). For the other jobs there is no date anywhere on the page — not on the job card, not in the job's details (checked, for example, on Plaid's and Browserbase's New York jobs, whose panels show salary and job type but no date). Those rows have postedAt: null; the date is never estimated. Google's "30+ days ago" is stored as 30 days, a lower bound (not seen in the test runs). Where Google shows a date, it is parsed in English, German, French, Spanish, Portuguese, Italian, Dutch, Polish and Turkish (checked on real pages in English, German, French, Spanish, Portuguese and Dutch).
  • Descriptions: Google shows the full description in the US (and in a Brazilian test search: 9 of 10 full, 1 without a description). In Germany and France it showed only a preview of up to 400 characters for every job in the 0.1.2 runs (30 of 30 and 50 of 50 in Berlin, 30 of 30 in Paris; an earlier Berlin run had 10 of 30 full), and so did one test search each in Spain and the Netherlands (10 of 10). Those rows have descriptionIsPreview: true.
  • Salary: US pay labels have no currency sign ("183,997–257,000 a year"); the country's currency is filled in and salaryCurrencyInferred is true. Thousands written apart from the number are read: "65 k € à 85 k € par an" gives 65000–85000 (also "55 Tsd. €", "60 mil €", "R$ 4 mil por mês"). Build 0.1.2 read 7 of the 8 pay labels in a Paris run (wfC9gQehi27uvlAaW) 1,000 times too small ("65 k €" as 65); fixed in 0.1.3, and no other of the 206 pay labels in the test runs changed.
  • Company domain: only the employer's own domain — the domain of an apply link whose name matches the company's name (uber.com, homedepot.com; a careers domain such as capitalonecareers.com or tdbank.jobs counts). Initials and acronyms count (bswhealth.com for Baylor Scott & White Health, gm.com for General Motors); a shared generic word ("health") alone does not. It is null when the only candidates are job boards, ATS or careers platforms, hosting services or link aggregators — also for companies that are themselves job boards (LinkedIn, France Travail). In the 0.1.2 test runs the independent review found 14 of 94 values wrong (ALL IN GROUP → indeed.com, RemoteHub → my-board.org, Thermon → applicantpool.com…); the 0.1.3 rules give 76 values on the same rows, none of them among the 14 (the other 4 removed were job-board companies).
  • Apply links checked: 12 apply links on 12 different sites (employer career sites, LinkedIn, Built In, StepStone, the German employment agency) were opened; all 12 showed the job's title and company.

Pricing

$3 per 1,000 jobs ($0.003 per job). One job event per delivered job. Status rows (no results, everything filtered) are free. Each run also has Apify's Actor start event ($0.00005 per GB of memory; the default 1 GB is one event). Current prices are also on the Pricing tab.

FAQ

Why do I get fewer jobs than I asked for? Google shows 10 jobs per search; the Actor widens with related searches until new searches bring no new jobs. Narrow or unusual searches run dry sooner. SOURCE_REPORT shows how many searches ran and how many jobs were duplicates.

Are the apply links direct? Yes, applyUrl and applyOptions[].url are the posting URLs Google embeds, not Google redirects, with utm_* parameters removed.

I searched "New York" — why are there no remote jobs? With a location, the default (remoteJobs: "auto") leaves out jobs Google lists as "Anywhere" ("Beliebiger Ort" in German, "Qualquer lugar" in Portuguese), so the results are jobs placed in your location. Set remoteJobs to include to add them, or only for remote jobs only. SOURCE_REPORT shows how many were left out.

Why are some of Google's apply links in otherEmployerOptions? Google groups postings it considers the same job and sometimes includes other employers' jobs in that group. Only links with strong evidence are kept apart: another company's own ATS page or careers site that does not show this job's title. Google's first link is never kept apart, and links on job boards stay in applyOptions even when their URL names another company (then matchesEmployer is false), so check that field if you need only this employer's postings. The links kept apart are still in the dataset for review.

Why is companyDomain often empty? It is filled only from an apply link on the employer's own domain, whose name matches the company's. Job boards, ATS and careers platforms and hosting services are never used, so jobs posted only on boards (LinkedIn, Indeed) have none, and neither do companies that are themselves job boards.

Can I get only new jobs every day? Use datePosted: "today" on a daily schedule; jobs Google shows without a date are left out when a window is set.

Troubleshooting

  • "Google Jobs shows no jobs for this search in this country": try a broader search or check that Google Jobs covers the country.
  • "none matched the filters": the date, type or remote filter removed every job Google showed; the message lists how many each filter removed.
  • "Apify Google SERP proxy is not available to this run": the Google SERP proxy must be enabled on your Apify account (Settings → Proxy).
  • Data is what Google Jobs publicly shows at run time; employers' postings change daily.
  • Google may change its page layout without notice; fields can then come back empty until the Actor is updated. If you see that, open an issue with the run ID.
  • Only publicly posted job ads are collected. Descriptions can contain whatever contact details the employer published.
  • Google, Google Jobs and all job board names are trademarks of their owners; this Actor is not affiliated with them.

Support

Open an issue on the Issues tab with the run ID and the input, or write to info@foxlabs.com.tr.

Changelog

0.1.5 — 2026-09-28

  • Poland and Turkey removed from country: Google showed ordinary web results there instead of Google Jobs (2 of 2 test searches each). An input with pl or tr is now rejected before the run starts.

0.1.4 — 2026-09-28

  • Pricing: $3 per 1,000 jobs, status rows free.

0.1.3 — 2026-09-28

  • Apply links: every link Google lists stays in applyOptions unless it is another company's own ATS page or careers site without this job's title; Google's first link (applyUrl) never moves. Measured on 445 jobs: links set apart 213 → 40, none of them a job board or the employer's own site in the independently labelled sample.
  • evidence values: other-site is replaced by other-company-site (another company's own careers site), job-board or unknown-site; new employer-hosted-page.
  • companyDomain only from the employer's own domain; never a job board, ATS, careers or hosting platform (14 wrong values of 94 in the test runs → 0).
  • Pay: thousands written apart from the number ("65 k €", "55 Tsd.", "60 mil", "R$ 4 mil") and Portuguese "por mês" are read.
  • Remote: "Beliebiger Ort" (German) and "Qualquer lugar" (Portuguese) are recognised as "Anywhere"; "Homeoffice" in a title marks the job remote.
  • Employment type: French "Prestataire" and Portuguese "Prestador de serviços" are CONTRACTOR.
  • A job past the per-search limit is no longer marked as seen, so a later location or query can still deliver it; the same search words in another order run once.
  • README corrections from an independent review; the claim that the Actor is monitored with test searches was removed (no monitoring runs at the moment). See CHANGELOG.md.

0.1 — 2026-09-28

First version. See CHANGELOG.md.