Loblaws, Superstore, No Frills, Maxi & 8 More — Grocery Prices avatar

Loblaws, Superstore, No Frills, Maxi & 8 More — Grocery Prices

Pricing

from $0.69 / 1,000 results

Go to Apify Store
Loblaws, Superstore, No Frills, Maxi & 8 More — Grocery Prices

Loblaws, Superstore, No Frills, Maxi & 8 More — Grocery Prices

Canadian grocery prices from all 12 Loblaw banners and 1,107 stores, priced at the individual store by postal code. 67 fields per product: UPC barcodes, stock status, PC Optimum member prices, promo expiry dates, nutrition and ingredients. Many chains and stores in one run. No API key, no browser.

Pricing

from $0.69 / 1,000 results

Rating

0.0

(0)

Developer

Arpit Gandhi

Arpit Gandhi

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

2

Monthly active users

3 days ago

Last modified

Share

Canadian grocery prices from all 12 Loblaw banners and 1,107 stores, priced at the individual store by postal code — with UPC barcodes, live stock status, PC Optimum member prices, promo expiry dates, ratings, nutrition and ingredients on the row.

67 fields per product. Not a name-and-price feed: everything the shelf tag, the barcode and the label carry, from one input.

  • Chains — Loblaws, Real Canadian Superstore, No Frills, Zehrs, Fortinos, Valu-mart, Your Independent Grocer, Independent City Market, Provigo, Maxi, Wholesale Club, Atlantic Superstore
  • Coverage — 1,107 stores across every province plus Yukon and the Northwest Territories, in English and French
  • Setup — none. No API key, no account, no proxy, no browser, no geocoder

What you get that a price feed doesn't

Scan-ready identifiers. upc and gtin on the row, so prices join straight onto an existing product database or a barcode scan. No fuzzy name matching.

Stock, not just price. stock_status and is_shoppable tell you whether the item is actually on the shelf at that store today. A price for something out of stock is a bad datapoint.

Member vs shelf price. member_price and member_price_ends capture PC Optimum member-only pricing separately from price and was_price — three different numbers the same product can show.

Promotions with expiry dates. sale_ends, deal_ends, pc_optimum_offer_ends and numeric pc_optimum_points, alongside multi_buy_deal and purchase_limit. You know when a price dies, not only that it exists.

Many chains and many stores in one run. banners takes a list and stores_per_banner prices the nearest N of each — so "Superstore vs No Frills vs Maxi, three stores each" is a single run, not nine.

The full label. Turn on include_details for nutrition, ingredients, category_path, average_weight_kg and gtin.

Paid placements removed by default. The storefront injects sponsored products into every search page, often unrelated — a search for milk returns kombucha and baby cereal. Those are dropped unless you ask for them, and flagged with is_sponsored when you do.

Real unit-price maths. comparable_unit_price normalizes to $/100 g or $/100 ml and stays null when a package size won't parse, so a wrong number never enters your comparison. comparison_prices keeps every unit the store quoted ($/kg and $/lb).

Run it

Paste into the Input tab (JSON view) and hit Start:

{
"banners": ["superstore"],
"search_terms": ["eggs", "milk", "chicken breast"],
"postal_code": "V5X 0C4"
}

Rows stream into Output as they arrive. Download from Storage → Dataset as JSON, CSV or Excel.

Three things to change from there:

  • Compare chains"banners": ["superstore", "nofrills", "maxi"], one run, every row naming its store
  • Compare stores"stores_per_banner": 3 prices the three nearest locations of each banner
  • Take the whole store"all_products": true instead of search terms

What a row looks like

