# How to Scrape Google Jobs with Python and Oxylabs

> This repository provides a Python CLI that saves basic Google Jobs results to `jobs.csv`, along with a separate Oxylabs API tutorial for asynchronous collection across multiple queries and locations.

**oxylabs/how-to-scrape-google-jobs** — Learn how to build your own Google Jobs scraper that simultaneously scrapes Google Jobs for multiple search queries and geo-locations with Python and Oxylabs’ Google Jobs Scraper API. https://oxylabs.io/blog/how-to-scrape-google-jobs

- Repository: https://github.com/oxylabs/how-to-scrape-google-jobs
- Stars: 1,770 · Forks: 9
- Language: Python
- License: not declared
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/oxylabs-how-to-scrape-google-jobs

## Local Google Jobs CSV Collection

The repository addresses a focused collection task: turning a Google Jobs search query into structured records stored locally. Its primary audience is Python developers who want a small command-line utility rather than a full job aggregation platform. The local route creates a file named `jobs.csv` with four documented attributes: `title`, `company`, `location`, and `url`. The URL points to the Google Jobs page for the corresponding listing.

That output is sufficient for basic inspection or as input to a later processing stage. It is not a complete job database. The README does not document deduplication, pagination controls, recurring schedules, historical tracking, or persistence beyond the generated CSV. It also does not explain how the scraper treats duplicate listings, missing salary information, multiple locations, or partial results.

Based on the repository layout, the implementation is packaged under `src` and configured through `pyproject.toml`. The package is named `google-jobs-scraper`, and its declared version is `0.1.0`. It targets Python `^3.11`. Direct dependencies include `pydantic`, `click`, `pandas`, `selenium`, `webdriver-manager`, and `pydantic-settings`. Selenium and `webdriver-manager` point to browser automation in the free route, while Click provides the command-line interface and pandas supports tabular output.

The README does not identify the browser version, proxy configuration, retry policy, selectors, or capture behavior. Consequently, those implementation details cannot be confirmed from the documentation. The package metadata also does not state a license, which leaves reuse and redistribution permissions unclear.

## Installing the Python CLI

The README requires Python 3.11 for the free scraper. From a terminal in the repository, run the documented installation target. It installs Poetry version `1.8.2` and then installs the project dependencies.

```bash
make install
```

The command is defined in the repository `Makefile`. Its first operation installs `poetry==1.8.2`; its second invokes `poetry install`. That makes the documented setup depend on the terminal environment's available Python packages and on Poetry resolving the dependencies declared in `pyproject.toml`.

The README does not provide a separate browser installation command. Although the dependency list contains `webdriver-manager`, the documentation does not state when or how a browser binary is acquired. Do not add browser flags, environment variables, or versions that the repository does not document.

After installation, the CLI is launched through another `Makefile` target. Search text must be supplied through `QUERY`, and the README explicitly recommends enclosing it in quotation marks. That is particularly important when the query contains spaces, because the shell must pass one query value into the Python module.

## Running the First Designer Search

The first complete local use documented in the README is a search for designer jobs. Run the `scrape` target from the repository directory.

```bash
make scrape QUERY="designer"
```

The `Makefile` checks whether `QUERY` is empty before starting Python. If it is empty, the target prints an error and exits. The command text itself explains the expected target and query form. The documented `Makefile` also invokes the installed package module through Poetry and supplies the query with the `--query` option.

When the scraper finishes, the README says a file named `jobs.csv` should be present in the current directory. It describes the following fields:

- `title` is the position title.
- `company` is the employer's name.
- `location` is the job location.
- `url` is the Google Jobs page URL.

The tutorial includes screenshots showing terminal output and sample CSV data, but it does not specify a guaranteed number of rows or a complete order for results. It also does not state the file encoding, treatment of missing values, or whether repeated listings are removed. Inspect `jobs.csv` after the first run rather than assuming that every search produces the same shape or volume.

## Oxylabs API Request and Parsing Flow

The second tutorial changes the collection boundary from a local browser-driven command to Oxylabs Web Scraper API. It requires an Oxylabs dashboard account, an API user, and credentials used to authenticate requests. The README describes a one-week free trial for Google Jobs API access.

Its first request asks Oxylabs to render a Google search as HTML. The example searches for developer jobs with `hl=en` and `gl=us`. Replace the credential placeholders in the documented example with the username and password from your API user.

```python
import requests

payload = {
    "source": "google",
    "url": "https://www.google.com/search?q=developer&ibp=htl;jobs&hl=en&gl=us",
    "render": "html"
}

response = requests.post(
    "https://realtime.oxylabs.io/v1/queries",
    auth=("USERNAME", "PASSWORD"),
    json=payload
)
print(response.json())
print(response.status_code)
```

The README says a successful test returns a JSON response containing HTML results and status code `200`. This example retrieves rendered HTML. It does not yet show parsed job records.

For the larger workflow, the tutorial introduces asynchronous requests with `aiohttp`, JSON handling with `json`, and CSV processing with `pandas`. Its documented parser targets job title, company name, location, listing date, salary, the platform through which the job was posted, and URL. Later sections describe functions for submitting a job, checking status, retrieving results, saving CSV data, and coordinating the scrape through a main function. The README also says additional API calls can retrieve job highlights, descriptions, and similar jobs from scraped URLs.

