Google Jobs Scraper
Pricing
from $1.50 / 1,000 job listings
Google Jobs Scraper
Scrape job listings from Google Jobs. Each job has a stable ID, employer, location, apply URLs, posting date and salary. You also get the site the job came from. Job details come when Google shows them. It tries a direct request first, then a browser.
Pricing
from $1.50 / 1,000 job listings
Rating
0.0
(0)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
4
Total users
2
Monthly active users
15 hours ago
Last modified
Categories
Share
Google Jobs Scraper: listings, employers and the boards they came from
Search the public Google Jobs results and get one row per listing: the job title, the employer, the location, which board Google picked it up from, Google's own stable job ID, the employment type and a link to the Google listing page.
The awkward part, stated plainly because it decides whether this fits your project. Google does not
put the apply link in the results it serves, so applyUrl comes back null. What you get instead
is applyOptions, the board names Google lists, and googleJobUrl, the listing page that carries
the working apply buttons. salary and description come back null on that same path.
| Input | Job keywords, and optionally a location |
| Output | One row per job listing |
| Ceiling | 100 jobs per run, 8 scroll rounds |
| Account needed | None. No Google API key, no job board login |
| Price | $1.50 per 1,000 jobs, flat on every plan |
💼 What Google Jobs Scraper does
It runs your keywords against Google's jobs results for one country and language, reads the listing cards, and writes a row each.
The identity fields. jobId is Google's own htidocid, so the same listing keeps the same ID
between runs and deduping is easy. When Google does not give one, a stable hash of the title,
employer, location and link is used instead.
The routing fields. source is the board Google credits, like LinkedIn or Indeed.
applyOptions lists every board Google offers for that listing. googleJobUrl opens the listing
where the apply buttons live.
Duplicates are removed by Google's ID within a run, so the same posting surfacing twice arrives once.
📥 What you give it
{"query": "software engineer","location": "Toronto","country": "CA","maxItems": 25,"maxScrolls": 3,"deadlineSeconds": 90}
| Field | Default | What it is |
|---|---|---|
query | box starts at software engineer | Job title, skill or keywords. |
location | empty | City, region, country or a remote location. Set country to match it. |
country | US | Two-letter Google country code. This is the edition being searched. |
language | en | Google interface language, like en, fr or de. |
maxItems | 25 | Unique job rows to return, 1 to 100. It is also the most a run can bill you. |
maxScrolls | 3 | Rounds of loading more listings after the first set, 0 to 8. |
deadlineSeconds | 90 | Seconds allowed for fetching, 20 to 180. Read the note below. |
enableProxyFallback | on | Leave it on. Off means a refused first request has nowhere to go and the run returns no jobs. |
proxyConfiguration | leave it alone | Optional. Your own servers are used exactly as given. |
Set country to match your location. This is the one mistake that reliably returns nothing.
Asking for Berlin while country is still US comes back empty; Berlin with country: "DE"
returns jobs. Change both together.
deadlineSeconds bounds the fetching, not the whole run. A run can take longer than the number
you set, because the steps that follow a slow fetch are not inside that budget.
📤 What you get back
A real row from a recent run, with the long Google link cut short:
{"ok": true,"jobId": "kqGSSHMeuPf_Dy4XAAAAAA==","title": "Software Engineer - E3","company": "Lockheed Martin","location": "Longmont, CO","source": "LinkedIn","applyUrl": null,"sourceUrl": null,"datePosted": "3 days ago","salary": null,"description": null,"employmentType": "Full-time","query": "software engineer","searchLocation": null,"country": "US","googleJobUrl": "https://www.google.com/search?ibp=htl;jobs&q=software+engineer&htidocid=kqGSSHMeuPf_Dy4XAAAAAA%3D%3D&hl=en-US...","applyOptions": ["LinkedIn", "BeBee"]}
| Field | What it is |
|---|---|
jobId | Google's htidocid. Stable between runs, so it is the key to dedupe on. |
source | The board Google credits the listing to, taken from its "via" line. |
applyOptions | Every board Google offers for that listing, by name. |
googleJobUrl | The Google listing page. This is where the apply buttons actually work. |
applyUrl, sourceUrl | null. Google does not serve them in these results. |
datePosted | Google's own wording, like 3 days ago. Not a date. |
salary, description | null on this path, even when Google prints them on the page. |
employmentType | Full-time, Contractor and so on, when Google states it. |
🧾 Reading the output
| Row | How to spot it | Charged |
|---|---|---|
| A job listing | ok: true and no _sample | yes |
| The sample row | _sample: true | no |
| A diagnostic | ok: false and an errorCode | no |
An empty query writes the sample row and stops, so you can see the shape before spending anything.
| Code | What it means |
|---|---|
NO_RESULTS | Google returned no listing cards. A location that does not match country lands here. |
BAD_INPUT | A value in the input is not usable, for example a country code that is not two letters. |
BLOCKED | Google would not serve that request. Re-run it or narrow the search. |
RATE_LIMITED | Google answered with a rate limit. Wait and try again. |
JS_REQUIRED | Google served a page that builds itself in the browser instead of listing cards. |
SERVER_ERROR | Google answered with an error of its own. |
NETWORK | Google was unreachable or the response never finished. |
The Overview table shows applyUrl, which is always empty, and hides googleJobUrl, applyOptions
and employmentType, which are not. Read the dataset as JSON or export it.
▶️ How to run it
- Open Google Jobs Scraper and click Try for free.
- Put your keywords into Job keywords, replacing the example.
- Type a Location, then set Google country to that country's code. Both, every time.
- Set Maximum jobs, then click Start.
- Download the dataset as JSON, CSV or Excel, or read it from the Apify API.
💰 How much does it cost?
$1.50 per 1,000 jobs, which is $0.0015 a row. The same rate on every Apify plan, no volume tiers.
A job is charged only once a complete row has been written. maxItems caps the rows, so it also
caps what a run can bill.
Not charged as jobs: the sample row, every diagnostic row, duplicates removed within a run, and a search that comes back with nothing.
💡 What people use it for
- Watching a job title in one city daily and alerting on new
jobIdvalues. - Seeing which boards a company posts through, by counting
sourceandapplyOptionsacross a role. - Building a picture of hiring in a market, by running the same keywords against several
countrycodes. - Feeding titles, employers and locations into a CRM, using
googleJobUrlas the link a human opens.
🚧 What it does not do
- No apply links.
applyUrlandsourceUrlarenull. UseapplyOptionsfor the board names andgoogleJobUrlfor the page with the working buttons. - No salary, no description. Both come back
nullon this path, even where Google shows them. datePostedis relative text, like2 days ago. Convert it against the run time if you need a date.- Expect roughly ten listings from one search. The 100 ceiling is a limit, not a promise, and
maxScrollsasks Google for more without guaranteeing it. - Australia and Ireland come back empty right now. Confirmed working today:
US,GB,DE,FR,ES,CA. Try one small search before planning a large run against anywhere else. - A listing with no employer name is skipped, quietly, because a row without a company is not much use.
deadlineSecondsdoes not bound the whole run, only the fetching inside it.- One search per run. Use a schedule or several runs for a list of titles.
🧭 Which Google scraper do you need?
| If you want | Use |
|---|---|
| Job listings from Google Jobs | This one |
| The ordinary web results page for a keyword | Google Search Results Scraper |
| News articles with the publisher's real link | Google News Scraper |
| Image tiles and their source pages | Google Images Scraper |
| Employers as businesses, with address and phone | Google Maps Scraper |
❓ Questions people ask
Do I need a Google API key or a job board account? No. These are public search results.
Why is applyUrl empty? Because Google does not put it in the results it serves. Open
googleJobUrl and the apply buttons are there.
Why did my search return nothing? Nine times out of ten, country did not match location. Set
both to the same place and try again.
Can I filter by salary or date? Not in the input. datePosted comes back as Google's relative
wording and salary is not populated, so neither is something you can filter on here.
Can I schedule it? Yes. jobId is stable between runs, so diffing yesterday against today gives
you the new postings.
Is scraping Google Jobs legal? These are public listings. Apify's write-up on scraping and the law is a good starting point, and we are not lawyers.
🆘 If something breaks
Open the Issues tab on the actor page. Send the keywords, the location, the country and the run
ID. The errorCode on the diagnostic row usually names the problem on its own.