Spot out-of-stock and newly added products on competitor Shopify/WooCommerce stores each week
What you get: one Google Sheet that, every week, shows four short lists for your competitor stores: new products, removed products, just sold out and back in stock. You build it by exporting each store's public product list to CSV on the same day each week, pasting it into a dated tab, and comparing the two latest tabs by product URL with three formulas. Setup is under an hour; the weekly refresh is about ten minutes.
The finished sheet
| Change | Store | Product | Product URL | Price now |
|---|---|---|---|---|
| New this week | competitor-a.com | Linen shirt, olive | …/products/linen-shirt-olive | ₹1,899 |
| Sold out this week | competitor-b.in | Canvas tote | …/product/canvas-tote/ | ₹1,199 |
| Back in stock | competitor-a.com | Cotton tee, black | …/products/cotton-tee-black | ₹699 |
| Gone since last week | competitor-b.in | Summer kurta, white | …/product/summer-kurta-white/ | (last seen ₹1,499) |
Why these four lists are worth ten minutes a week
- New products show where a competitor is investing: a new colour, a new range, a new price tier.
- Sold out on a product you also sell is a window: your listing may be the one buyers find while theirs is unavailable. Make sure yours is in stock and visible.
- Back in stock tells you that window has closed.
- Gone products, once checked, hint at what did not sell or was replaced.
If you mainly care about price moves on products you already follow, use the weekly competitor price sheet guide instead. This one is about the catalogue changing.
Step 1: fix your store list and your day
- Pick 3–10 direct competitors. Write the exact URLs down (homepage or the one category page that matches your range).
- Pick one day and time, for example Monday 10:00. Comparing a Monday export with a Saturday export mixes in weekend sales and restocks.
- Do not change the list between weeks. If you add a store, it will look as if every one of its products is "new". Add it, and ignore its first week.
- Skip marketplaces (Amazon, Flipkart, eBay). This method is for brand-owned Shopify and WooCommerce shops.
Step 2: get this week's product CSV
Free, one or two stores
- Shopify: many shops answer at
/products.json?limit=250&page=1. Each product carriescreated_atandpublished_atdates, and each variant carriesavailable(true/false). Step-by-step: Export a Shopify store's products to CSV. - WooCommerce: many shops answer at
/wp-json/wc/store/v1/products?per_page=100, withis_in_stockon each product. Step-by-step: Export a WooCommerce store's products to CSV.
If a shop returns 401, 403 or 404 there, or its robots.txt or terms forbid scraping, drop it from the list rather than forcing it.
No code, many stores (Apify)
- Create a free Apify account (no card needed for the free plan; see apify.com/pricing for current free monthly usage).
- Open Shopify & WooCommerce Product + Price Tracker and click Try for free.
- Paste your store list. In JSON view:
{
"startUrls": [
{ "url": "https://competitor-a.com/collections/shirts" },
{ "url": "https://competitor-b.in" }
],
"maxProductsPerShop": 300,
"maxListingPages": 20,
"includeDescription": false
}
Set maxProductsPerShop above the store's real catalogue size. If the cap cuts a store short, products past the cap will look "gone" next week when they are not. Turn descriptions off; you do not need them here.
When the run finishes, open the dataset and choose Export → CSV. The columns this sheet uses are url, shop, title, price, inStock and, for Shopify stores, createdAt. Check the SHOPS_SUMMARY record: it says which shops were read and which were skipped (for example because robots.txt or the shop's terms forbid scraping).
To keep the store list identical every week, save the input as an Apify Task, and if you like add a weekly Schedule for it, then just download the CSV.
Step 3: build the sheet (one-time)
One Google Sheet, these tabs:
- raw_2026-10-19, raw_2026-10-26, … — paste each week's CSV as-is into a new tab. Never edit a raw tab.
- settings — cell
B1holds last week's tab name,B2this week's. Each week you change only these two cells. - changes — the four lists, built by formula.
So the formulas below stay short, give each raw tab the same column order. After you paste, make sure column A is the product URL and column B is inStock (drag the column headers into place, or reorder the columns before you paste). Leave the rest as it comes.
New this week (URL in this week's tab, not in last week's)
=LET(now, INDIRECT("'"&settings!B2&"'!A2:A"), old, INDIRECT("'"&settings!B1&"'!A2:A"),
FILTER(now, now<>"", ISNA(MATCH(now, old, 0))))
Gone since last week (URL in last week's tab, not in this week's)
=LET(now, INDIRECT("'"&settings!B2&"'!A2:A"), old, INDIRECT("'"&settings!B1&"'!A2:A"),
FILTER(old, old<>"", ISNA(MATCH(old, now, 0))))
Sold out and back in stock (same URL, stock flipped)
=ARRAYFORMULA(LET(nowU, INDIRECT("'"&settings!B2&"'!A2:A"), nowS, TO_TEXT(INDIRECT("'"&settings!B2&"'!B2:B")),
oldU, INDIRECT("'"&settings!B1&"'!A2:A"), oldS, TO_TEXT(INDIRECT("'"&settings!B1&"'!B2:B")),
was, IFERROR(VLOOKUP(nowU, {oldU, oldS}, 2, FALSE), ""),
FILTER({nowU, IF(nowS="FALSE", "Sold out this week", "Back in stock")},
nowU<>"", was<>"", nowS<>"", nowS<>was)))
Put each formula at the top of an empty column in changes. A "no matches" error simply means nothing changed in that list this week. Add titles and prices next to the URLs with VLOOKUP or XLOOKUP against the same raw tab if you want the layout in the table above. In Excel, the same logic works with FILTER, XLOOKUP and ISNA(MATCH()) on direct sheet references instead of INDIRECT.
Shopify bonus: "really new" vs "new to my sheet"
For Shopify stores, sort the new list by createdAt. A product created months ago that appears this week was probably re-published or moved into the category you track, not launched this week.
Step 4: check before you act
- Open every "gone" URL. A renamed product gets a new URL, so it shows up once as gone and once as new. Hidden products, category moves and run caps look the same.
- Stock is product-level. In the Unadhi scraper,
inStockis true when any variant is available, so one sold-out size does not flip it. For size-level stock, look at thevariantscolumn (each variant has its ownavailableflag when the shop publishes it). - Blank stock means unknown, not out of stock. Some shops do not publish availability. The formula above skips blanks on purpose.
- One week is noise. A product sold out two weeks running tells you more than a one-day gap.
What not to do
- Do not run it daily "just in case". Weekly is enough to see catalogue changes and keeps your load on the shop light.
- Do not ignore robots.txt or terms that forbid scraping. Drop that shop.
- Do not place fake orders or add items to a cart to test stock levels. Use only what the shop publishes.
This guide is general information, not legal advice. You are responsible for how you use the data and for following each shop's terms and your local law. The Apify Actor mentioned reads only public pages, uses an honest bot User-Agent, follows robots.txt, never logs in and never gets around blocks.
Partner programme opening soon
Partner programme opening soon: join the free waitlist. Planned terms are 50% of each referred sale (75% once you have 5+ paying customers), single level, paid through Gumroad only from revenue received.
Related
- Build a weekly competitor price sheet (price moves, not catalogue changes)
- Export a Shopify store's products to CSV
- Export a WooCommerce store's products to CSV without a plugin
- Copy-paste inputs for the Contact Details and Product scrapers
- Want to ask a competitor-turned-supplier about stock? Related only: Website Contact Scraper: Emails, Phones & WhatsApp (also an Unadhi Apify product) finds a shop's published role inboxes such as sales@. Use it for genuine one-to-one enquiries, not bulk cold email.
Unadhi Guides are free, independent explainers. We correct errors as soon as we find them: write to mininglife7@gmail.com.