{
"store": "Real Canadian Superstore",
"banner": "superstore",
"name": "Bananas, Bunch",
"product_id": "20175355001_KG",
"upc": "4011",
"price": 1.98,
"price_unit": "ea",
"was_price": null,
"is_on_sale": false,
"member_price": null,
"unit_price": "$1.72/kg, $0.78/lb",
"comparable_unit_price": 0.17,
"comparable_unit": "100g",
"selling_type": "by_weight",
"stock_status": "in_stock",
"is_shoppable": true,
"rating": 3.67,
"review_count": 3,
"image_url": "https://digital.loblaws.ca/PCX/20175355001_KG/en/1/...png",
"product_url": "https://www.realcanadiansuperstore.ca/en/bananas-bunch/p/20175355001_KG",
"location_id": "1517",
"location_name": "Real Canadian Superstore Marine Drive",
"location_address": "350 SE Marine Dr, Vancouver, BC, V5X 2S5",
"location_province": "British Columbia",
"location_coordinates": { "lat": 49.20906, "lng": -123.10 },
"distance_km": 1.4
}

Fields

Productname, brand, description, product_id, article_number, upc, upcs, package_size, parsed_package_size, normalized_package_size, variant_label, image_url, product_url, seller_name

Priceprice, price_unit, was_price, is_on_sale, sale_ends, member_price, member_price_ends, unit_price, comparable_unit_price, comparable_unit, parsed_unit_price, comparison_prices, selling_type, deposit, eco_fee, tax_info

Promotionsdeal_type, deal_text, deal_ends, multi_buy_deal, purchase_limit, pc_optimum_offer, pc_optimum_points, pc_optimum_offer_ends, badges

Availability & reviewsstock_status, is_shoppable, rating, rating_count, review_count, is_sponsored

Storestore, banner, location, location_id, location_name, location_address, location_city, location_province, location_postal_code, location_coordinates, location_phone, distance_km

Runsearch_term

With include_detailsgtin, category, category_path, ingredients, nutrition, average_weight_kg, variant_group_id, variant_count, variants

Input

FieldTypeDefaultDescription
bannersstring[]One or more of the 12 banners below. Several in one run compares chains.
search_termsstring[]Keyword queries, e.g. ["eggs", "no name"]. Use French for Maxi and Provigo.
postal_codestringAny Canadian postal code; picks the nearest store of each banner.
all_productsbooleanfalseWalk the store's entire catalogue instead of searching.
include_detailsbooleanfalseAdd nutrition, ingredients, category path, GTIN, average weight. One extra request per product.
on_sale_onlybooleanfalseKeep only products on sale or carrying a deal.
group_variantsbooleanfalseCollapse sizes of one product into a single row with a variants array.
stores_per_bannerinteger1Price the nearest N stores (1–10) of each banner.
locationIdstringOne exact store, overriding postal_code.
languagestringautoen / fr. Auto = French for Maxi and Provigo.
max_items_per_searchinteger500Cap per search term, per store.
max_itemsinteger0Stop the whole run after N products. 0 = no limit.
include_sponsoredbooleanfalseKeep the storefront's paid placements.

One of search_terms or all_products is required.

Examples

Compare one basket across three chains:

{ "banners": ["superstore", "nofrills", "maxi"], "search_terms": ["milk", "eggs", "bread"], "postal_code": "H2X 1Y6" }

Everything on sale at the nearest No Frills:

{ "banners": ["nofrills"], "all_products": true, "on_sale_only": true, "postal_code": "M6H 1V4" }

Barcodes and nutrition for a category of products:

{ "banners": ["loblaw"], "search_terms": ["greek yogurt"], "include_details": true, "postal_code": "M5V 2T6" }

Price the same products at the five nearest stores:

{ "banners": ["superstore"], "search_terms": ["chicken breast"], "stores_per_banner": 5, "postal_code": "T2P 1J9" }

One exact store:

{ "banners": ["superstore"], "locationId": "1517", "search_terms": ["bananas"] }

Supported stores

