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

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

Pricing

from $15.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 $15.00 / 1,000 google-skus

Rating

0.0

(0)

Developer

SR

SR

Maintained by Community

Actor stats

13

Bookmarked

527

Total users

40

Monthly active users

2.9 days

Issues response

21 days 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.

You pay for the scrape, once. Collecting the result is free. If an EAN has never been scraped, this request queues the scrape and is charged. Run the actor again for that EAN in about 2 hours and the offers come back free of charge, however many times you collect them. See Pricing.

Output Schema

Each record in the dataset represents one product lookup. Every record carries a status and a charged flag:

statusMeaningCharged?
queued_for_scrape (first time)Nothing known about this EAN yet. Your request queued the scrape.Yes — this is the charge
queued_for_scrape (repeat)You already paid for this scrape and it is still running.No
cachedOffers found and returned. Already paid for.No
scraped_no_offersThe scrape ran; Google Shopping has no offers. Already paid for.No

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 while the scrape is still queued. 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)
chargedbooleantrue only on a first request, the one that queued the scrape. Everything else is false.

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 (Not 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 (Charged, first request)

status: "queued_for_scrape" with charged: true — nothing was known about this EAN, so your request queued the scrape and this is the charge. Run the actor again for these EANs in about 2 hours and the offers come back free in the not-charged-results dataset. The full retry list is in the QUEUED_EANS key-value record. A repeat request while the scrape is still running carries charged: false.

{
"ean": "5088809648017",
"gl": "uk",
"found": false,
"status": "queued_for_scrape",
"charged": true,
"message": "This product had not been scraped yet, so this request queued the scrape and is charged. Re-run the actor for this product in about 2 hours to collect the offers free of charge - collecting never costs anything, however often you do it.",
"retry_after_hours": 2,
"offers_count": 0,
"offers": []
}

Example — Scraped, No Offers Exist (Not charged)

status: "scraped_no_offers" — the scrape ran and Google Shopping has no offers for this EAN in this country. You already paid for that scrape on the first request, so this record is not charged and lands in not-charged-results. 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 pay for a scrape, once, at the moment you ask for a product we do not already have. Collecting the result is always free.

statusWhat happenedCharged?Where it lands
queued_for_scrape (first time)First request for this EAN in this country. Your request queued the scrape.Yes.Default dataset
queued_for_scrape (repeat)Same EAN again while the scrape is still running.No.not-charged-results dataset
cachedOffers returned. The scrape was already paid for.No.not-charged-results dataset
scraped_no_offersScrape ran, Google had no offers. Already paid for.No.not-charged-results dataset

You are billed per item in the default dataset, and only first requests go there. Everything you have already paid for lands in the not-charged-results dataset, alongside a QUEUED_EANS key-value record listing exactly which EANs to collect.

Why this way. The cost of this actor is the scrape itself, so that is what you pay for, and you pay for it exactly once per product per country. A first request is charged whatever the scrape turns up: establishing that Google Shopping has no listings for a product takes the same full scrape as finding twenty offers, and "nothing exists here" is a real answer.

Re-collecting is free and unlimited. A price monitor that re-reads the same 500 EANs every hour pays nothing after the first pass, until the data ages past 48 hours and a genuinely new scrape is needed.

Two-pass flow

  1. Pass A submits your EAN list. Every EAN we do not already have is charged once and queued.
  2. Pass B, about 2 hours later, submits the QUEUED_EANS list. The offers arrive in not-charged-results at no cost.

Read QUEUED_EANS from the run's key-value store to get the exact list for Pass B. You can automate the whole thing 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.