How to scrape Google results with Python and Oxylabs
In this tutorial, we showcase how to scrape public Google data with Python and Oxylabs API.
At a glance
- What is it?
- oxylabs/scrape-google-python is a tutorial for retrieving public Google result pages through Oxylabs SERP Scraper API. It suits developers who already have Python credentials for the paid service, but it is not a standalone scraper or a general search client.
- Who is it for?
- Adopt this tutorial if you already need an Oxylabs subscription and want a minimal Python integration for public Google SERPs. Do not treat it as a complete collection pipeline, a local scraping library, or a substitute for checking Google's terms and applicable law.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 126 days ago.
- What is it written in?
- GitHub does not report a main language for this repository.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What oxylabs/scrape-google-python actually provides
oxylabs/scrape-google-python is a tutorial repository with one visible top-level entry, README.md. It does not present itself as an installable Python package. Its purpose is narrower: show how an application can send a search request to the Oxylabs SERP Scraper API and receive a Google results page.
The intended audience is a Python developer who needs public Google search data through a hosted Oxylabs service. The README says users need Python 3.8 or later, the Requests library, and credentials for Oxylabs SERP Scraper API. It also states that access requires a subscription or a free trial. That dependency is important because the repository does not contain the scraping engine. Google retrieval, request routing, and result delivery occur through Oxylabs.
The repository is designed around SERPs, meaning Search Engine Results Pages. Its introduction lists featured snippets, paid advertisements, a video carousel, People Also Ask, local results, and related searches as examples of elements found on Google result pages. However, the demonstrated output contains an HTML document under the `content` key. The tutorial does not show a parser that turns that HTML into titles, links, rankings, advertisements, or local-pack records. Developers who need those fields must add a separate extraction layer or request a suitable structured interface outside what this README demonstrates.
The POST request path from Google query to response
The basic flow uses Python Requests to make a POST request to `https://realtime.oxylabs.io/v1/queries`. The JSON payload contains a `source` value and either a Google `url` or structured search parameters. Oxylabs Basic Authentication uses the account username and password included in the request.
In the URL-oriented form, `source` is `google` and `url` points to `https://www.google.com/search?hl=en&q=newton`. Oxylabs processes that request and returns a response object with a `results` list. According to the documented shape, each item includes `content`, `created_at`, `updated_at`, `page`, `url`, `job_id`, and `status_code`. The example shows a successful item with HTTP status 200 and an HTML string under `content`.
The README also describes a parameterized form based on `google_search`. In that mode, the payload includes `query` and may add localization settings such as `geo_location` and `locale`. This avoids constructing the full Google search URL in client code. The documentation makes an important interface distinction: `google_search` cannot be combined with `url`. A developer must choose either a source that consumes a complete URL or a structured source whose query parameters define the request.
No retries, timeout, pagination implementation, status inspection, rate-limit handling, or exception handling appears in the shown code, even though the README table of contents mentions handling errors and exceptions. The excerpt should therefore not be treated as a production HTTP client.
Installing Requests and sending the first Google query
The repository gives installation instructions for the dependency used by its example. It asks readers to install Python 3.8 or above from python.org, obtain Oxylabs SERP Scraper API credentials, and install Requests through Python's package installer.
The documented installation command is:
$python3 -m pip install requestsThis installs the Requests library for Python 3. On Windows, the README says to use `python` instead of `python3`, while retaining the rest of the command:
python -m pip install requestsA first request can be placed in a new Python file using the tutorial's structure. Replace the example authentication values through your own credential handling rather than assuming the placeholders are valid account names:
import requests
from pprint import pprint
payload = {
'source': 'google',
'url': 'https://www.google.com/search?hl=en&q=newton'
}
response = requests.request(
'POST',
'https://realtime.oxylabs.io/v1/queries',
auth=('USERNAME', 'PASSWORD'),
json=payload,
)
pprint(response.json())The README says a successful response should contain a `results` list. The displayed item has a status of 200 and an HTML string in `content`. The `job_id` and timestamps are returned as request metadata. The example prints the decoded JSON but does not save the HTML, validate credentials, or raise an exception for an unsuccessful HTTP response.
Choosing source, query, and localization fields
The payload's `source` field selects the Oxylabs scraper and determines which other fields are valid. The README uses `google` with a full `url`, then also introduces `google_search` with a `query`. It mentions other Google-related sources, including `google_ads`, `google_travel_hotels`, and `google_lens`, but the visible tutorial does not define their payloads. It links to Oxylabs developer documentation for the broader target list.
For a structured search request, the smallest documented payload is:
payload = {
'source': 'google_search',
'query': 'newton',
}This form separates the search term from the destination page. It is more convenient when application code should not assemble a Google URL. The tradeoff is strict parameter compatibility. The README explicitly says that `google_search` cannot use `url`; adding it would create a request outside the documented example rather than combining two optional settings.
Localization is expressed with fields rather than query-string fragments in the structured example:
payload = {
'source':'google_search',
'query':'newton',
'geo_location': 'Germany',
'locale' : 'en-us'
}The README links to separate Oxylabs documentation for accepted `geo_location` values and possible `locale` values. That distinction matters because the configured values must match the API's documented vocabulary. The excerpt mentions controlling the number of results and includes more parameters in its table of contents, but the visible README text does not preserve the corresponding examples. This article does not invent those parameter names or limits.
Raw HTML is the endpoint, not a parsed SERP dataset
The clearest boundary in this repository is between requesting a result page and extracting its individual elements. The documented `content` value is raw HTML beginning with a document declaration. There is no included HTML parser, selector library, schema, retry policy, CSV exporter, or persistence layer in the repository layout.
That design keeps the example small, but it moves work to the adopter. A developer who needs organic result titles, destination URLs, positions, advertisements, local listings, or related searches must define an extraction format and account for changes in Google's markup. The README does not claim that the returned HTML always has a stable structure, and it provides no compatibility policy for markup changes.
The README also points to exporting scraped data to CSV, but the visible excerpt does not provide that code. It would therefore be incorrect to describe this repository as a complete CSV export tool. Based on the top-level `README.md` entry, it is instructional source material rather than a reusable library with published release artifacts. For a small proof of integration, the documented POST request is enough. For an application that needs validated records, the missing parser and operational HTTP behavior are substantial additions.
A direct alternative is to build against Google's own public web interfaces or another search-data provider without Oxylabs. The difference is who controls access and result acquisition: this tutorial routes the request through Oxylabs, while a direct Google request places request handling and page retrieval in the developer's own application. The repository does not compare response schemas, pricing, limits, or output quality between those approaches.
Maintenance, releases, and license boundaries
The repository is not archived, and its last push was on 2026-06-19. That date records repository activity, but it does not establish that the tutorial covers every current Oxylabs API behavior. The repository also has no GitHub releases. This matters because there is no documented release cadence or versioned package through which consumers receive tutorial updates.
The repository is associated with Oxylabs and repeatedly directs readers to the company's dashboard and developer documentation. API behavior can therefore depend on an external hosted service even when the GitHub example remains unchanged. The README documents a seven-day free trial for obtaining credentials, but it does not state subscription pricing or quota details. Those commercial terms must be checked with Oxylabs rather than inferred from the example.
No license is identified in the repository metadata reviewed here, and the visible README contains no software license section. Consequently, the licensing status of copying or redistributing repository content cannot be established from the repository information. The presence of tutorial code also does not make the hosted API free or independent of a separate service agreement. Review the repository's license file and Oxylabs terms before incorporating substantial example code into a product.
Upgrade cost appears low for the tiny request example because there is no local scraper engine or dependency set beyond Requests. The external API may still require adaptation when Oxylabs changes its source parameters or response contract. The README's external developer links are therefore more important to the integration than the absence of GitHub releases might suggest.
Editorial conclusion
Adopt this tutorial if you already need an Oxylabs subscription and want a minimal Python integration for public Google SERPs. Do not treat it as a complete collection pipeline, a local scraping library, or a substitute for checking Google's terms and applicable law. Before adoption, verify your API plan, the intended source mode, the licensed account credentials, and whether your application needs parsed result data rather than raw HTML.
Frequently asked questions
What does oxylabs/scrape-google-python require before the first request?
It requires Python 3.8 or later, the Requests library, and credentials for Oxylabs SERP Scraper API. The README says the service requires a subscription or a free trial.
Does oxylabs/scrape-google-python return parsed Google results?
The demonstrated response returns the Google page as HTML in the `content` field. The repository does not show code that parses that HTML into structured result fields.
Can `google_search` and `url` be used together in oxylabs/scrape-google-python?
No. The README explicitly states that setting `source` to `google_search` prevents use of the `url` parameter; that mode uses fields such as `query` instead.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/oxylabs-scrape-google-python)Was this useful?