Free Google Shopping Scraper - Extract offers from any EAN/SKU avatar

Free Google Shopping Scraper - Extract offers from any EAN/SKU

Pricing

from $8.00 / 1,000 google-skus

Go to Apify Store
Free Google Shopping Scraper - Extract offers from any EAN/SKU

Free Google Shopping Scraper - Extract offers from any EAN/SKU

Grab all offers from all sellers of a Google Shopping EAN/SKU. Whether you're monitoring competitor prices, optimizing your pricing strategy, or tracking market trends, this scraper delivers the insights you need at scale.

Pricing

from $8.00 / 1,000 google-skus

Rating

0.0

(0)

Developer

SR

SR

Maintained by Community

Actor stats

12

Bookmarked

499

Total users

57

Monthly active users

2.2 days

Issues response

14 hours ago

Last modified

Share

Google Shopping Scraper — Real-Time Price & Offer Data by EAN / GTIN

Extract live pricing data from Google Shopping for any product, identified by EAN or GTIN barcode. Get every seller offer — price, shipping, condition, seller identity — across 25+ countries, in one clean JSON output per product.

Products are looked up by EAN/GTIN or by Google Shopping SKU. Paste either, one per line; the type is detected automatically. Entries that are neither produce an error record.

What It Does

This actor resolves your EAN/GTIN codes against Google Shopping and returns a structured dataset of all seller offers. For each product you submit, you receive the full competitive landscape: who is selling it, at what price, with what shipping cost, and under what conditions.

If an EAN has never been scraped, the actor queues a scrape and returns a free queued_for_scrape record asking you to run again in about 2 hours — you are not charged for that. Once the EAN has been scraped you get either the offers (cached) or a verified "Google has no offers for this" verdict (scraped_no_offers); both are charged. See Pricing.

Output Schema

Each record in the dataset represents one product lookup. Every record carries a status telling you which of three outcomes it is — and whether it was charged:

statusMeaningCharged?
queued_for_scrapeNothing known about this EAN yet. A scrape has been queued.No — free
scraped_no_offersThe scrape ran; Google Shopping has no offers for this EAN.Yes
cachedOffers found and returned.Yes

Product Record

FieldTypeDescription
eanstring | nullEAN / GTIN barcode (null when looked up by SKU)
skustring | nullGoogle Shopping SKU / catalog id (null when looked up by EAN)
statusstringqueued_for_scrape, scraped_no_offers or cached (see above)
foundbooleanfalse only for queued_for_scrape (the free case). true once the EAN has actually been scraped.
glstringCountry code (lowercase) the lookup ran against
titlestring | nullProduct title as listed on Google Shopping
brandstring | nullBrand name
urlstring | nullGoogle Shopping search URL for the product
thumbnailstring | nullProduct image URL
currencystring | nullISO 4217 currency code (e.g. EUR, GBP)
offers_countintegerNumber of seller offers returned
lowest_total_pricenumberLowest combined price + shipping across all offers
highest_total_pricenumberHighest combined price + shipping across all offers
offersarrayFull list of seller offers — see below
fetched_atstringWhen the offers were scraped (cached only)
checked_atstringWhen the empty scrape ran (scraped_no_offers only)
age_hoursnumberHow old the scrape result is, in hours
no_offers_foundbooleantrue on scraped_no_offers records
messagestringHuman-readable explanation (queued_for_scrape, scraped_no_offers)
retry_after_hoursintegerHours to wait before re-requesting (queued_for_scrape only)

Offer Object

FieldTypeDescription
sellerNamestringShop or marketplace name (e.g. Amazon.fr, Zalando.fr)
sellerReferencestringDirect URL to the product listing at the seller
pricestringBase product price
shippingPricestring | nullShipping cost, or null if unknown
totalPricestringPrice + shipping combined
conditionstringProduct condition (New, Used, Refurbished)
availabilitystringStock availability (e.g. InStock)

Example — Offers Found (Charged)

status: "cached" — the normal case.

