Google Jobs Scraper - Job Listings, Salaries & Apply Links
Pricing
from $2.00 / 1,000 per-run start fees
Google Jobs Scraper - Job Listings, Salaries & Apply Links
Scrape Google Jobs as structured job postings data into your dataset: one row per advert with company, location, source job board, posting date, salary where shown, full description, requirements and every apply link. For recruiters, job market research and hiring signals.
Pricing
from $2.00 / 1,000 per-run start fees
Rating
0.0
(0)
Developer
SR
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
2
Monthly active users
4 days ago
Last modified
Categories
Features
Share
Google Jobs Scraper - Job Listings, Salaries and Apply Links
This Google Jobs scraper turns job titles and cities into a table of job listings: one row per advert with the company, the location, the job board it came from, how long ago it was posted, the salary where Google has one, the full job description, the requirements Google extracted from it, and every site the job can be applied on. Recruiters, labour-market researchers and sales teams looking for hiring signals use it to read the whole market for a role in one run.
What does this Google Jobs scraper do?
Google has already merged the job boards. A single advert here typically carries five to eight apply links, one per board that listed it, so you see LinkedIn, Indeed, the company's own careers page and several aggregators in one row instead of deduplicating four scrapes by hand.
You give it a list of job searches and a list of locations. It runs every search once per location, reads the jobs Google shows for it, removes duplicates across the whole run by Google's own job id, and writes one clean row per advert to the dataset. Export it as JSON, CSV, Excel or through the Apify API.
Ten jobs per search, and why that is not a setting
This is the one limit to plan around. A Google Jobs search returns ten adverts and there is no page two: the surface does not page, and asking for more returns nothing rather than the next ten.
So the way to a bigger dataset is more searches, and the input is shaped for exactly that. Job searches takes a list, Locations takes a list, and every search runs once per location. Four titles across five cities is twenty queries and up to two hundred adverts.
That works in your favour more than it sounds: "python developer" in Austin and "python developer" in Denver return genuinely different companies, where page two of a single search would have returned more of the same.
Input
| Field | Name in the API | Default | What it does |
|---|---|---|---|
| Job searches | search | — | List of job titles or skills, such as software engineer |
| Locations | locations | empty | List of cities; empty searches without a city |
| Maximum jobs | maxItems | 100 | Total unique adverts to deliver, 1 to 5000 |
| Language | language | en | Language the results come back written in |
| Country | region | us | Market the search is made for |
| Resolve apply links | resolveApplyLinks | false | Follow each apply link to the board it lands on |
| Maximum apply links to resolve | maxApplyLinksResolved | 60 | Cap on resolved links, across the whole run; zero leaves them all unchanged |
| Attempts per query | attempts | 15 | How often one search is retried before it is reported as blocked |
The actor searches every combination of search and locations in that
order. Both fields also accept comma-separated text through the API.
maxItems cannot make Google show more than ten cards for one query; add
search terms and locations to increase the result set.
Example input:
{"search": ["software engineer"],"locations": ["New York"]}
Output: Google Jobs data per advert
The default dataset contains one row per unique advert. This is the first row the example input above returned (the description and lists are shortened here; the dataset has them in full):
{"job_id": "fplVD6NzqcGb_8UAAAAAAA==","title": "Software / Data Engineer (First Technology Hire - NYC Private Equity)","company": "Averity","location": "New York, NY","via": "LinkedIn","posted": "1 day ago","employment_type": "Full-time","salary_text": "$125K–$175K a year","salary_min": 125000,"salary_max": 175000,"salary_currency": "$","salary_period": "year","description": "How would you like to be the first technology hire at a NYC private equity firm - handed a blank sheet of paper to build their entire tech stack and data strate…","qualifications": ["1-4 years of professional experience as a Software Engineer, Data Engineer, Analytics Engineer, Data Analyst, Business Intelligence Developer or Business Systems Analyst","Strong SQL, plus Python (or similar) for automation and data work"],"responsibilities": ["Building the data foundation our investment, asset management and finance teams run on - pipelines, integrations, and one source of truth for portfolio and property data","Automating the manual processes that live in spreadsheets and inboxes today, using Python, SQL, Power Automate and Power Apps"],"benefits": ["$125,000 - $175,000 base salary","Annual bonus, targeted at 15-30% in year one"],"apply_options": [{"name": "LinkedIn","url": "https://www.google.com/goto?url=CAESgwIB6zswFeLxcwaLylTxyqHzn37ImOMutJiuQ5d950eWZmyZWRvZyeXphbseaBfa5L4CSMSfBMeD0-D6hmROTVSnunf2WMFdffics3FURh0ZFooYZIOjlhvxEBrGfK0GnpoqQXsksgbqWSr14MbSPWDrtSyYZXpES6PPVCP0mjNcuzo8ngOG5LDrOTpVijMiVBcI8DZnu3BdcCdCWwDx3gwcPH7qdpxHwL_Ie9Rn9Mcfs5vHEZKgNNcpJkj3QA25E6hkUAgOGLwtxsUPPv8K0YtWmIx8b90e9WRlgbA6E3Z0y6vrnpDKQ9ykzoWzqbd2PffmAveC10orHksrFVEAnof4_tG1"}],"share_url": "https://www.google.com/search?ibp=htl;jobs&q=software+engineer+New+York&htidocid=fplVD6NzqcGb_8UAAAAAAA%3D%3D&hl=en-US&shem=epsd1,esd2e,rimspwouoe&shndl=37&shmd=H4sIAAAAAAAA_xWOvQrCMBSFce0LCE53VNFGBBedRKviIIIuBaGk4ZpGa25Nrv15Lx_QuJzh4_CdE3170e1Cd26kQxCwlSwhsdpYRAfDnXGe4YqqsFSS7uBgQm0Kp3QDZ2dqyQjJ-2O4GwV6pBw8SqcKIAt7Il3iYFUwV34phPdlrD1LNipW9BJkMadWPCj3_8h8ES5UZVBm88WsjSurx_11jS7YwVg4YQMpueckrP8AWYk8zrcAAAA&shmds=v1_ARwrE22yYrbvB1ZhnO31LOh46KfL15jpKPVB94JzQP6ToLAORg&source=sh/x/job/li/m1/1#fpstate=tldetail&htivrt=jobs&htiq=software+engineer+New+York&htidocid=fplVD6NzqcGb_8UAAAAAAA%3D%3D","company_logo": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSWkK7qTycsNhxTsYFZoumETzBVq4pfjovIUTl4&s=0","source": "google-jobs-scraper","platform": "google_jobs","fetched_at": "2026-10-04T00:46:24.138Z","posted_at": "2026-10-03","employment_type_code": "FULL_TIME","salary_currency_code": "USD","salary_unit": "YEAR","position": 1,"search": "software engineer","search_location": "New York","market": "us","language": "en"}
The fields:
title,company,location,via,posted,employment_typesalary_text,salary_min,salary_max,salary_currency,salary_perioddescription— the advert's own textqualifications,responsibilities,benefits— Google's own extraction from the original post, as three separate listsapply_options— every board the job can be applied on, each withnameandurlshare_url,company_logo,job_idsearch,search_location,market,language,positionsource,platform,fetched_at,posted_at,employment_type_code,salary_currency_code,salary_unit— normalized values that make records easier to combine
Every field keeps its JSON type. Missing text, salary or highlights stay null.
position counts from one across the entire dataset. employment_type stays
the displayed text, salary_currency the symbol and salary_period the
lowercase period; the normalized fields sit next to them and are null when the
source is absent or cannot be read confidently. German results may contain a
job preview instead of a full description; that preview is returned in
description.
via is worth a second look. It names the board Google took the advert from,
which is where the job actually lives, and it is often the company's own
careers site rather than an aggregator. Filtering on it is the quickest way to
separate first-party postings from reposts.
qualifications and responsibilities are the fields that make this cheaper
than reading the boards yourself. Google has already pulled the requirements
out of the prose, so a screen for "3+ years" or "Kubernetes" is a filter on a
list rather than a search through paragraphs.
Salary is present on a minority of adverts
Two adverts in ten carried a salary in the example above, and that is Google's
doing: the rest do not publish one. salary_text keeps the line exactly as
advertised because the same figure gets written a dozen ways across boards, and
the parsed salary_min / salary_max / salary_period sit next to it as a
convenience. When the two disagree, trust the text.
posted is similar: Google dates some adverts and leaves others undated. A
null means undated, not missed.
Apply links
Every apply link comes back as Google's own redirect. Turn on Resolve apply links to follow each one through to the board it lands on and get the real URL instead, capped by Maximum apply links to resolve. Links are resolved in dataset order; if a destination does not respond, its Google URL stays and the run reports a warning.
It is off by default because adverts carry up to eight links, which on a forty-advert run is a couple of hundred extra lookups to learn what the board's name already told you. Turn it on when you are going to open the links, leave it off when you are analysing the market.
Run summary and errors
summary in the key-value store reports queriesSent, jobs, withSalary,
withApplyLinks and queriesWithNoJobs. Check queriesWithNoJobs before
concluding a market is unavailable: some city-and-title pairs return nothing.
| Code | Meaning |
|---|---|
blocked | The search could not be read after every attempt |
bad_input | No search term was given |
A search Google answered with no jobs is not an error. The run succeeds
with an empty dataset and counts it in queriesWithNoJobs. Raise Attempts
per query if you see blocked.
Market and language
Country is the market the search is made for and Language is what the
page comes back written in. They are separate on purpose: an English-language
search of the German market is a normal thing to want, and pinning both to de
would change the results as well as the wording. Job results are regional, so
the same title returns different companies per market. To compare two
countries, run them as two runs and keep market on every row, which it
already is.
Use cases for Google Jobs data
- Recruiting and sourcing: every open role for a title across ten cities, with the board each one lives on and a direct apply link.
- Job market research: count adverts, salary ranges and required skills per role and city, and repeat the run weekly to see demand move.
- Hiring signals for sales: a company advertising five data engineer roles
is buying data tooling.
company,titleandpostedare the trigger. - Job boards and aggregators: fill or check your own listings against what Google shows for the same search.
- Salary benchmarking:
salary_min,salary_maxandsalary_periodper title and location, with the original line kept for audit.
Google Jobs scraper vs. Google Jobs API and other job scrapers
Google does not offer a public API for its jobs results. The "Google Jobs API" that turns up in search is Cloud Talent Solution, which searches the jobs you upload, not the market. Commercial SERP APIs return the same Google Jobs results but bill per request, usually on a monthly plan, and leave the salary parsing and deduplication to you.
Board-specific scrapers (LinkedIn, Indeed, XING) are deeper on one board but see only that board. This actor reads the merged view, so one row already tells you every board the advert is on. Use both: this actor to find the market, a board scraper when you need that board's own fields. For the companies behind the adverts, the LinkedIn company actors fit next to it.
Pricing
Pay per event, unchanged:
- $0.002 per run (
run_start), charged once. - $0.0015 per job advert delivered (
job).
Resolving apply links costs nothing extra. A run that finds no jobs costs only the start fee; failed searches generate no advert charges, and a duplicate advert is charged once. A hundred adverts cost $0.152. Free-plan users receive up to ten adverts per run and pay only for the rows delivered.
FAQ
Why do I get only ten jobs for a search?
Google returns ten cards for one search on this surface. Increasing maxItems
does not raise that ceiling. Add search terms or cities to collect more.
Can I get the actual application URLs?
Yes. Enable resolveApplyLinks. The actor follows apply links in dataset
order, up to maxApplyLinksResolved. If a destination does not respond, its
original Google URL stays available.
Does an empty salary mean the scraper missed it?
No. Many adverts do not publish a salary. The fields stay null when Google does not show one; the actor never estimates missing salaries.
Are repeated vacancies charged twice?
No. The first occurrence of each Google job id wins across the whole run, and each delivered advert is charged once.
Can I scrape Google Jobs outside the United States?
Yes. Set region to the country code, for example de or gb, and
language to the language you want the results in.
Can I schedule it?
Yes. Use an Apify schedule to run the same searches daily or weekly and compare
job_id between runs to see which adverts are new.