Canadian Grocery Prices Scraper avatar

Canadian Grocery Prices Scraper

Pricing

Pay per event

Go to Apify Store
Canadian Grocery Prices Scraper

Canadian Grocery Prices Scraper

Search current Real Canadian Superstore and No Frills prices by product term, category query, and Canadian store. Export package, sale, unit price, promotion, availability, and source records.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Stas Persiianenko

Stas Persiianenko

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Categories

Share

Monitor current Canadian grocery prices at Real Canadian Superstore and No Frills. Search the public PC Express catalog by product term or category phrase, select a Canadian pickup store, and export typed product, package, price, promotion, and availability records.

Use recurring runs to build store-level basket histories or compare like-for-like products across the two supported banners. Each row includes its query, store, product identity, current and regular price, unit-price text, promotion details, source URL, and collection time.

What does Canadian Grocery Prices Scraper do?

The Actor queries the structured catalog used by the Real Canadian Superstore and No Frills websites.

It can:

  • search one banner for multiple product terms;
  • submit category-oriented phrases such as dairy and eggs;
  • scope results to a retailer store ID or exact Canadian postal code;
  • return only products carrying a sale, deal, or loyalty promotion;
  • deduplicate products found by more than one query;
  • stop at a user-selected maximum result count;
  • export results as JSON, CSV, Excel, XML, or through the Apify API.

This is a catalog-data Actor. It does not place orders, access accounts, reserve stock, or create historical price data by itself.

Who is it for?

  • Retail analysts comparing recurring grocery baskets.
  • Consumer packaged goods teams checking store-level shelf prices and promotions.
  • Procurement teams collecting a repeatable local price snapshot.
  • Deal and savings applications looking for current promotion records.
  • Data teams feeding Canadian grocery product records into warehouses or spreadsheets.
  • Developers building scheduled price-monitoring workflows with Apify.

Why use this Actor?

Store-scoped results

Prices and offers can vary by location. Every run resolves one visible pickup store and includes its ID, name, and address in every product row.

Structured price fields

The output separates current, regular, and sale price values while preserving the retailer's unit-price and promotion text.

Two Canadian banners

Choose either Real Canadian Superstore or No Frills with the same input and output contract. Run each banner separately when you want a cross-banner comparison.

Lightweight API extraction

The Actor uses the retailer's structured catalog service rather than loading product images and browser pages. This keeps the workflow bounded and reproducible.

What Canadian grocery price data can I extract?

FieldDescription
bannersuperstore or nofrills
storeIdRetailer pickup-store identifier
storeNameDisplay name of the resolved store
storeAddressPublic address of the resolved store
querySearch term or category phrase that found the product
queryTypesearch or category
productIdStable retailer product identifier
articleNumberRetail article number when supplied
brandProduct brand when supplied
productNameProduct display name
packageSizePackage quantity or size text
currentPriceCurrent listed price in Canadian dollars
regularPricePrevious/regular price when supplied; otherwise current price
salePriceCurrent price when a deal or promotion is detected; otherwise null
unitPriceRetailer unit-price text, such as $0.35/100ml
currencyCAD
isOnSaleWhether a previous price, deal, loyalty offer, or promotion is present
availabilityPublic inventory indicator text
promotionCombined public deal and promotion text
promotionExpiryPromotion expiry timestamp when supplied
imageUrlPublic product-image URL when supplied
productUrlProduct page URL
sourceUrlBanner search URL for the originating query
scrapedAtUTC collection timestamp

Nullable fields remain null when the source does not provide them. Prices are numeric CAD values; unitPrice remains text because the retailer publishes different units and formats.

How much does it cost to monitor Canadian grocery prices?

This Actor uses pay-per-event pricing:

  • Start: $0.005 once per run.
  • Product item: tiered by your Apify plan; the BRONZE tier is $0.005632 per saved product.

Only valid, unique rows saved to the default dataset receive an item charge. Duplicate, filtered, malformed, and failed products are not charged as items.

Example BRONZE prices:

Saved productsEstimated Actor charge
5$0.0332
25$0.1458
100$0.5682
500$2.8210

These examples cover Actor events only. Your Apify plan can also account for platform compute and proxy usage. Actual item pricing depends on your Apify tier; review the live pricing panel before a large run.

How to scrape Real Canadian Superstore prices

  1. Open the Actor input page.
  2. Select Real Canadian Superstore.
  3. Keep store ID 1517 for the provided Vancouver example, or enter another public Superstore pickup-store ID.
  4. Add product terms such as milk, eggs, and bread.
  5. Set maxItems to the number of unique products you need.
  6. Click Start.
  7. Open the default dataset and export the overview view.

Example:

{
"banner": "superstore",
"storeId": "1517",
"searchTerms": ["milk", "eggs"],
"maxItems": 20
}