BannerStoreStoresProvinces
nofrillsNo Frills350AB, BC, MB, NB, NL, NS, ON, PE, SK
maxiMaxi198NB, QC
independentYour Independent Grocer181AB, BC, NB, NL, NS, NT, ON, PE, QC, SK, YT
superstoreReal Canadian Superstore119AB, BC, MB, ON, SK, YT
wholesaleclubWholesale Club56AB, BC, MB, NB, NL, NS, ON, QC, SK
rassAtlantic Superstore52NB, NS, PE
loblawLoblaws48AB, BC, ON
zehrsZehrs42ON
fortinosFortinos24ON
provigoProvigo20QC
valumartValu-mart14ON
independentcitymarketIndependent City Market3ON

Counts read live from Loblaw's own store directory. Each banner prices independently — the same SKU can differ by a dollar or more between them. rass is Atlantic Superstore's internal code. Aliases accepted: loblaws, rcss, no frills, valu-mart, yig, atlantic, icm.

From the API

Grab a token at console.apify.com/settings/integrations:

curl -X POST \
"https://api.apify.com/v2/acts/arpitgandhi1934~loblaws-grocery-scraper/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"banners": ["superstore"], "search_terms": ["eggs", "milk"], "postal_code": "V5X 0C4"}'

run-sync-get-dataset-items suits small runs and can time out on large ones. For scheduled or whole-store scrapes, POST to /runs and read the returned defaultDatasetId. The official JavaScript and Python clients work too, as do Zapier, Make, Google Sheets and Airbyte.

What people build with it

  • Price comparison apps keyed to a real store, not a national average
  • Food inflation research — rerun a fixed basket weekly and diff price by product_id and store
  • CPG competitor monitoring across all 12 banners, including member-only pricing rivals can't see in a flyer
  • Deal and flyer sites from is_on_sale, multi_buy_deal, pc_optimum_offer and their expiry dates
  • Barcode and inventory apps joining on upc / gtin with stock_status
  • AI shopping agents that need grounded prices with a store, a timestamp and a stock flag

FAQ

How do I scrape Real Canadian Superstore prices? Set "banners": ["superstore"] with search_terms and a postal_code. The Run it example above works as-is.

Can I get prices for a specific postal code? Yes. Any Canadian postal code resolves to the nearest store of each banner, and every row reports that store's name, address, postal code, coordinates and distance.

Does this work in Quebec? Yes — maxi and provigo, which default to French. independent and wholesaleclub also have Quebec locations.

Can I compare the same product across chains? Yes, in one run: pass several banners. product_id is shared across the Loblaw catalogue, so rows join directly.

Is there an official Loblaws API? No. Loblaw publishes no public pricing API, which is why this reads the same JSON endpoints its own storefronts and app use.

How do I get barcodes? upc is on every row. gtin comes with include_details.

How do I track prices over time? Schedule it daily or weekly and keep each run's dataset, then compare price per product_id per store. The Actor returns current prices and stores no history itself.

How many products can one run return? A search term returns up to max_items_per_search (default 500). all_products walks the whole catalogue — a small Valu-mart is ~2,000 products in under a minute; a large No Frills is ~21,000 and takes several minutes. Around 25,000 products are reachable per store. Rows stream as they go, so partial results are available while the run continues.

Do I need a proxy? No. It runs from Apify's datacenter IPs without one. proxyConfiguration is there for very large or very frequent scrapes.

Is scraping Loblaws legal? Scraping publicly available product and price information is generally legal. Complying with the retailer's terms and the law in your jurisdiction is your responsibility, so keep request volume reasonable.

Notes

  • Grocery size variants are separate products in Loblaw's catalogue; group_variants groups them by brand and name with no extra requests. True variants arrays are clothing (Joe Fresh size/colour).
  • Result ordering from the upstream search is not stable between identical calls, so whole-store runs walk the catalogue in repeated passes until a pass adds almost nothing. That is why a full store takes minutes rather than seconds.
  • A postal code outside a banner's footprint returns a clear error naming the provinces that banner serves, so a Quebec query never quietly returns an Ontario store.