{
"ean": "0198376596101",
"gl": "fr",
"found": true,
"status": "cached",
"title": "Sandales Skechers Desert Kiss Low Femme",
"brand": null,
"url": "https://www.google.com/search?q=%2B%22Sandales+Skechers+Desert+Kiss+Low+Femme%22&num=10&udm=28&gl=fr",
"thumbnail": "https://encrypted-tbn3.gstatic.com/shopping?q=...",
"currency": "EUR",
"fetched_at": "2026-07-13T10:00:00",
"age_hours": 1.4,
"offers_count": 7,
"lowest_total_price": 35.99,
"highest_total_price": 82.0,
"offers": [
{
"sellerName": "Amazon.fr",
"sellerReference": "https://www.amazon.fr/Skechers-Femme-Desert-Sandale-Glissante/dp/B0DC8QSWVC",
"price": "35.99",
"shippingPrice": null,
"totalPrice": "35.99",
"condition": "New",
"availability": "InStock"
},
{
"sellerName": "obishoes.fr",
"sellerReference": "https://obishoes.fr/sandales/9624-sandales-skechers-bobs-desert-kiss-low-peak-look-114707-noir",
"price": "40.99",
"shippingPrice": "4.95",
"totalPrice": "45.94",
"condition": "New",
"availability": "InStock"
}
]
}

Example — Scrape Queued (Free)

status: "queued_for_scrape" — nothing is known about this EAN yet, so a scrape has been queued. This record is free and does not appear in the default dataset: you will find it in the queued-and-skipped dataset, and the full retry list in the QUEUED_EANS key-value record. Run the actor again for these EANs in about 2 hours to get the offers.

{
"ean": "5088809648017",
"gl": "uk",
"found": false,
"status": "queued_for_scrape",
"message": "This product has not been scraped yet. A scrape has been queued and this request is free of charge. Please run the actor again for this EAN in about 2 hours to retrieve the offers.",
"retry_after_hours": 2,
"offers_count": 0,
"offers": []
}

Example — Scraped, No Offers Exist (Charged)

status: "scraped_no_offers" — the scrape ran and Google Shopping has no offers for this EAN in this country. That is a real, verified verdict, so it is charged. No new scrape is queued. Use checked_at / age_hours to see how recent the "nothing exists" verdict is.

{
"ean": "5088809648017",
"gl": "uk",
"found": true,
"status": "scraped_no_offers",
"no_offers_found": true,
"message": "This product was scraped but Google Shopping returned no offers for it in this country. No new scrape was queued.",
"title": null,
"brand": null,
"url": null,
"thumbnail": null,
"currency": null,
"checked_at": "2026-07-13T13:05:12",
"age_hours": 3.2,
"offers_count": 0,
"offers": []
}

Example — Input Without EAN (Error Record)

Entries that do not contain a valid EAN/GTIN are not processed. Instead, an error record is added to the dataset:

{
"input": "not-an-ean",
"error": "EAN is required. Supply a valid EAN/GTIN (8, 12, 13 or 14 digits) for every product."
}

Input Format

Select your target country from the dropdown (default: Netherlands), then enter one EAN/GTIN code per line:

8720648364181
4024074895542
193575000923

Accepted formats: EAN-8 (8 digits), UPC-A (12 digits), EAN-13 (13 digits), GTIN-14 (14 digits), or a Google Shopping SKU (15+ digit catalog id). You can mix both in one run. Any entry that is neither is rejected with an error record (free, never charged).

There is also an optional Force fresh fetch toggle — see Caching and Forcing Fresh Data at the bottom.

Supported Countries

CountryCodeGoogle Shopping Domain
NetherlandsNLshopping.google.nl
GermanyDEshopping.google.de
FranceFRshopping.google.fr
BelgiumBEshopping.google.be
AustriaATshopping.google.at
SwitzerlandCHshopping.google.ch
SpainESshopping.google.es
ItalyITshopping.google.it
PolandPLshopping.google.pl
SwedenSEshopping.google.se
DenmarkDKshopping.google.dk
NorwayNOshopping.google.no
FinlandFIshopping.google.fi
PortugalPTshopping.google.pt
IrelandIEshopping.google.ie
Czech RepublicCZshopping.google.cz
HungaryHUshopping.google.hu
RomaniaROshopping.google.ro
GreeceGRshopping.google.gr
SlovakiaSKshopping.google.sk
CroatiaHRshopping.google.hr
BulgariaBGshopping.google.bg
United KingdomUKshopping.google.co.uk
United StatesUSshopping.google.com
AustraliaAUshopping.google.com.au
CanadaCAshopping.google.ca
BrazilBRshopping.google.com.br
IndiaINshopping.google.co.in
JapanJPshopping.google.co.jp

