🎉 Premium Proxies · 24-Hour Free TrialClaim Now
Guides

How to Scrape Wayfair Product Data: Prices & SKUs

Scrape Wayfair product data at scale: pull SKUs, per-option prices, reviews, and stock from the page JSON, and get past PerimeterX with a scraping API.

S SparkProxy 0 24 min read
Share
How to Scrape Wayfair Product Data: Prices & SKUs

To scrape Wayfair product data cleanly, you have two jobs, plus a third that catches almost everyone out. The first two are the usual pair: read the structured data Wayfair already ships inside every page, and get past PerimeterX, the HUMAN Security bot layer that decides whether you load that page at all. The third is specific to Wayfair. A single listing is not one product with one price. It is a parent (Wayfair calls it a SuperSKU) that fans out into many buyable options, where each color, size, and finish carries its own SKU, its own price, and its own stock. Scrape only the price you see on load and you store a number most of your shoppers will never pay. This guide walks the whole pipeline for public catalog data: the fields worth pulling, how Wayfair's option model works, how to read both the JSON-LD and the hidden application JSON, how to catch a PerimeterX block that returns HTTP 200, where reviews live, and how to discover SKUs at volume. Every code sample uses SparkProxy's Scraping API, so the anti-bot work is one request parameter instead of an infrastructure project.

What Wayfair data you can extract (fields reference)

A public Wayfair product page (a PDP) lives at a URL that ends in .html with a product identifier, along the lines of /furniture/pdp/-.html. The visible fields are stable, and the reliable ones come out of the page's structured data rather than the rendered DOM. Here is the reference set worth pulling, and which source each field comes from.

FieldWhere it livesExampleNotes
SKUJSON-LD `sku`; per-option `sku` in app JSON`"MCRR2249"`The buyable unit's key; one listing has many
Product nameJSON-LD `name``"Mercury Row 84'' Rolled Arm Sofa"`The parent listing name
BrandJSON-LD `brand.name``"Mercury Row"`Wayfair private or partner brand
Price rangeJSON-LD `offers.lowPrice` / `highPrice``499.99` / `1299.99`An `AggregateOffer` spanning options
Per-option priceApp JSON, per option`749.00`The number a shopper actually pays
CurrencyJSON-LD `offers.priceCurrency``"USD"`Currency code
AvailabilityApp JSON, per option `inStock``true`Per option, not per listing
RatingJSON-LD `aggregateRating.ratingValue``4.5`Average, 0 to 5
Review countJSON-LD `aggregateRating.reviewCount``2317`Integer count
OptionsApp JSON `options` / option categoriesColor, SizeEach combination resolves to a SKU
ImageJSON-LD `image`; per-option in app JSONimage URLOptions often have their own photos

The SKU is your anchor, but read the next section before you decide what a "SKU" means on Wayfair, because it is the one place this target differs from Amazon or Best Buy in a way that quietly corrupts datasets.

Free trial

Scraping at scale? Skip the blocks.

Fast, unblockable datacentre proxies with unlimited bandwidth.

The option and SuperSKU model

Here is the Wayfair-specific gotcha, and it is the whole reason this guide exists as its own post. On most retailers a product page maps to one sellable thing with one price. On Wayfair, a product page is a SuperSKU: a parent listing that groups a set of purchasable options, and every option combination is its own SKU with its own price, its own inventory, and often its own image.

Take a sofa offered in six upholstery colors and two sizes. That is one PDP, one URL, one product name, and up to twelve buyable SKUs behind it. The gray loveseat and the blue three-seater are different prices and can differ in stock. A rug listing in eight sizes is eight SKUs, and the price gap between the 5x8 and the 9x12 is not small. If your scraper reads the price rendered on first load and writes one row per PDP, you have recorded the default option and thrown away the other eleven. Worse, you cannot tell later which option that price belonged to.

Contrast this with the sibling retailers. On Amazon and Walmart the classic trap is location: the same item shows different prices by ZIP or store, so you pin a location. On Wayfair the base price is essentially national, and the trap is the option. Pinning a ZIP does nothing for you here. Enumerating the options is the job.

There are two ways to capture every option's price:

  • Read the options out of the application JSON that hydrates the page. It already contains the full option tree and, in most page versions, the per-option price and stock. This is the fast path: one request, all options.
  • Drive the option selector with a browser scenario, clicking each option and re-reading the price, when the JSON only carries the currently selected option's price. Slower, but it survives page versions that lazy-load per-option pricing.

Design your schema for this from the start. One row per option SKU, each carrying the parent SuperSKU id and the option labels (color, size) that define it. That is the difference between a price feed you can trust and a pile of default-option noise.

Where the data lives: JSON-LD and the app JSON

Wayfair's storefront is a React application, so scraping the rendered DOM with CSS selectors is the brittle path: class names are hashed and the layout shifts. Two structured sources are far steadier.

JSON-LD. Every PDP embeds a