The README does not provide exact rate limits, pricing, retry intervals, status values, parser payload keys, or completeness guarantees. Those details must be established from the dashboard documentation and repository implementation before using the hosted workflow for a production dataset.

## Hosted API and Local Browser Trade-offs

The local command and the Oxylabs workflow address overlapping but different requirements. The local route is easy to describe: pass one `QUERY`, run the Python package through Make, and inspect `jobs.csv`. It uses the browser automation dependencies declared in `pyproject.toml`. Its output contract is limited to four documented fields.

The hosted route requires an account and credentials, but its architecture is intended for collection at greater scale. The repository description specifically calls out simultaneous scraping for multiple search queries and geo-locations. The tutorial also adds asynchronous request handling and parser instructions for fields such as salary and listing date. That difference is architectural, not merely cosmetic. A local single-query command and a credentialed asynchronous API client impose different setup and operating requirements.

The free local approach is the clearer choice when the requirement is a small CSV for one search. It avoids the documented Oxylabs account requirement, although browser readiness remains an unresolved operational dependency. The Oxylabs route is more relevant when the project needs multiple searches, additional parsed fields, or delegated request handling. The repository does not document API pricing beyond mentioning a trial, so cost cannot be calculated from this documentation.

Neither route is documented as a complete recruiting platform. There are no documented integrations with an applicant tracking system, job taxonomy service, notification system, or warehouse. The outputs are collected Google Jobs records rather than verified employment offers. The README does not explain what happens when Google omits a field, when a listing expires, or when the same vacancy appears under multiple employers or locations.

## Maintenance, Releases, and Licensing

The repository is not archived, and the last push was on 2026-06-19. The repository has no GitHub releases. Although `pyproject.toml` declares version `0.1.0`, there is no documented release schedule or changelog. Recent repository activity therefore does not by itself establish compatibility with future Google pages or a predictable upgrade path.

Python and browser automation add upgrade considerations. `pyproject.toml` constrains the project to Python `^3.11` and pins dependency ranges for packages including Selenium, pandas, Pydantic, and `webdriver-manager`. The README does not document an upgrade procedure, a supported browser matrix, or a migration path between package versions. The Makefile installs a specific Poetry version, so changes to that line could also affect dependency installation.

The repository license is unknown. Neither the repository listing nor the documented `pyproject.toml` content identifies a license. As a result, the documentation does not establish permission to copy, modify, or redistribute the code. Do not infer those permissions from public access.

Oxylabs account and API use is separate from the repository's own licensing. The README directs users to the Oxylabs dashboard for the hosted service and does not state service pricing or account terms. Review those service terms directly before sending queries or storing returned data.

## Choosing a Google Jobs Collection Route

Use the local Make-based CLI when the immediate requirement is one Google Jobs query and a four-column CSV. Its shortest documented path is `make install`, followed by `make scrape QUERY="designer"`. Confirm that Python 3.11 is present, that Poetry installs the declared dependencies, and that Selenium can access a suitable browser environment before relying on the output.

The Oxylabs workflow is the alternative for developers who need multiple queries, geo-locations, asynchronous requests, or parser instructions covering salary and listing date. That route adds an account, API credentials, network requests to `https://realtime.oxylabs.io/v1/queries`, and service-specific behavior. It should be evaluated separately from the local scraper rather than treated as an automatic replacement.

Do not adopt the repository as a universal job-data platform. It has no GitHub releases, no documented license, and no documented guarantees for completeness, deduplication, uptime, or response handling. The first project-specific check is therefore `pyproject.toml`, followed by a review of the generated `jobs.csv` and the exact Oxylabs parser implementation chosen for a hosted workflow.

## Conclusion

Adopt the local CLI for a single-query CSV workflow after checking its Selenium and browser setup. Consider the Oxylabs route when multiple queries or geo-locations justify a hosted service and API credentials. Do not treat the repository as a general-purpose job database. The README documents no release history, and the repository files state no license, so verify `pyproject.toml`, the current Python environment, and expected CSV fields before adoption.

## FAQ

### What does how-to-scrape-google-jobs produce?

The local scraper writes `jobs.csv` in the current directory. Its documented columns are `title`, `company`, `location`, and `url`.

### How do I run the free Google Jobs scraper for designer jobs?

Install the project with `make install`, then run `make scrape QUERY="designer"`. The README says the scrape command creates `jobs.csv` after completion.

### What credentials does the Oxylabs Google Jobs API tutorial require?

It requires API user credentials from an Oxylabs account, passed as the username and password in the API request. The README describes a one-week free trial for Google Jobs API access.

## Sources

- [Issues](https://github.com/oxylabs/how-to-scrape-google-jobs/issues)
- [oxylabs/how-to-scrape-google-jobs on GitHub](https://github.com/oxylabs/how-to-scrape-google-jobs)
- [README](https://github.com/oxylabs/how-to-scrape-google-jobs/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/oxylabs-how-to-scrape-google-jobs
