# Changelog of Google Jobs Scraper (`searchapi/google-jobs-scraper`) Actor

- **URL**: https://apify.com/searchapi/google-jobs-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/searchapi/google-jobs-scraper.md

## Changelog

All notable changes to the Google Jobs Scraper are documented here.

### \[3.3.0] - 2026-10-25

#### Added

- Static-SERP HTTP transport: when the configured proxy is Apify Proxy's HTTP-only `GOOGLE_SERP` group, the Actor requests the Jobs vertical (`udm=8`) over plain-HTTP absolute-URI forwarding and parses the result cards from Google's own SERP HTML. This is the default and is the only transport that reaches Google from a datacenter exit in this repo.
- `googleJobUrl`, taken from the card's own `data-share-url` (`htidocid=…`) deep link.
- Regression tests for the transport URL, card extraction, dataset-contract record mapping, page classification, and retry behaviour.

#### Changed

- Default `proxyConfiguration` is now `{ "useApifyProxy": true, "apifyProxyGroups": ["GOOGLE_SERP"] }`. Any other configuration uses the browser transport, and `GOOGLE_SERP` is stripped before a Chromium session is created because that group rejects a CONNECT tunnel with status 400.
- Transport selection, challenge classification, and the failed-closed summary now report the transport that actually ran.

#### Fixed

- `normalizeOutputRecord` crashed with `Cannot read properties of null (reading 'text')` on a card with no salary, because `typeof null === 'object'`; the salary and company unwrapping now guard against `null`.

### \[3.2.0] - 2026-10-25

#### Changed

- Removed unverified HTTP SERP and indexed source-page fallbacks. A Google challenge or unsupported Jobs page now ends in a failed run without trying another route or source.
- Added a structured failed-closed log summary with status, error code, query counts, and records pushed; confirmed no-result searches now report an explicit successful no-results status.
- Updated the README to document browser-only extraction and the current residential proxy default.

### \[3.1.0] - 2026-09-23

#### Changed

- Removed the public debug input and its input-dependent logging hooks.
- Kept card-load counts in ordinary Actor logs so extraction progress remains observable.
- Added explicit data-source, retrieval-method, page, and result-position provenance to normalized records.
- Enforced a 20-property minimum in the dataset contract and omitted remote when the listing does not expose a work arrangement.
- Removed filter inputs that the Actor did not apply to Google Jobs searches.
- Defined the nested locale, retrieval, and search metadata fields in the dataset schema.

### \[3.0.2] - 2026-08-28

#### Changed

- Unified native Google and structured source-page records into one 67-field output contract with stable IDs, result types, canonical URLs, and search metadata.
- Added globally deduplicated multi-query execution, bounded concurrency, sequential positions, and clean empty-result handling.
- Removed null, empty-string, and empty-array values recursively while preserving valid zero and false values.
- Made the dependency install reproducible across Windows and Linux, aligned the Playwright Docker image, and patched production dependency advisories.

#### Verified

- Local single-query run produced five rich jobs in about one minute despite a Google CAPTCHA by using validated public `JobPosting` pages.
- Local two-query run produced six unique jobs across both queries in about 71 seconds.
- Dataset audits found no required-field, type, URL, duplicate, empty-value, block-page, or sensitive-key issues.

### \[3.0.1] - 2026-07-22

#### Added

- Ported the jobsapi Google Jobs source-page fallback with Yahoo-indexed discovery and strict `JobPosting` JSON-LD extraction.
- Added rich company/salary details, structured locations, skills, requirements, benefits, application links, retrieval provenance, and source JSON-LD.
- Added additional-query and job-filter inputs, UTF-8 repair, Linux Impit bindings, and cloud/local dataset validation coverage.

### \[3.0.0] - 2026-07-20

#### Changed

- Replaced regular Google web-result heuristics with native Google Jobs (`udm=8`) card extraction.
- Added per-job detail expansion for apply links, full descriptions, qualifications, responsibilities, and benefits.
- Added bounded result loading, stable job-ID deduplication, strict input validation, session handling, and explicit block/failure reporting.
- Corrected dataset types for numeric salary values, booleans, arrays, objects, and string locations.
- Removed the unused direct proxy helper that could read credentials outside the Actor proxy configuration.

#### Breaking

- `remote` is now a boolean.
- `salaryMin` and `salaryMax` are numbers.
- `responsibilities`, `qualifications`, `benefits`, and `applyLinks` are arrays.
- Placeholder fields that Google did not expose were removed from the output contract.

### \[2.0.0] - 2026-06-12

#### Added

- **Schema expanded** from 30 to **45 fields**.
- **New fields**: `type`, `resultType`, `titleHtml`, `link`, `companyUrl`, `companyLogo`, `companyRating`, `companyReviewCount`, `city`, `state`, `country`, `remote`, `workplaceType`, `schedule`, `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod`, `responsibilities`, `qualifications`, `benefits`, `postedAtRaw`, `expiresAt`, `applyUrl`, `applyType`, `viaLogo`, `jobId`, `tags`, `query`.
- **New view**: `fullDetails` — all 45 fields.
- **INPUT.json** added at project root for local validation.

### \[1.0.0] - 2025-05-20

#### Added

- Initial production release of the Google Jobs Scraper.
- `PlaywrightCrawler`-based architecture using Chrome.
- Modular project structure.
- `validate-datasets.js` for local dataset output validation.
- `Dockerfile` using `apify/actor-node-playwright-chrome` image.
- `README.md` with full Apify usage guide.