How to scrape No Frills prices

Select nofrills and use a No Frills store ID. Store 3663 is the real store used by the source-specific example.

{
"banner": "nofrills",
"storeId": "3663",
"searchTerms": [],
"categoryQueries": ["dairy and eggs"],
"maxItems": 20
}

A store ID belongs to one banner. If the ID cannot be resolved for the selected banner, the run fails with a clear validation error rather than returning misleading prices.

Input parameters

Choose superstore or nofrills. The default is superstore.

searchTerms

A list of product, brand, or basket terms. Examples:

  • milk
  • eggs
  • chicken breast
  • President's Choice coffee

categoryQueries

A list of category-oriented phrases submitted to catalog search. Examples:

  • dairy and eggs
  • fresh vegetables
  • bakery bread

This mode is useful for category-like discovery, but it is not an exhaustive crawl of a retailer department taxonomy.

storeId

An optional 3–6 digit public retailer store ID. It takes priority over postalCode.

Without a store ID or postal code, the Actor uses a known example store for the selected banner.

postalCode

An optional Canadian postal code, such as M6M 0A1. The Actor selects a visible pickup location whose address has that exact postal code. It does not perform nearest-store distance calculations.

onSaleOnly

When enabled, save only products with a previous price, deal, loyalty offer, or other promotion signal.

maxItems

Maximum unique products saved across all queries. The supported range is 1–5,000 and the default is 100.

At least one non-empty searchTerms or categoryQueries value is required.

Example output

The following is a shortened record from a real Superstore run:

{
"banner": "superstore",
"storeId": "1517",
"storeName": "Real Canadian Superstore Marine Drive",
"storeAddress": "350 SE Marine Dr, Vancouver, BC, V5X 2S5",
"query": "milk",
"queryType": "search",
"productId": "20264273_EA",
"articleNumber": "20264273",
"brand": "Blue Diamond",
"productName": "Almond Breeze, Unsweetened Vanilla",
"packageSize": "946 ml",
"currentPrice": 2.99,
"regularPrice": 2.99,
"salePrice": 2.99,
"unitPrice": "$0.35/100ml",
"currency": "CAD",
"isOnSale": true,
"availability": "Available",
"promotion": "Limit 4, after limit $3.29; PC Optimum Points",
"promotionExpiry": "2026-09-09T00:00:00Z",
"productUrl": "https://www.realcanadiansuperstore.ca/en/en/almond-breeze-unsweetened-vanilla/p/20264273_EA",
"sourceUrl": "https://www.realcanadiansuperstore.ca/en/search?search-bar=milk",
"scrapedAt": "2026-08-17T15:15:54.050Z"
}

The source can change product titles, prices, promotion wording, and availability at any time.

Build a recurring basket-price monitor

A single run is a current snapshot. To build history:

  1. Keep banner, store, and search terms stable.
  2. Create an Apify Schedule for daily or weekly runs.
  3. Save each run's dataset ID and collection timestamp.
  4. Join snapshots by banner, storeId, and productId.
  5. Compare currentPrice, regularPrice, availability, and promotion over time.

A useful sale-basket input is:

{
"banner": "superstore",
"storeId": "1517",
"searchTerms": ["milk", "eggs", "bread", "chicken"],
"onSaleOnly": true,
"maxItems": 40
}

The Actor does not label a row as “new” or “changed”; your workflow determines changes by comparing snapshots.

Compare Superstore and No Frills

Run the same terms once for each banner and store. Then join products using identifiers where they match, or use normalized brand, product name, and package size where the banners expose different identifiers.

For defensible comparisons:

  • compare similar package sizes;
  • retain storeId and scrapedAt;
  • distinguish loyalty promotions from unconditional prices;
  • treat textual unit prices carefully when units differ;
  • avoid assuming one location represents an entire province or chain.

Data exports and integrations

The default Apify dataset works with:

  • Google Sheets and Microsoft Excel;
  • CSV or JSON downloads;
  • Make and Zapier automations;
  • webhooks after a successful run;
  • Snowflake, BigQuery, or another data warehouse;
  • Python, JavaScript, and REST API clients.

Common workflows include:

  • alerting when a watched product's current price drops;
  • tracking weekly basket totals by store;
  • checking promoted products for a CPG brand;
  • feeding local grocery offers into a deal application;
  • comparing current and prior datasets in a notebook.

Use the Actor through the Apify API

Set APIFY_TOKEN as an environment variable rather than committing it to source code.

cURL