Supported Product Identifiers

You can submit either identifier, mixed freely in the same run. The type is detected from the code, and the two formats never collide.

EAN / GTIN barcodes (8 to 14 digits). Our matching algorithm resolves these against Google Shopping automatically:

  • EAN-8 (8 digits)
  • UPC-A (12 digits)
  • EAN-13 (13 digits, most common in Europe)
  • GTIN-14 (14 digits)

Google Shopping SKU (15+ digits) — the long numeric catalog id, e.g. 15946942461803762490. Use this when you already know Google's product id and want to skip EAN matching entirely.

On the output record, ean is populated for EAN lookups and sku for SKU lookups; the other is null. Entries that are neither a valid EAN nor a SKU return an error record (free, never charged).

Item Limits and Plan Tiers

PlanLimit
Free20 products per dataset
PaidSet via ACTOR_MAX_PAID_DATASET_ITEMS environment variable

The actor tracks unique products by EAN. Re-submitting the same identifier in a single run does not count twice. Items already in the dataset from previous runs count toward the limit.

Configuring a paid limit:

  1. Apify Console → Your Actor → Settings → Environment variables
  2. Add ACTOR_MAX_PAID_DATASET_ITEMS with your desired value (e.g. 5000)

Pricing

You are only charged once an EAN has actually been scraped. Queuing a scrape is free.

statusWhat happenedCharged?Where it lands
queued_for_scrapeFirst time we've seen this EAN. A scrape was queued; no data yet.No, free. Re-run in ~2 hours.queued-and-skipped dataset + QUEUED_EANS
scraped_no_offersThe scrape ran and Google Shopping had no offers for this EAN.Yes.Default dataset
cachedThe scrape ran and offers were returned.Yes.Default dataset

You are billed per item in the default dataset. Records you are not charged for never enter it:

  • Queued EANs and rejected inputs go to a separate queued-and-skipped dataset, plus a QUEUED_EANS record in the key-value store containing the exact list of EANs to retry. Both are free.
  • A run over 500 EANs where only 9 resolve therefore costs you 9 items, not 500.

scraped_no_offers is charged because it is a real result: confirming that a product has no listings in a market requires the same full scrape as finding offers. The checked_at / age_hours fields tell you how recent that verdict is, and no new scrape is queued for it, so re-requesting the same EAN will not put you in a re-billing loop.

  1. Run A submits your full EAN list. You are charged only for the EANs that already have data.
  2. Read QUEUED_EANS from the run's key-value store (or the queued-and-skipped dataset) to get the EANs whose scrape was just queued. These cost nothing.
  3. Run B, about 2 hours later, submits only that list. Now those EANs return cached or scraped_no_offers.

You can automate this with a scheduled Apify task, so you never orchestrate it by hand.

Use Cases

Retail price monitoring — track how your products are priced across all Google Shopping sellers in each of your markets. Identify undercutting, map-price violations, and grey-market listings.

Dynamic repricing — feed real-time competitor prices into your repricing engine to stay competitive without eroding margin.

Market entry research — before expanding to a new country, assess the competitive landscape by querying your catalogue against that market's Google Shopping.

Marketplace benchmarking — compare your prices against the lowest and highest offers across multiple sellers to understand your positioning.

Price drop alerts — schedule regular runs and compare lowest_total_price against a stored baseline to trigger alerts when a competitor drops price significantly.

Caching and Forcing Fresh Data

By default this actor serves cached offers up to 24 hours old. If a product was scraped within the last 24 hours, you get that result instantly and cheaply, without triggering a new scrape.

Turn on Force fresh fetch when you need the newest possible data (for example right after a price change) and don't want a cached copy. Forcing makes the actor demand fresh data and trigger a new scrape whenever the cache is stale.

How to force

In the Apify UI, tick the Force fresh fetch checkbox.

Via the API / JSON input, set force to true:

{
"country": "NL",
"products": "8720648364181\n8720938897238",
"force": true
}

Leave force out (or set it to false) to use the standard 24-hour cache.

Note: forcing runs a real scrape, so it can take longer to return and may be charged like any other scraped result.

Support

For questions, issues, or feature requests, open a ticket via the Apify platform.