# Google Shopping Scraper - Product Prices & Offers (`parseforge/google-shopping-prices-scraper`) Actor

Scrape Google Shopping offers: title, price, original price, discount, merchant, rating, reviews, delivery and return terms. Export to CSV, JSON, Excel or XML.

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

## Pricing

from $1.26 / 1,000 product offers

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

![ParseForge Banner](https://github.com/ParseForge/apify-assets/blob/ad35ccc13ddd068b9d6cba33f323962e39aed5b2/banner.jpg?raw=true)

## 🛒 Google Shopping Prices Scraper

> 🚀 **Export Google Shopping offers in seconds.** One search query returns up to 40 offers per page with the current price, the struck-through original price, the discount percent, the merchant, the star rating, the review count and the delivery and return terms. 100 offers for "4k monitor" took 31 seconds on a 1 GB run.

Give the Actor one or more search queries and a country, and it reads the server-rendered Google Shopping results through Apify's Google SERP proxy, the route built for Google search pages. Every product card becomes one flat row with 21 fields, including Google's own product, cluster and offer IDs, so the same product can be tracked run after run. Price range, condition and sort order are handed to Google before the page is read, so filters never cost you rows.

Coverage is whatever Google Shopping serves for your query in the selected market: 39 countries and 21 interface languages are available in the input, pagination runs 40 offers per page up to Google's depth ceiling of about 400 per query, and multiple queries stack in one run.

| 🎯 Target Audience | 💡 Primary Use Cases |
|---|---|
| Price intelligence and revenue teams | Read the market price of a product across every merchant Google lists |
| Brands and manufacturers | See who sells your product, at what price, and who is undercutting MAP |
| Retail and e-commerce operators | Track competitor prices and promotion depth by category |
| Deal, coupon and affiliate sites | Find discounted offers with the original price and discount percent |

### 📋 What the Google Shopping Prices Scraper does

> 💡 **Why it matters:** Google answers datacenter and residential exits, browsers included, with HTTP 429 and a captcha, and its newer shopping tab ships no prices in the HTML. This Actor reads the server-rendered `tbm=shop` surface through the Google SERP proxy group, finds cards by their stable `data-pid` attribute and reads the screen-reader text Google maintains for each card, so a redesign of the CSS class names does not silently empty your dataset.

- 🏷️ **Price:** current price and currency symbol, the original price where Google prints one struck through, the discount percent and a Yes/No `isOnSale` flag.
- 🏬 **Merchant:** the merchant named on the card plus a Yes/No flag saying whether Google aggregates more sellers behind it.
- ⭐ **Reviews:** star rating and review count, with Google's `5.4K` shorthand expanded to a number.
- 🚚 **Terms:** the delivery line and the return window exactly as printed on the card.
- 🆔 **Identifiers:** Google's product, cluster and offer IDs, plus a Google Shopping product page URL for every row.
- 🖼️ **Thumbnail:** the encrypted-tbn image URL when Google links one (about 4 cards in 10; the rest are inlined as image bytes and reported as `Not Disclosed`).
- 🔁 **Filters that do not cost rows:** price range, condition and sort order are sent to Google; the on-sale and merchant filters are applied to the cards after they are read.

### 🎬 Full Demo (🚧 Coming soon)

A short walkthrough video is in production.

### 📊 Output

Each row is one Google Shopping offer. Fields, in dataset order:

| Field | Description |
|---|---|
| 🖼 `imageUrl` | Thumbnail URL from Google's image cache, or `Not Disclosed` when Google inlines the image instead of linking it |
| 📌 `title` | Product title as shown on the card |
| 🔗 `url` | Google Shopping product page for the offer's product ID |
| 🆔 `productId` | Google product ID, stable across runs |
| 🧩 `clusterId` | Google product cluster ID |
| 🏷 `offerId` | Google offer ID for this merchant listing |
| 💵 `price` | Current price as a number |
| 💱 `currency` | Currency symbol printed on the card (`$`, `£`, `€`) |
| 🏷 `originalPrice` | Struck-through original price, or `N/A` when the offer is not discounted |
| 📉 `discountPercent` | Discount percent printed by Google, `0` when there is none |
| 🔥 `isOnSale` | `Yes` when an original price higher than the current price is shown, else `No` |
| 🏬 `merchant` | Merchant named on the card |
| 🏪 `hasMultipleMerchants` | `Yes` when Google lists more sellers behind the card |
| ⭐ `rating` | Star rating out of 5, or `Not Disclosed` |
| 🗣 `reviewCount` | Number of reviews, or `Not Disclosed` |
| 🚚 `delivery` | Delivery line as printed, or `Not Disclosed` |
| ↩️ `returnPolicy` | Return window as printed, or `Not Disclosed` |
| 🔎 `query` | The search query that produced the row |
| 🌍 `country` | Market code used for the request |
| 🕒 `scrapedAt` | ISO timestamp of the collection |
| ❌ `error` | `null` on success; error rows carry only this field and are never charged |

Three real records from the cloud verification run (query "laptop", United States, Max Items 5):

```json
[
  {
    "imageUrl": "Not Disclosed",
    "title": "HP OmniBook X Flip 2-in-1 16\" 2K OLED Touchscreen Laptop",
    "url": "https://www.google.com/shopping/product/1381297317110928014?gl=us&hl=en",
    "productId": "1381297317110928014",
    "clusterId": "12265389182617013139",
    "offerId": "4553594992797254453",
    "price": 999.99,
    "currency": "$",
    "originalPrice": 1350,
    "discountPercent": 25,
    "isOnSale": "Yes",
    "merchant": "Best Buy",
    "hasMultipleMerchants": "Yes",
    "rating": 4.7,
    "reviewCount": 384,
    "delivery": "Free delivery by Wed",
    "returnPolicy": "15-day returns",
    "query": "laptop",
    "country": "us",
    "scrapedAt": "2026-09-08T04:54:00.649Z",
    "error": null
  },
  {
    "imageUrl": "Not Disclosed",
    "title": "Lenovo Yoga 7a 2-in-1 AI PC Laptop | 14 inch Wuxga Oled Touch (100% Dci-p3) | AMD Ryzen AI 5 340 (Up to 50 Tops) | 16gb Ddr5 1TB SSD | for Creator",
    "url": "https://www.google.com/shopping/product/14145348008510860685?gl=us&hl=en",
    "productId": "14145348008510860685",
    "clusterId": "16924392382734695053",
    "offerId": "12978534686114576382",
    "price": 1139.99,
    "currency": "$",
    "originalPrice": "N/A",
    "discountPercent": 0,
    "isOnSale": "No",
    "merchant": "Walmart - Happy Ranger",
    "hasMultipleMerchants": "No",
    "rating": "Not Disclosed",
    "reviewCount": "Not Disclosed",
    "delivery": "Free delivery",
    "returnPolicy": "Not Disclosed",
    "query": "laptop",
    "country": "us",
    "scrapedAt": "2026-09-08T04:54:00.650Z",
    "error": null
  },
  {
    "imageUrl": "Not Disclosed",
    "title": "HP OmniBook X Flip 2-in-1 14\" 2K OLED Touchscreen Laptop",
    "url": "https://www.google.com/shopping/product/2187320107212753054?gl=us&hl=en",
    "productId": "2187320107212753054",
    "clusterId": "16793559515556330662",
    "offerId": "17355904709601380764",
    "price": 1649.99,
    "currency": "$",
    "originalPrice": "N/A",
    "discountPercent": 0,
    "isOnSale": "No",
    "merchant": "Best Buy",
    "hasMultipleMerchants": "Yes",
    "rating": 4.7,
    "reviewCount": 384,
    "delivery": "Free delivery by Wed",
    "returnPolicy": "15-day returns",
    "query": "laptop",
    "country": "us",
    "scrapedAt": "2026-09-08T04:54:00.651Z",
    "error": null
  }
]
```

### ✨ Why choose this Actor

| | What you get |
|---|---|
| **It gets through** | Google answers residential and datacenter exits with a 429 captcha, browser included. This Actor uses Apify's Google SERP proxy group, the route built for Google search pages, and it is the default. |
| **The server-rendered surface** | The newer `udm=28` shopping tab is a client-rendered shell with zero prices in the HTML. This Actor reads `tbm=shop`, which ships every price server side: 68 cards in one response against none from the new tab. |
| **Parsed off stable hooks** | Cards are found by `data-pid` and read from the `aria-label` text Google maintains for screen readers. The CSS class names are per-deploy hashes and are never used. |
| **Server-side filters** | Price range, condition and sort order are handed to Google, so you are not paying for rows you then throw away. |
| **Explicit market** | `country` and `language` are set on every request. Without them Google prices in whatever market the exit node sits in. |
| **Honest blanks** | `N/A` and `Not Disclosed` instead of empty cells, so filters in Excel behave. |
| **You pay for what you keep** | Rows are billed as they are written and capped at Max Items; error rows are never billed. |

### 📈 How it compares to alternatives

Most Google Shopping scrapers on the Store render the page in a browser at 2 to 4 GB per run or rely on a third-party SERP API. This Actor reads the server-rendered page at 1 GB and states its ceilings up front.

| Feature | This Actor | Browser-based scrapers | Third-party SERP APIs |
|---|---|---|---|
| Memory per run | 1 GB | 2 to 4 GB | Not applicable |
| Original price, discount percent, on-sale flag | Yes | Varies | Varies |
| Delivery line and return window | Yes | Rare | Rare |
| Google product, cluster and offer IDs | Yes | Rare | Varies |
| Server-side price, condition and sort filters | Yes | Varies | Varies |
| Merchant destination URL | No, Google builds it in the browser | Sometimes | Sometimes |
| Thumbnail URL | About 4 cards in 10 | Varies | Varies |
| Depth per query | About 400 offers, Google's own ceiling | Same ceiling | Same ceiling |
| Extra API key | No | No | Yes |

### 🚀 How to use

1. [Create a free Apify account with $5 in credit](https://console.apify.com/sign-up?fpr=vmoqkp).
2. Open the [Google Shopping Prices Scraper](https://apify.com/parseforge/google-shopping-prices-scraper?fpr=vmoqkp).
3. Type your search queries, pick the country, set Max Items and any price, condition or sort filter, then click **Start**.
4. Download the dataset as CSV, Excel, JSON or XML from the **Storage** tab, or read it through the API.

A first run:

```json
{
  "queries": ["laptop"],
  "maxItems": 10,
  "country": "us",
  "language": "en",
  "sortBy": "price-low",
  "minPrice": 300,
  "maxPrice": 900
}
```

Free-plan runs return up to 10 offers as a preview. [Upgrade your Apify plan](https://console.apify.com/sign-up?fpr=vmoqkp) to collect up to 1,000,000 offers per run.

### 💼 Business use cases

**📉 Price history without a data vendor.** A price intelligence team schedules the same 50 queries daily, keeps `productId`, `merchant` and `price`, and diffs the runs. The product ID is stable, so the diff is the price history.

**🔎 MAP and undercutting alerts.** A brand searches its own product names, sorts by price low to high and reads the `merchant` column. Any row under the minimum advertised price is a violation with the seller's name attached.

**🌍 Cross-market comparison.** Run the same query with `country` set to `us`, `gb` and `de`. Google prices in the local currency and the currency symbol is on every row.

**🔥 Deal discovery.** A coupon site runs a category query with `onlyOnSale` on, then ranks rows by `discountPercent` to publish the day's deepest cuts with the original price beside them.

### 🔌 Automating Google Shopping Prices Scraper

- **Make and Zapier:** run the Actor on a schedule and append new rows to Google Sheets or Airtable.
- **Slack:** post a message when a run returns a row whose `price` drops under a threshold or whose `merchant` is not on your approved list.
- **Airbyte:** sync the dataset into BigQuery, Snowflake or Postgres for price dashboards.
- **GitHub Actions:** refresh a public price index on every deployment of your app.
- **Google Drive:** save each run as CSV or Excel for a shared folder.

Every integration starts from the [Apify API](https://docs.apify.com/api/v2) or the [ApifyClient](https://docs.apify.com/api/client/js) for JavaScript and Python.

### 🌟 Beyond business use cases

- **Research:** collect discount depth across categories for a study on promotional prices.
- **Personal:** watch one product across merchants and buy on the day it drops.
- **Non-profit:** compare the price of essential goods across markets for a consumer report.
- **Experimentation:** feed titles and prices to an LLM to prototype a product-matching model.

### 🤖 Ask an AI assistant about this scraper

Give an AI agent live access to Google Shopping offers through the Model Context Protocol:

```bash
claude mcp add --transport http apify "https://mcp.apify.com?tools=parseforge/google-shopping-prices-scraper"
```

Then ask in plain language, for example "What does a Milwaukee M18 drill cost across merchants right now?" or "Find discounted laptops under $900 with a rating above 4.5".

### ❓ Frequently Asked Questions

#### 🛡️ Why must I use the Google SERP proxy?

Because nothing else works. A stealth browser on an Apify residential exit got HTTP 429 with a captcha on the shopping tab, and plain HTTP over datacenter and residential got the same. Apify's Google SERP group returns 200 with a full page. It is the default and there is no reason to change it.

#### 🔗 Does it return the merchant's product URL?

No. Google routes its card links through a click tracker built in the browser, so there is no destination URL in the server-rendered HTML. You get the merchant name, Google's product, cluster and offer IDs, and a Google Shopping product page URL instead.

#### 🖼️ Why is `imageUrl` often `Not Disclosed`?

Google links about 4 thumbnails in 10 through its image cache and inlines the rest into the page as 20 to 30 KB of image bytes. Only the linked ones are reported; a 30 KB blob per row is not something you want in a CSV.

#### 🆔 Is the product ID stable between runs?

Yes, which is what makes price tracking possible: keep `productId` and `price` from each run and diff them.

#### 🌍 Which countries and languages work?

39 markets and 21 interface languages are listed in the input. Set `country` and `language` together; English labels are what the parser reads best, so keep `language` at `en` unless you need local titles.

#### 💱 Why are my prices in the wrong currency?

Set `country`. Without it Google prices in the market the exit node sits in.

#### 🏷️ Why is `originalPrice` `N/A` on most rows?

Because most offers are not discounted. Google only prints a struck-through price when there is one, and roughly one row in two carries it in a typical search. `onlyOnSale` keeps just those.

#### 🏬 Why is `merchant` sometimes a phrase like "Also nearby"?

Google reuses the card layout for local inventory results, where that slot holds a proximity note rather than a seller. Those rows still carry a valid price and product ID.

#### 📦 How many offers can I collect?

Free users get 10 offers as a preview. Paid Apify users can set Max Items up to 1,000,000 per run across as many queries as they supply. Google stops serving new results past about 400 offers per query, so add queries to go wider rather than deeper.

#### 🔁 Why fewer offers than Max Items?

Either Google ran out of results for the query, or the on-sale and merchant filters removed cards after they were read. The run log shows how many cards each page had and how many were kept.

#### 🧾 What do `N/A` and `Not Disclosed` mean?

`N/A` means the field does not apply to that row (no original price on an offer that is not discounted). `Not Disclosed` means Google's card has the slot but this offer left it empty (no rating, no delivery line).

#### ❌ What happens if Google does not answer?

The Actor retries each page up to 5 times with a growing pause. If a page still fails, one row containing only an `error` field is written, which is never charged, and the run status message says so.

#### ⏰ Can I run this on a schedule?

Yes. Create an Apify schedule to run the Actor hourly, daily or weekly and connect the dataset to your pipeline.

#### 📄 What output formats are supported?

CSV, JSON, Excel and XML from the Apify Console or API.

### 🔌 Integrate with any app

The dataset is available through the Apify API the moment the run finishes. Use the `run-sync-get-dataset-items` endpoint for one-shot calls, webhooks to trigger downstream jobs, or the Make, Zapier, Airbyte and LangChain integrations listed on the Actor page.

### 🔗 Recommended Actors

- [Home Depot Products Scraper](https://apify.com/parseforge/home-depot-products-scraper?fpr=vmoqkp)
- [Albertsons Products Scraper](https://apify.com/parseforge/albertsons-products-scraper?fpr=vmoqkp)
- [PCPartPicker Component Scraper](https://apify.com/parseforge/pcpartpicker-component-scraper?fpr=vmoqkp)
- [Chemist Warehouse Health Scraper](https://apify.com/parseforge/chemist-warehouse-health-scraper?fpr=vmoqkp)

***

> 💡 **Pro Tip:** browse the complete [ParseForge collection](https://apify.com/parseforge?fpr=vmoqkp).

**🆘 Need Help?** [Open our contact form](https://tally.so/r/BzdKgA) with your run ID, your input and what you expected.

> **⚠️ Disclaimer:** This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Google. It collects only publicly available search results. You are responsible for using the data in compliance with Google's terms of service and applicable laws.

# Actor input Schema

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

What to search for on Google Shopping, one query per line. Each query is paginated independently, so three queries can return up to three times the offers.

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

Free users: Limited to 10 items (preview). Paid users: Optional, max 1,000,000

## `country` (type: `string`):

Two-letter market code. Sets the currency and the merchants Google shows. Without it Google prices in whatever market the exit node sits in.

## `language` (type: `string`):

Interface language for the result page. English keeps the price, delivery and review labels in the form the parser reads best.

## `minPrice` (type: `integer`):

Ask Google for offers at or above this price, in the country's currency.

## `maxPrice` (type: `integer`):

Ask Google for offers at or below this price, in the country's currency.

## `condition` (type: `string`):

Restrict to new or used items.

## `sortBy` (type: `string`):

How Google should order the offers before they are read.

## `onlyOnSale` (type: `boolean`):

Keep only offers where Google shows a struck-through original price.

## `merchantContains` (type: `string`):

Keep only offers whose merchant name contains this text, for example Walmart or Best Buy.

## `proxyConfiguration` (type: `object`):

Keep the Google SERP group. Every other route measured (datacenter, residential, a stealth browser on residential) returns HTTP 429 with a captcha.

## Actor input object example

```json
{
  "queries": [
    "laptop"
  ],
  "maxItems": 10,
  "country": "us",
  "language": "en",
  "condition": "any",
  "sortBy": "relevance",
  "onlyOnSale": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "GOOGLE_SERP"
    ]
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

Key fields: image, title, price, original price, discount, merchant, rating, reviews, delivery

## `fullData` (type: `string`):

Complete dataset with all 21 fields, including Google's product, cluster and offer IDs

# 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": [
        "laptop"
    ],
    "maxItems": 10,
    "country": "us",
    "language": "en",
    "condition": "any",
    "sortBy": "relevance",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "GOOGLE_SERP"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("parseforge/google-shopping-prices-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": ["laptop"],
    "maxItems": 10,
    "country": "us",
    "language": "en",
    "condition": "any",
    "sortBy": "relevance",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["GOOGLE_SERP"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("parseforge/google-shopping-prices-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": [
    "laptop"
  ],
  "maxItems": 10,
  "country": "us",
  "language": "en",
  "condition": "any",
  "sortBy": "relevance",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "GOOGLE_SERP"
    ]
  }
}' |
apify call parseforge/google-shopping-prices-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parseforge/google-shopping-prices-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/0OU5i9ZWi8jf1b7LZ/builds/lAjRZLEamUOI7yZY5/openapi.json
