[{"data":1,"prerenderedAt":271},["ShallowReactive",2],{"learn-lesson-competitor-price-monitoring-extract-price-stock-and-shipping":3},{"course":4,"lesson":68,"index":227,"outline":228,"prev":269,"next":270},{"slug":5,"order":6,"level":7,"time":8,"card_text":9,"seo":10,"hero":16,"outcomes":26,"who":36,"syllabus":47,"faq":50,"lessonCount":67},"competitor-price-monitoring",1,"No coding required","8 lessons, about 90 minutes","From \"we check three competitors by hand on Mondays\" to a feed you trust enough to reprice from. The eight decisions in order, including the two that quietly ruin most projects.",{"title":11,"description":12,"keywords":13,"og_title":14,"og_description":15},"Competitor Price Monitoring: A Free 8-Lesson Course","Build a competitor price monitoring pipeline end to end: pick competitors, find product URLs, extract prices, match to your catalogue, schedule, export, reprice. Free, ungated.","competitor price monitoring, price monitoring course, how to track competitor prices, price tracking pipeline, competitor price tracking tutorial, retail price monitoring","A free course on building a competitor price monitoring pipeline","Eight written lessons on the part nobody covers: matching, data quality, and turning prices into decisions.",{"badge":17,"title":18,"subtitle":19,"cta_primary":20,"cta_secondary":23},"Course one","Build a competitor price monitoring pipeline","Price monitoring looks like a scraping problem for about a week. Then you discover that scraping was the easy part, and the project actually lives or dies on which competitors you picked, whether their listings are really the same product as yours, and whether anyone notices the morning the feed comes back half empty. This course is those eight decisions, in the order you have to make them.",{"label":21,"url":22},"Start with lesson one","/learn/competitor-price-monitoring/what-is-competitor-price-monitoring",{"label":24,"url":25},"Try the free price checker","/tools/free-competitor-price-checker",{"title":27,"items":28},"What you will be able to do",[29,30,31,32,33,34,35],"Say which competitors matter to your margin, and defend the list to a finance director","Collect competitor product URLs without copying them one at a time","Decide which fields you actually need, and which ones are a trap","Judge a match rate honestly, including the denominator that most vendors quietly change","Spot a feed that has silently degraded before a buyer acts on it","Put the numbers where the decision is made, instead of in a dashboard nobody opens","Write a repricing rule that survives contact with a competitor who is out of stock",{"title":37,"for_title":38,"for":39,"not_title":43,"not_for":44},"Who this is for","Written for",[40,41,42],"Pricing, category and e-commerce managers who own the number","Marketplace sellers repricing against a handful of named rivals","Anyone evaluating price monitoring vendors who wants to ask better questions","Not written for",[45,46],"Engineers who want a tutorial on CSS selectors and headless browsers — that is a different and much shorter problem","Anyone looking for a sub-second price feed; nothing here runs faster than daily",{"title":48,"intro":49},"The eight lessons","Each one ends where the next one starts. Four lessons are pure method; the ones that walk through our product say so in their own heading.",{"badge":51,"title":52,"description":53,"items":54},"FAQ","Before you start","Questions people ask in the first ten minutes.",[55,58,61,64],{"title":56,"description":57},"Do I need a Scrapewise account to follow this?","For five of the eight lessons, no. Lessons three, four and seven walk through doing the thing in our portal and are marked as needing an account. A new account comes with five free requests and no card, which covers those lessons.",{"title":59,"description":60},"Is scraping competitor prices legal?","This is not legal advice. Reading a publicly visible price is not the same question as storing it, republishing it, or building a product on it, and the answer changes by jurisdiction and by the site's own terms. Lesson two covers how to keep the collection narrow enough that the question stays simple, but take your own advice before you start.",{"title":62,"description":63},"How often can prices be checked?","This course assumes a daily cycle, which is what most retail pricing decisions actually run on. If you need minute-level reaction — a marketplace buy box, an airline fare — the architecture in lesson six is wrong for you and you want an event-driven system instead.",{"title":65,"description":66},"What if my competitors are not online retailers?","The method holds for any public price list: distributors, wholesalers, rental catalogues. What changes is lesson three, because those sites rarely have a clean product sitemap. Lesson three covers that case directly.",8,{"slug":69,"nav_title":70,"title":71,"summary":72,"time":73,"needs_account":74,"seo":75,"blocks":79,"takeaways":218,"next_step":223},"extract-price-stock-and-shipping","Extracting the fields","Getting price, stock and shipping off the page","Which fields to extract, why the sale price is two fields and not one, and the four ways a price appears on a page.","12 min",true,{"title":76,"description":77,"keywords":78},"Which Fields to Extract From a Competitor Product Page","Price is never one number. How to extract list price, sale price, currency, stock and shipping reliably, and which fields cost more than they are worth.","extract price from website, product page fields, scrape price and stock, json-ld price, competitor price fields, structured data product",[80,85,90,135,140,148,154,161,199,209],{"type":81,"paragraphs":82},"prose",[83,84],"Now the scraping. This is the part everyone pictures when they imagine price monitoring, and it is genuinely the least interesting stage — which is good news, because it means you can treat it as plumbing and spend your attention elsewhere.","Two decisions matter here. What to extract, and how to make it survive the competitor redesigning their site.",{"type":81,"title":86,"paragraphs":87},"Price is never one number",[88,89],"The most common beginner mistake is a single column called price. A product page typically shows a crossed-out original, a current selling price, sometimes a member price, sometimes a per-unit price underneath, and sometimes a basket-only price that is not displayed at all until checkout. Collapsing that into one number throws away the thing you most want to know, which is whether you are being undercut by a permanent reposition or by a three-day promotion.","Extract them separately and derive the comparison later. A discount percentage calculated at extraction time is a value you cannot recheck; two prices stored side by side can be re-derived any way you like, forever.",{"type":91,"title":92,"intro":93,"headers":94,"rows":98},"table","The field list","The first five are non-negotiable. The rest earn their place case by case.",[95,96,97],"Field","Take it?","Note",[99,103,106,109,112,115,119,123,127,131],[100,101,102],"price","Always","The current selling price as displayed, digits only, no symbol",[104,101,105],"list_price","The crossed-out original where one is shown; empty is a valid answer",[107,101,108],"currency","Stop guessing from the domain. Multi-market stores serve several currencies on one host.",[110,101,111],"availability","The exact words on the page, not your interpretation of them",[113,101,114],"url","The canonical URL, so you can click through and verify a surprising row",[116,117,118],"pack_size / unit","Usually","The single most valuable matching field in grocery, chemicals and anything sold by volume",[120,121,122],"shipping_cost","Sometimes","Often only visible at checkout. If it is on the page, take it; do not build a basket flow to get it.",[124,125,126],"seller_name","Marketplaces only","Meaningless on a single-brand store; essential on one where third parties list",[128,129,130],"ean / mpn","If shown","Worth more than every other field combined when it comes to matching",[132,133,134],"review_count","Rarely","Interesting, never actionable, and it changes every day so it bloats your change history",{"type":136,"variant":137,"title":138,"text":139},"callout","warning","Store the words, not your reading of them","\"Only 2 left\", \"Ships in 3-5 days\", \"Available to order\" and \"In stock\" are four different commercial situations. A pipeline that maps all of them to a boolean in_stock = true has destroyed information it cannot get back. Capture the exact string; classify it downstream where you can change your mind.",{"type":81,"title":141,"paragraphs":142},"Four places a price hides",[143,144,145,146,147],"Knowing which of these a site uses tells you immediately how fragile your extraction will be.","In the HTML, in a predictable element. The classic case. A CSS selector reads it, and it breaks the day the competitor changes their theme.","In JSON-LD structured data. Many stores publish a machine-readable Product block in the page source, for Google. When it is there and it is accurate, it is the best source available: it is explicitly a contract with search engines, so it changes far less often than the visual markup. It is also frequently incomplete, wrong on sale prices, or absent on exactly the pages you care about — so verify, do not assume.","In an internal API call the page makes after loading. The HTML arrives with a price-shaped hole in it and JavaScript fills it in. Any extraction that reads raw HTML gets nothing; you need something that runs the page's JavaScript first.","In an image. Rare, deliberate, and a signal that the site does not want to be read. Treat it as a competitor you track manually.",{"type":81,"title":149,"paragraphs":150},"Selectors versus a model that reads the page",[151,152,153],"A CSS selector is precise, free, fast and brittle. It encodes the competitor's current HTML structure into your pipeline, and it breaks on redesign — not with an error, which would be helpful, but usually by returning nothing or by returning the wrong element that happens to sit where the old one did.","The alternative is to describe the field in words and have a model find it on the rendered page. That survives a redesign, because a price is still visibly a price after the CSS changes. It costs more per page and it is not infallible — a model can also pick the wrong element, and it will do so with complete confidence.","In practice the deciding factor is maintenance headcount. If nobody owns fixing broken selectors within a day, selectors are a false economy: the cheapest extraction in the world is worthless on the mornings it returns nothing.",{"type":136,"variant":155,"title":156,"text":157,"cta":158},"product","Doing it in Scrapewise","You define the columns once in a Custom Schema — a field name, a type (text, number or yes/no), and a description that tells the extractor what to look for on the page. The description is the instruction, not a comment: \"stock status\" produces guesswork, while \"the exact text on the page showing stock status, for example In Stock, Out of Stock, Only 2 left\" produces the string you wanted. The same schema is then reusable across every competitor you point it at, which is what makes their columns line up.",{"label":159,"url":160},"See how custom scrapers work","/custom-scrapers",{"type":91,"title":162,"intro":163,"headers":164,"rows":168},"Worked example: one product page, eight columns","A single listing, as a shopper sees it on the left and as it should land in your table on the right. Every judgement has been deferred: nothing here is interpreted, only recorded. Note what is absent — there is no discount column, because 1 − 199 ÷ 249 is 20.1% today and will still be 20.1% whenever anyone asks, recomputed from two columns that were written down.",[165,166,167],"What the page shows","Column","Stored value",[169,172,176,179,183,187,191,195],[170,104,171],"€249.00, struck through","249.00",[173,174,175],"€199.00, in red","sale_price","199.00",[177,107,178],"The € symbol before the figure","EUR",[180,181,182],"\"In stock — 3 left\"","availability_text","In stock — 3 left",[184,185,186],"nothing on the page","availability_class","left empty, derived downstream",[188,189,190],"\"Free delivery over €50\"","shipping_text","Free delivery over €50",[192,193,194],"read at 06:14 on 14 March","captured_at","2026-03-14T06:14:00Z",[196,197,198],"the page the figures came from","source_url","https://…/p/12345",{"type":200,"title":201,"intro":202,"items":203},"list","What usually goes wrong","Extraction failures are rarely loud. Four of these five produce a table that looks entirely reasonable and is wrong.",[204,205,206,207,208],"One price column. The page showed two numbers and the table kept one, so nobody can separate a permanent reprice from a three-day promotion, and the discount history is gone for good.","Interpreting availability at capture time. \"Ships in 2–3 weeks\" becomes true in an in_stock boolean, and six months later nobody can reconstruct what the page actually said.","Trusting JSON-LD without verifying it. It is the most stable source on the page and also the one most often left stale after a promotion — check the sale price against the rendered page on a handful of listings before you rely on the field.","Keeping the price as a string with its symbol attached. €1.299,00 and $1,299.00 both parse to 1299, and both parse to 1.299 if you guess the separator wrong. Keep the number and the currency in separate columns.","Reading a market you did not mean to read. Several large retailers decide currency and price from a cookie rather than from the URL, so a run can capture the wrong country's figure correctly, with no error raised anywhere.",{"type":200,"title":210,"intro":211,"items":212},"Check these before you scale up","Run one page per competitor and look at the output with your own eyes. Five minutes here saves a month.",[213,214,215,216,217],"A product that is on sale — do you get both prices, in the right columns?","A product that is out of stock — do you get a price at all, and is it the right one?","A multi-variant product — which variant did you capture, and did you mean to?","A product in a second currency or market domain, if the competitor has one","The most expensive product you track — decimal separator errors turn 1.299,00 into 1.29 and nothing downstream will question it",[219,220,221,222],"Never store one price column. List price and sale price separately; derive the discount later.","Capture availability as the exact words on the page and classify it downstream.","JSON-LD is the most stable source when it exists, but verify it — sale prices in particular are often wrong.","Selectors are cheap and brittle; a model reading the page is dearer and survives redesigns. Choose based on who is on call to fix it.",{"text":224,"label":225,"url":226},"You now have competitor rows. The next lesson is the one that decides whether any of them mean anything.","Lesson 5: matching their listings to your catalogue","/learn/competitor-price-monitoring/match-listings-to-your-catalogue",3,[229,236,242,247,248,254,259,264],{"slug":230,"navTitle":231,"title":232,"summary":233,"time":234,"needsAccount":235},"what-is-competitor-price-monitoring","What it actually is","What competitor price monitoring actually is","The four stages of a price pipeline, why only two of them are scraping, and the one question to ask before you build anything.","9 min",false,{"slug":237,"navTitle":238,"title":239,"summary":240,"time":241,"needsAccount":235},"choose-competitors-and-skus","Choosing what to track","Choosing which competitors and which SKUs to track","How to build a list that is small enough to afford and large enough to matter, using margin at risk rather than gut feel.","11 min",{"slug":243,"navTitle":244,"title":245,"summary":246,"time":73,"needsAccount":74},"find-competitor-product-urls","Finding product URLs","Finding every competitor product URL without copying them by hand","Four ways to get a competitor's full product URL list, ranked by how much work they are, and what to do when none of them work.",{"slug":69,"navTitle":70,"title":71,"summary":72,"time":73,"needsAccount":74},{"slug":249,"navTitle":250,"title":251,"summary":252,"time":253,"needsAccount":235},"match-listings-to-your-catalogue","Matching to your catalogue","Matching competitor listings to your own catalogue","The stage that decides whether your feed is intelligence or fiction, and the denominator trick that makes bad match rates look good.","13 min",{"slug":255,"navTitle":256,"title":257,"summary":258,"time":241,"needsAccount":235},"schedule-runs-and-catch-silent-failure","Scheduling and data quality","Scheduling runs and catching silent data loss","How often to actually check, and the four alerts that catch a degrading feed before someone reprices from it.",{"slug":260,"navTitle":261,"title":262,"summary":263,"time":234,"needsAccount":74},"export-to-sheets-bi-and-erp","Getting the data out","Getting the data into Sheets, BI or your ERP","Four delivery routes ranked by how likely they are to actually get used, and the column contract that stops downstream jobs breaking.",{"slug":265,"navTitle":266,"title":267,"summary":268,"time":73,"needsAccount":235},"turn-price-data-into-repricing-rules","From data to decisions","Turning price data into repricing decisions","Why \"match the cheapest\" destroys margin, what a rule needs besides a competitor price, and how to start without automating anything.",{"slug":243,"navTitle":244,"title":245,"summary":246,"time":73,"needsAccount":74},{"slug":249,"navTitle":250,"title":251,"summary":252,"time":253,"needsAccount":235},1791047866760]