Instacart Scraper - Grocery Prices by Retailer avatar

Instacart Scraper - Grocery Prices by Retailer

Pricing

from $1.00 / 1,000 run start fees

Go to Apify Store
Instacart Scraper - Grocery Prices by Retailer

Instacart Scraper - Grocery Prices by Retailer

Scrape Instacart storefronts for any retailer: product name, price, unit price per lb or oz, pack size and image. Flags weight-estimated prices separately so loose produce is never read as a fixed price.

Pricing

from $1.00 / 1,000 run start fees

Rating

0.0

(0)

Developer

SR

SR

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

4 days ago

Last modified

Share

Instacart Scraper

Scrape Instacart storefronts for any retailer: product name, price, unit price per pound or ounce, pack size and image. Give it a retailer slug like wegmans, costco or publix and it returns the storefront's products.

Why other Instacart scrapers struggle

Instacart serves an unrendered stub to most clients: about 133 KB with no products in it. It renders the full storefront for link previews on purpose, so that a pasted Instacart link shows a product card in a chat app, and this Actor reads that same rendered page.

Nothing underhand, and no browser or solver needed on your side. Ten consecutive fetches came back usable ten times out of ten.

Prices come from the accessibility text

Worth explaining because it is the difference between correct prices and plausible-looking wrong ones.

The visible price is split across three separate spans — $, then 1, then 98 — which a scraper has to glue back together, and which produce nonsense the moment the markup shifts. Every card also carries a screen-reader line:

Current price: $1.98 each (estimated)

One string, in plain language, and it states the unit as well. This Actor reads that. It is both more robust and more honest than reassembling spans.

Estimated prices are marked, never hidden

Loose produce is sold by weight, and Instacart quotes it against an assumed weight. Bananas come back as $1.78 with is_estimated: true,

unit_price: 0.89
, unit_measure: "lb" and size: "About 2.0 lb each".

That flag matters. If you are comparing basket prices or tracking inflation, treating an estimated banana price as a fixed one quietly corrupts the number, and nothing in the raw page forces you to notice. The run summary counts how many rows are estimates.

Fields

FieldWhat it is
product_idInstacart's own id. Stable, use it to join runs
nameProduct name
priceCurrent price
is_estimatedTrue when priced against an assumed weight
price_unitWhat the price is per, e.g. each (estimated)
unit_price, unit_measurePrice per lb, oz, ct and so on
sizePack size or approximate weight as printed
imageProduct image
retailerWhich retailer's storefront the row came from
urlInstacart product page

Input reference

FieldTypeDefault
retailerretailer slugwegmans
store_urlslist of full Instacart URLs, overrides retailer—
limit1-2000100
retries1-84

Passing several store_urls scrapes several retailers in one run, and every row carries its retailer, so a cross-retailer price comparison comes out of a single run. A non-Instacart URL is rejected with a message rather than fetched.

Typical uses

  • Grocery price comparison across retailers. Run two or three storefronts in one go and group by name or product_id per retailer. Mind is_estimated when comparing fresh produce.
  • Unit-price analysis. unit_price and unit_measure are the fields that make a 12-pack comparable with a 24-pack.
  • Assortment tracking. Which products a retailer carries on Instacart, and how that changes week to week.
  • Inflation and basket tracking. Schedule it and join snapshots on product_id.

Notes on behaviour

A page that comes back short is the unrendered stub, and it is retried and then reported as an error rather than returned as an empty store. A storefront that renders but carries no product cards is reported as no_products. Both cases are made loud on purpose: a successful-looking run with zero rows is the worst possible outcome for price data.

Pages are paced with a short randomised gap.

Storefront pages show a slice of a retailer's catalogue, not the entire inventory. For deeper coverage pass specific aisle or category URLs in store_urls rather than expecting one storefront to return everything.

Prices are US dollars, and they are Instacart's prices, which frequently differ from the retailer's in-store shelf price.

Finding a retailer slug

The slug is the part of the Instacart URL after /store/. Browse to a retailer on Instacart and read it off the address bar: instacart.com/store/wegmans/storefront gives wegmans. Common ones include costco, publix, kroger, safeway, aldi, sprouts and wegmans.

Availability is regional. Instacart serves different retailers in different parts of the United States, so a slug that works in one metro may return nothing useful in another. When that happens the run reports no_products for that storefront rather than returning an empty dataset with no explanation.

What this Actor does not do

No search. Instacart's search results behave differently from storefront pages and did not render for link-preview agents in testing. Pass aisle or category URLs instead.

No delivery fees, tips or service charges. Those are calculated at checkout against an address and a basket, and nothing in the storefront page carries them. The price field is the item price as shown on the storefront.

No stock levels. Instacart does not publish a count. A product that appears on the storefront is being offered; whether the shopper finds it on the shelf is decided at pick time.