curl -X POST \
"https://api.apify.com/v2/acts/automation-lab~superstore-no-frills-grocery-prices/runs?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"banner":"superstore","storeId":"1517","searchTerms":["milk"],"maxItems":10}'

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor(
'automation-lab/superstore-no-frills-grocery-prices'
).call({
banner: 'superstore',
storeId: '1517',
searchTerms: ['milk'],
maxItems: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor(
'automation-lab/superstore-no-frills-grocery-prices'
).call(run_input={
'banner': 'nofrills',
'storeId': '3663',
'searchTerms': ['eggs'],
'maxItems': 10,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)

Use Canadian Grocery Prices Scraper with MCP

Add the Actor to Claude Code through Apify MCP:

claude mcp add --transport http apify \
"https://mcp.apify.com?tools=automation-lab/superstore-no-frills-grocery-prices"

Claude Desktop setup

Add this server entry to Claude Desktop's MCP configuration.

Cursor setup

Add the same server entry in Cursor under Settings → MCP.

VS Code setup

Add the same server URL through your VS Code MCP extension or workspace MCP configuration.

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=automation-lab/superstore-no-frills-grocery-prices"
}
}
}

Example prompts:

  • “Search the Marine Drive Superstore for milk and eggs and return 20 products.”
  • “Collect current No Frills dairy and eggs prices from store 3663.”
  • “Find promoted bread and chicken products at Superstore and summarize unit prices.”

Tips for reliable grocery price datasets

  • Use stable store IDs for recurring comparisons.
  • Keep the same query list and maximum when comparing snapshots.
  • Search specific product families instead of ambiguous one-word terms when precision matters.
  • Use onSaleOnly for promotion monitoring, not as proof that every row has a lower regular price.
  • Store the raw promotion text because loyalty conditions and quantity limits matter.
  • Keep productId, packageSize, and unitPrice when matching products over time.
  • Start with 20–100 items before scheduling a 5,000-item run.

Limitations

  • Only Real Canadian Superstore and No Frills are supported.
  • One run is scoped to one banner and one store.
  • Category queries use catalog search and are not guaranteed exhaustive department crawls.
  • Postal-code selection requires an exact visible pickup-location match.
  • The output reflects public catalog data, not checkout totals or guaranteed in-store shelf stock.
  • Taxes, deposits, delivery fees, personalized account offers, and basket-level discounts are not calculated.
  • Promotion fields follow source wording and may include loyalty or quantity conditions.
  • Historical changes require scheduled snapshots and downstream comparison.
  • Retailer API or anti-bot changes can temporarily affect runs.

Failure behavior and troubleshooting

“Provide at least one searchTerms or categoryQueries value”

Add at least one non-empty term. Empty arrays do not define a catalog job.

“No visible pickup location matched”

Check that the store ID belongs to the selected banner, or use an exact postal code from the banner's public store locator.

The dataset has fewer products than maxItems

maxItems is a ceiling, not a promised count. The query may have fewer unique products, products can overlap across queries, and onSaleOnly can filter many rows.

The same product appeared under several queries but only once

This is intentional. Rows are deduplicated by banner, store, and source product ID. The first query that accepts the product is retained.

Prices differ from a later website visit

Catalog values can change, and stores can differ. Confirm the row's storeId, scrapedAt, package size, and promotion conditions.

A run fails on an upstream response

Retry later before changing your workflow. The Actor retries bounded transient network and server errors, but it fails closed when the response is blocked or no longer has the expected structured product collection.

Responsible use and legality

This Actor extracts public product-catalog information. Users are responsible for complying with applicable law, Apify's terms, the retailers' terms, and reasonable request volumes.

Do not use the Actor to evade access controls, collect private account information, misrepresent prices, or make automated purchasing decisions without independent verification. Product names, images, and trademarks remain the property of their respective owners.

These Actors cover different sources and jobs; they do not substitute for Superstore or No Frills store-level catalog prices.

FAQ

Does this Actor cover all Canadian grocery chains?

No. It supports Real Canadian Superstore and No Frills only.

Can it search Canadian grocery prices by province?

You can select stores in different provinces using their public store IDs and compare separate runs. The Actor does not automatically enumerate provinces or claim one store represents province-wide prices.

Does it return both regular and sale prices?

It returns the source's current price and previous/regular price when supplied. salePrice is populated when a promotion signal is detected. Read promotion for loyalty or quantity conditions.

Can I use a postal code instead of a store ID?

Yes, when it exactly matches a visible pickup store address. Store ID is more reliable for recurring monitoring.

Can I search both banners in one run?

No. Run once per banner so every row has a clear store and banner context.

Does it create a historical price database?

No. Schedule recurring runs and retain datasets to build history.

Is availability guaranteed at checkout?

No. The field is the public catalog inventory indicator captured at run time.

Are duplicate products charged more than once?

No. Accepted products are deduplicated within the run before charging and saving.

What happens when the retailer changes its catalog API?

The Actor fails rather than returning an empty success from an unrecognized response. Check run logs and retry later; a persistent source change may require an Actor update.