# Google Shopping Scraper (`barefoot_grade/google-shopping-scraper`) Actor

Collect Google Shopping offers for any search, country and language: product title, price and currency, previous price, store, rating and review count, delivery and returns notes, product link and image. Paging and item caps included; you only pay for offers delivered.

- **URL**: https://apify.com/barefoot_grade/google-shopping-scraper.md
- **Developed by:** [Philip Kirkbride](https://apify.com/barefoot_grade) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.20 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Google Shopping Scraper

Compare prices across stores in one table. Type the products you care about, pick a country and language, and every Google Shopping offer becomes one clean row: product title, current price as a number and as shown, currency, the "Was" or "Usually" price, the deal badge, the store, whether other stores sell it too, star rating and review count, delivery and returns notes, a link to the product's Google Shopping page and the product image.

Collect a quick snapshot of the first results or page deeper, with a cap per search and a cap for the whole run, so a long list of searches never runs away. You only pay for offers delivered; pages that cannot be read are listed in the run summary and are not charged.

### Use cases

- **Price monitoring**: track what stores charge for your products, or your competitors', on a schedule.
- **Competitor research**: see which stores list a product, at what price, with what delivery and returns terms.
- **Deal discovery**: find offers below their usual price, with the discount badge Google shows.
- **Assortment and market research**: what sells under a search term in a given country, with ratings and review counts.
- **Catalog enrichment**: product titles, images and review counts for a list of products.

### Quick Start

```json
{
  "queries": ["wireless earbuds", "espresso machine"],
  "countryCode": "us",
  "languageCode": "en",
  "maxItemsPerQuery": 50,
  "maxItems": 1000
}
```

Each search is one Google Shopping search. Google lists about 40 to 60 offers per results page; set `maxItemsPerQuery` higher to read further pages. Paging stops by itself when a search runs out of new offers.

### Input

| Input | Type | Default | Meaning |
| --- | --- | --- | --- |
| `queries` | array | required | What to search for, one search per line, exactly as you would type it (`espresso machine`, `nike air max 90`). A Google search link (`google.com/search?q=...`) also works. Repeated searches are read once. |
| `countryCode` | string | `us` | Two-letter code of the shopping market (`us`, `gb`, `de`, `fr`, `ca`, `au`, `in`, ...). Prices, stores and currency follow that country. |
| `languageCode` | string | `en` | Language of the result text, such as delivery and returns notes (`en`, `de`, `fr`, `es`, ...). |
| `maxItemsPerQuery` | integer | `100` | Offers to collect per search, 1 to 1,000. |
| `maxItems` | integer | `1000` | Total cap on offers (dataset rows) across every search, up to 20,000. |
| `maxConcurrency` | integer | `3` | Searches that run side by side, 1 to 5. |

### Example queries

- `{"queries": ["4k monitor", "mechanical keyboard"], "maxItemsPerQuery": 100}`
- `{"queries": ["kaffeevollautomat"], "countryCode": "de", "languageCode": "de"}`
- `{"queries": ["electric kettle", "air fryer"], "countryCode": "gb"}`
- `{"queries": ["https://www.google.com/search?q=running+shoes"]}`

### What it returns

The dataset contains one row per offer:

| Field | Meaning |
| --- | --- |
| `position` | 1-based rank of the offer within its search, across pages. |
| `title` | Product title as listed. |
| `price` | Current price as a number. For a "from" price shown as `$640+`, the lowest price. |
| `priceText` | The price exactly as shown, for example `$249.99`, `419,00 €` or `$640+`. |
| `currency` | ISO currency code, such as `USD`, `EUR` or `GBP`. |
| `originalPrice` | The previous or typical price as a number, when the offer shows one. |
| `originalPriceText` | That price as shown, for example `Was $599` or `Usually $299`. |
| `hasMorePrices` | Google notes that more prices are available for the product. |
| `condition` | Condition label when shown, for example `Used` or `Refurbished`. |
| `badge` | Deal badge, for example `8% OFF` or `Low price`. |
| `merchant` | The store selling the offer. Empty for a "from" price across several stores. |
| `moreStores` | Other stores also sell this product. |
| `rating` | Average product rating out of 5. |
| `reviewsCount` | Number of reviews (`3.6K` becomes `3600`). |
| `delivery` | Delivery note, for example `Free delivery by Wed`. |
| `returns` | Returns note, for example `30-day returns`. |
| `productLink` | The product's Google Shopping page, with prices from every store. |
| `imageUrl` | Product image. |
| `productId`, `offerId` | Google's ids for the product and for this offer. |
| `searchQuery` | The search the offer came from: `term`, `page`, `countryCode`, `languageCode`. |
| `scrapedAt` | Collection time (UTC, ISO 8601). |

Fields that an offer does not show are `null`. The run summary (`OUTPUT`) reports `offers` (rows delivered), `pages` read, searches with no results in `emptyQueries`, and any page that could not be read in `pageErrors`, each with a short code and message (for example `BLOCKED`, `LAYOUT_CHANGED` or `NETWORK_ERROR`).

### Output example

```json
{
  "position": 4,
  "title": "Gaggia Classic E24 Iconic espresso machine for your home",
  "price": 549.0,
  "priceText": "$549.00",
  "currency": "USD",
  "originalPrice": 599.0,
  "originalPriceText": "Was $599",
  "hasMorePrices": false,
  "condition": null,
  "badge": "8% OFF",
  "merchant": "Whole Latte Love",
  "moreStores": true,
  "rating": 2.9,
  "reviewsCount": 831,
  "delivery": "Free delivery by Sat",
  "returns": "30-day returns",
  "productLink": "https://www.google.com/search?ibp=oshop&q=Gaggia+Classic+E24+Iconic+espresso+machine+for+your+home&prds=catalogid%3A10095501518220150894%2Cgpcid%3A14862320879344990550%2CheadlineOfferDocid%3A3644310309703997006%2CimageDocid%3A7557753840327796041%2CproductDocid%3A17420663260271296052%2Cpvt%3Ahg&hl=en&gl=us&udm=28",
  "imageUrl": "https://encrypted-tbn1.gstatic.com/shopping?q=tbn:ANd9GcSPNnYW3QhnZICjzkZeAi5mV3wH-G_V28yf2MWTNAUfQr2Q7oVyDUpMSFCKLFAWUKzqyT9INcOmFQ",
  "productId": "10095501518220150894",
  "offerId": "3644310309703997006",
  "searchQuery": {
    "term": "espresso machine",
    "page": 1,
    "countryCode": "us",
    "languageCode": "en"
  },
  "scrapedAt": "2026-10-20T00:31:12Z"
}
```

### Price

**$0.0022 per offer** delivered (one dataset row), plus **$0.005 per run start**. The run-start event is charged per GB of memory; the default 512 MB run is one start event ($0.005). The start is charged even if the run saves no offers. Pages that could not be read are not charged. Platform usage is included in these prices. 1,000 offers cost $2.20 plus the start.

### Good to know

- Google shows each shopper a slightly different selection, so offers and their order can differ from what you see when signed in to your own Google account. Results here are what a signed-out shopper in the chosen country sees.
- Prices come from the chosen country's shop, in its currency. A few offers from stores abroad can appear (for example `US$120.00` in Canada), and `currency` always says which currency a price is in.
- The same product can be listed in several places on a results page; each offer is delivered once per search.
- The store's own product page is one click away from `productLink`, which lists every store's price for the product.
- Most searches run out of new offers after a few pages (roughly 100 to 250 offers), so very high `maxItemsPerQuery` values may return fewer offers.
- Searches that return no offers are listed in `OUTPUT.emptyQueries`. If a run's searches keep returning almost nothing, the run stops early and says so, rather than reading empty pages.
- If Google temporarily limits requests, the run retries with growing pauses and reports any page it could not finish in `OUTPUT.pageErrors`; offers already collected are kept. If no page at all can be read, the run fails with a clear message.

# Actor input Schema

## `queries` (type: `array`):

What to search for on Google Shopping, one search per line, exactly as you would type it (for example: espresso machine, nike air max 90). A Google search link (google.com/search?q=...) also works.

## `countryCode` (type: `string`):

Two-letter country code of the shopping market, such as us, gb, de, fr, ca, au or in. Prices, stores and currency follow that country.

## `languageCode` (type: `string`):

Language of the result text (delivery and returns notes, conditions), such as en, de, fr or es.

## `maxItemsPerQuery` (type: `integer`):

How many offers to collect per search. Google lists about 40 to 60 offers per results page; more pages are read until this number is reached or the results run out.

## `maxItems` (type: `integer`):

Total cap on offers (dataset rows, and so on cost) across every search.

## `maxConcurrency` (type: `integer`):

How many searches run side by side. Higher is faster.

## Actor input object example

```json
{
  "queries": [
    "wireless earbuds",
    "espresso machine"
  ],
  "countryCode": "us",
  "languageCode": "en",
  "maxItemsPerQuery": 50,
  "maxItems": 1000,
  "maxConcurrency": 3
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "queries": [
        "wireless earbuds",
        "espresso machine"
    ],
    "countryCode": "us",
    "languageCode": "en",
    "maxItemsPerQuery": 50,
    "maxItems": 1000
};

// Run the Actor and wait for it to finish
const run = await client.actor("barefoot_grade/google-shopping-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "queries": [
        "wireless earbuds",
        "espresso machine",
    ],
    "countryCode": "us",
    "languageCode": "en",
    "maxItemsPerQuery": 50,
    "maxItems": 1000,
}

# Run the Actor and wait for it to finish
run = client.actor("barefoot_grade/google-shopping-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "wireless earbuds",
    "espresso machine"
  ],
  "countryCode": "us",
  "languageCode": "en",
  "maxItemsPerQuery": 50,
  "maxItems": 1000
}' |
apify call barefoot_grade/google-shopping-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,barefoot_grade/google-shopping-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/rmj9M8gc9OU2t1vDS/builds/bzPr4dh5OHSYLDHgM/openapi.json
