# Walmart Products Scraper & Price Tracker (`myth84/walmart-search-scraper`) Actor

Walmart products scraper and Walmart price tracker: scrape Walmart.com and Walmart.ca search results and category pages — price, was-price, discount, stock, rating, review count, badges, sponsored flag. USD or CAD. Track price drops between runs. One flat row per product, no personal data.

- **URL**: https://apify.com/myth84/walmart-search-scraper.md
- **Developed by:** [Flatrow Data Studio](https://apify.com/myth84) (community)
- **Categories:** E-commerce, Automation, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.99 / 1,000 products

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### Walmart Products Scraper & Price Tracker – prices, ratings and price drops, no personal data

- Verified daily by an automated run on Apify with the default input.
- Price: $1.50 per 1,000 products on the Free plan; on paid plans, from $0.99 for 1,000 (Business plan).
- Start fee: $0.00005 per run (Apify's minimum).

Walmart products scraper and Walmart price tracker: get Walmart prices, was-prices and discounts, stock, ratings and review counts for any keywords or category page on walmart.com and walmart.ca, as a clean table or through an API — no login. Use it as a Walmart scraper and Walmart price monitor with price drop alerts on scheduled runs, for competitor price monitoring, product research and price comparison with other marketplaces.

**No login, no cookies, no personal data:** nothing to sign in to, no cookies to paste, nothing about buyers, reviewers or private sellers in the output.

- **What you get:** one flat row per Walmart product for any keywords or category page on walmart.com (USD) and walmart.ca (CAD, English or French): price, was-price and discount, stock, rating and number of reviews, category, badges, sponsored and best-seller flags, image and link; a price-tracking mode that returns only the price drops, price rises and new products since your previous run. No personal data.
- **For whom:** price-tracking and competitive-intelligence teams, e-commerce brands and resellers, deal hunters, market analysts, AI agents through MCP.
- **How much:** from $1.50 per 1,000 products on the Free plan, lower on paid plans; Apify's free monthly credit of $5 covers about 3,333 products. A fixed price per product saved and nothing else (compute and proxy traffic included, see the Pricing tab); `maxResults` caps every run.

**Sample output**: one real row from a "wireless earbuds" search on walmart.ca, key columns only (the full row is under *Output example*):

```json
{
  "platformProductId": "0SG1RP1JP4QS",
  "title": "JYX Bluetooth 5.4 Earbuds, Wireless Earbuds with Noise Cancelling, 36 H Battery Life, Real-Time Translation with 115 Languages",
  "brand": "JYX",
  "category": "True Wireless Earbuds",
  "currency": "CAD",
  "price": 27.99,
  "originalPrice": 89.99,
  "discountPercent": 68.9,
  "inStock": true,
  "rating": 4.3,
  "reviewCount": 37,
  "isSponsored": true
}
```

Scrape Walmart search results for any keywords, or any Walmart category page, on **walmart.com** (prices in USD) and **walmart.ca** (prices in CAD, pages in English or in French), and get **one flat row per product**: current price, strike-through "was" price and discount, amount saved, stock status, average rating and number of reviews, brand, category path, Walmart badges (best seller, rollback, clearance, reduced price, popular picks), sponsored flag, variants, other offers, unit price, delivery estimate, main image and position in the results. Sort by price, filter by price range, or paste your own Walmart search or category URLs with their filters; turn on price monitoring to get only what changed since your previous run. This Walmart scraper reads the public result pages without logging in, keeps one browsing session per search, skips the recommendation modules mixed into the results, removes duplicates and stops exactly at the number of products you ask for.

**No personal data, by design.** Walmart product cards carry no information about buyers; review texts and their authors are never collected, only the average rating and the number of reviews. Sellers are named only when they are Walmart itself or a registered Walmart Marketplace business; nothing else about a seller is ever kept. Every row goes through a privacy filter before it is saved. The dataset is safe to store, share and feed to AI agents.

### What can you do with Walmart data?

- **Track prices and discounts** of a product family on walmart.com or walmart.ca: rollbacks, clearance, was-prices and the amount saved, with a scheduled price-monitoring run that returns only the price drops, price rises and new products.
- **Watch the competition and your own listings**: rank of each product for a keyword, sponsored placements, best-seller badges, ratings and review counts, stock status.
- **Study a market or a category**: price distribution, brands, share of sponsored results, the products Walmart pushes first in a category page.
- **Compare marketplaces and countries** with a stable, documented schema shared by the other scrapers of this e-commerce studio (eBay Scraper and AliExpress Scraper use the same columns), USD and CAD side by side.

### What data does Walmart Scraper extract?

Every row has every column: a value Walmart does not show in the results is `null` (or `[]` / `{}` for lists and objects), so CSV and Excel exports keep the same columns from run to run.

| Group | Columns |
|---|---|
| Identity | `schemaVersion`, `platform`, `platformProductId`, `variantId`, `url`, `title`, `brand`, `category`, `categoryPath` |
| Prices | `currency`, `price`, `originalPrice`, `discountPercent`, `inStock`, `stockQuantity` |
| Popularity | `rating`, `ratingMax`, `reviewCount`, `soldCount`, `isBestSeller`, `isChoice`, `listedAt` |
| Seller | `storeType`, `storeName`, `storeId`, `storeUrl`, `storeRating` |
| Shipping | `shippingFree`, `shippingCost`, `deliveryEstimate`, `shipsFrom` |
| Media and attributes | `imageUrl`, `imageCount`, `attributes` |
| Search context | `isSponsored`, `searchQuery`, `searchRank`, `searchPage`, `viewCountryCode`, `scrapedAt` |
| Price monitoring | `changeType`, `previousPrice`, `priceDelta`, `priceDeltaPercent` (filled in price-monitoring runs only, see *Price monitoring*; `null` otherwise) |

Result pages show a subset of what a product page holds. For this Actor, `stockQuantity`, `soldCount`, `shipsFrom`, `isChoice`, `listedAt`, `storeUrl` and `storeRating` are always empty, and `imageCount` is filled only when the page lists the product's images. `brand` is often `null` on walmart.com results and usually filled on walmart.ca. `storeType` is `platform` (sold by Walmart, `storeName` "Walmart"), `business` (a Walmart Marketplace seller, which must be a registered business: `storeName` is its business name) or `unknown` when the page does not say, which is common; `storeName` and `storeId` stay `null` for `unknown`. `shippingFree` is `true` only when a badge says shipping is free without condition, `false` when a shipping price is shown (mostly marketplace items), `null` otherwise. `deliveryEstimate` is the delivery wording of the product when the page carries one, otherwise the date Walmart computes for the first delivery option (an ISO 8601 timestamp).

`attributes` holds the other facts of the product as flat strings, only the keys the product shows: `condition` (`new` or `pre-owned`), `classType` (`VARIANT` or `REGULAR`), `catalogProductType` ("Headphones"), `fulfillmentType` (`FC`, `STORE`, `MARKETPLACE`), `badges` (Walmart badge keys joined by `|`: `BESTSELLER`, `ROLLBACK`, `CLEARANCE`, `REDUCED_PRICE`, `FLASH_DEAL`…), `variants` (option names joined by `|`: "Black|Grey|Pink|White"), `salesUnit`, `unitPrice` ("$24.99/count"), `additionalOfferCount` (offers from other sellers), `categoryPathId` (Walmart's numeric category ids), `priceFrom` and `priceMax` (range of the options, or "more options from"), `savings` (amount saved), `walmartPlusPrice`, `subscriptionPrice`, `socialProof` ("In 200+ people's carts") and `boughtRecently` ("100+ bought in past month").

### How to scrape Walmart products

1. **Enter search keywords**, one per line ("wireless earbuds", "coffee maker"), or paste **Walmart search or category URLs** copied from your browser, with their filters (the URL decides the site and the language).
2. **Choose the site**: walmart.com (USD) or walmart.ca (CAD), and for walmart.ca the language of the pages (English or French).
3. **Set the maximum number of products per search**, the sort order (best match or price low to high) and, if needed, a price range.
4. **Run** and open the **Output** tab: the *Overview*, *Prices*, *Availability* and *Ranking* views show the main columns; export everything as JSON, CSV, Excel or through the API.
5. **To track prices**, turn on `monitorPrices` and `onlyChanges` and schedule the run: from the second run on you get only the price drops, price rises and new products, in the *Changes* view.

### Input

Give at least one keyword in `searchQueries` or one URL in `startUrls` (with nothing at all, "wireless earbuds" is searched). Field names and defaults are those of the input form.

The input of our validation run: the first 60 products for "wireless earbuds" on walmart.com in Walmart's best-match order (every other field keeps its default):

```json
{
  "searchQueries": [
    "wireless earbuds"
  ],
  "site": "US",
  "sortBy": "best_match",
  "maxResults": 60
}
```

Every field, with its type and default:

| Field | Type | Default | Description |
|---|---|---|---|
| `searchQueries` | string\[] | `["wireless earbuds"]` | Search keywords, one search per entry, as typed in the Walmart search box. |
| `startUrls` | string\[] | `[]` | Walmart search URLs (`/search?q=...`) or category URLs (`/browse/...`) copied from your browser, on walmart.com or walmart.ca; their filters are kept, the URL decides the site and the language. The sort order and price range below are applied on top only when set. walmart.com.mx is not supported. |
| `site` | string | `"US"` | `US` (walmart.com, USD) or `CA` (walmart.ca, CAD), both validated. Used for keyword searches; a URL keeps its own site. |
| `language` | string | `"en"` | `en` or `fr`: language of the walmart.ca pages (French titles, categories, badges and "39,99 $" prices). French requires `site: "CA"`. |
| `maxResults` | integer | `100` | Stop each search after this many unique products (1 to 2,000). You are never charged for more. The form is prefilled with 20 for a quick first run. |
| `sortBy` | string | `"best_match"` | `best_match` (Walmart default) or `price_low` (price low to high), both validated; `price_high`, `best_seller`, `rating_high` and `new` use Walmart's URL parameters and are not verified yet. |
| `priceMin` | number | — | Minimum price in the site currency, e.g. `20` (Walmart's filter, which rounds its bounds; validated on walmart.com, not verified on walmart.ca nor on category pages). |
| `priceMax` | number | — | Maximum price in the site currency, e.g. `50`, at least `priceMin` (same filter and caveats as `priceMin`). |
| `includeSponsored` | boolean | `true` | Keep the sponsored products mixed into the results (flagged in `isSponsored`) or skip them; skipped products keep their place in `searchRank`. |
| `maxPages` | integer | `20` | Safety cap on result pages read per search (Walmart offers about 13 per search). |
| `monitorPrices` | boolean | `false` | Price monitoring: compare every product with the previous run of the same search (by Walmart product id and site) and fill `changeType`, `previousPrice`, `priceDelta`, `priceDeltaPercent`. `maxResults` then counts the products compared per search. See *Price monitoring*. |
| `onlyChanges` | boolean | `false` | With `monitorPrices`: return and charge only the new products and the price changes; a run without any change succeeds with an empty dataset. |
| `monitorStoreName` | string | `"walmart-price-monitor"` | Key-value store of your account that keeps the previous prices, one record per search (letters, digits and dashes, lower-cased). One name per schedule when two schedules run the same search. |
| `proxyConfiguration` | object | `{"useApifyProxy":true}` | The default (Apify Proxy, automatic group, no country) is the configuration validated for Walmart and its traffic is included in the price: keep it. Other Apify proxy groups and your own proxy URLs are accepted; they are not needed. |
| `maxRequests` | integer | `500` | Safety cap on result pages fetched in one run, all searches and retries included. |
| `delayMs` | integer | `2500` | Pause between two page requests of the same search, in milliseconds. Walmart slows down clients that go faster. |
| `debugStoreHtml` | boolean | `false` | Debugging only: store every fetched page in the key-value store (1 to 2 MB each). |
| `debugSendAccept` | boolean | `false` | Debugging only: send a browser-like `Accept` header (the validated requests sent only `Accept-Language`). |

### Output example

One real row, produced by the Actor from a "wireless earbuds" search on walmart.ca in English (the first, sponsored product of the results page). All columns are present, in this order, for every product:

```json
{
  "schemaVersion": "ecommerce-product/1.1",
  "platform": "walmart",
  "platformProductId": "0SG1RP1JP4QS",
  "variantId": "16K623DL415G",
  "url": "https://www.walmart.ca/en/ip/JYX-Bluetooth-5-4-Earbuds-Wireless-Earbuds-with-Noise-Cancelling-36-H-Battery-Life-Real-Time-Translation-with-115-Languages/0SG1RP1JP4QS",
  "title": "JYX Bluetooth 5.4 Earbuds, Wireless Earbuds with Noise Cancelling, 36 H Battery Life, Real-Time Translation with 115 Languages",
  "brand": "JYX",
  "category": "True Wireless Earbuds",
  "categoryPath": [
    "Electronics",
    "Headphones",
    "Earbuds",
    "True Wireless Earbuds"
  ],
  "currency": "CAD",
  "price": 27.99,
  "originalPrice": 89.99,
  "discountPercent": 68.9,
  "inStock": true,
  "stockQuantity": null,
  "rating": 4.3,
  "ratingMax": 5,
  "reviewCount": 37,
  "soldCount": null,
  "storeType": "unknown",
  "storeName": null,
  "storeId": null,
  "storeUrl": null,
  "storeRating": null,
  "shippingFree": null,
  "shippingCost": null,
  "deliveryEstimate": "2026-10-20T19:00:00.000Z",
  "shipsFrom": null,
  "imageUrl": "https://i5.walmartimages.ca/asr/92da1f0a-636d-45d5-be1b-4cbad1846e09.6afb5fc117684de2c6c7a11277c4228d.jpeg",
  "imageCount": null,
  "attributes": {
    "classType": "VARIANT",
    "fulfillmentType": "FC",
    "badges": "HALLOWEEN_TOP_PICKS",
    "variants": "Black|Grey|Pink|White",
    "salesUnit": "EACH",
    "categoryPathId": "10003:30509:6000188524346:6000201925436",
    "savings": "62.00"
  },
  "isSponsored": true,
  "isBestSeller": false,
  "isChoice": null,
  "listedAt": null,
  "searchQuery": "wireless earbuds",
  "searchRank": 1,
  "searchPage": 1,
  "viewCountryCode": "CA",
  "scrapedAt": "2026-10-20T00:00:00.000Z",
  "changeType": null,
  "previousPrice": null,
  "priceDelta": null,
  "priceDeltaPercent": null
}
```

`price` is the price displayed in the results, shipping not included; `originalPrice` is the strike-through "was" price when Walmart shows one, `discountPercent` the percentage off computed from it (one decimal) and `attributes.savings` the amount saved as displayed. The last four columns are filled in price-monitoring runs only (see *Price monitoring*).

The **Output** tab offers five views of the same rows: **Overview** (title, price, currency, was price, discount, in stock, rating, reviews, best seller, sponsored, link, image), **Prices** (product and variant ids, price, was price, discount, currency, attributes with badges and offers, seller kind and name, link), **Availability** (price, in stock, free shipping, shipping cost, delivery, seller kind and name, site country), **Ranking** (query, page, rank, sponsored and best-seller flags, rating, reviews, category, site country) and, for price-monitoring runs, **Changes** (change, title, price, previous price, change and change %, currency, was price, discount, in stock, product id, query, site country, link).

### Price monitoring

Turn on `monitorPrices` and `onlyChanges`, then **schedule the run** (daily is typical): the Actor becomes a Walmart price tracker that sends you the price drops. It keeps the last displayed price of every product it compared in a key-value store of your account (`monitorStoreName`, `walmart-price-monitor` by default), with one record per search (same keywords or URL, site, language, sort order and price range); a product is identified by its Walmart product id and its site (walmart.com in USD or walmart.ca in CAD). The first run of a search is the reference: every product comes back with `changeType` = `"new"` (and `RUN_STATS.monitorBaseline` is true). From the second run on, with `onlyChanges` the dataset holds **only the new products and the products whose price changed**, with the previous price and the difference, and **only those rows are charged**; a run where nothing changed succeeds with an empty dataset. Without `onlyChanges`, every compared product is returned with its `changeType` (`new`, `price_changed` or `unchanged`). In both cases `maxResults` is the number of products compared per search.

A scheduled input that watches the 100 first "wireless earbuds" results of walmart.com, cheapest first:

```json
{
  "searchQueries": ["wireless earbuds"],
  "site": "US",
  "sortBy": "price_low",
  "maxResults": 100,
  "monitorPrices": true,
  "onlyChanges": true,
  "monitorStoreName": "earbuds-daily"
}
```

A `price_changed` row, as the Actor produces it from the row of the output example when the previous run had recorded 31.99 CAD (the other columns are the same as above):

```json
{
  "platformProductId": "0SG1RP1JP4QS",
  "title": "JYX Bluetooth 5.4 Earbuds, Wireless Earbuds with Noise Cancelling, 36 H Battery Life, Real-Time Translation with 115 Languages",
  "currency": "CAD",
  "price": 27.99,
  "changeType": "price_changed",
  "previousPrice": 31.99,
  "priceDelta": -4,
  "priceDeltaPercent": -12.5
}
```

What to know before relying on it:

- **The record is written only after a search that ended cleanly.** A failed or empty search, a page given up after three unusable answers in a row, a run stopped by its budget (`maxRequests` or your charge limit) or an interrupted run never overwrites the reference, so a bad day cannot erase your prices; the log says when a record was kept unchanged (`RUN_STATS.monitor` counts the records written and skipped).
- **Prices are compared as displayed, in the same currency.** The displayed price is what gets compared, shipping excluded: a new rollback or clearance shows as a price drop, a new badge alone does not. A product shown without a price is reported `unchanged` and keeps its last known price, so that a price that comes back lower is reported as a drop. The prices are the national prices of the site, without a store or a postal code (see *Limits*).
- **Rankings move.** Walmart reorders its results and its sponsored placements from one visit to the next, so the set of compared products (the first `maxResults` of each search) drifts a little from run to run; a product that drops out of the results and comes back later is not reported as new (its last price is kept for 90 days). Sort by price, use a price range or a category URL, or skip sponsored products (`includeSponsored: false`) to get a stable set.
- **Several searches in one run.** Each search compares its own products, so a product found by two searches of the run is recorded in both; it is written to the dataset (and charged) only once per site (`RUN_STATS.extra.monitorDuplicatesNotWritten`).
- **One store per schedule when searches collide.** Runs sharing a `monitorStoreName` share the records: two schedules with the same keywords, site, language, sort and price range would overwrite each other's reference, so give them different store names. Changing the keywords, site, language, sort or price range of a search starts a new reference for it. Delete the key-value store in Apify Console to start over.

### How much does it cost to scrape Walmart?

This Actor uses **pay-per-event pricing: you pay a fixed price per product** saved to your dataset, and nothing else. On the Free plan, products cost $1.50 per 1,000, so Apify's free monthly credit of $5 covers about 3,333 products; paid plans pay less per product, and the price of every plan tier is on the **Pricing tab** of this page.

| What you pay for | How it is counted | Price |
|---|---|---|
| `result` event: one product saved to your dataset | once per unique product of the run, capped by `maxResults` | Pricing tab, per plan tier |
| Run start | a symbolic amount, once per run | Pricing tab |
| Compute, proxies, storage and data transfer | included: no platform usage is passed on to you | — |

The cost of a run is known before you start: 1,000 products cost 1,000 times the `result` price of your tier, whatever the number of pages fetched. In price-monitoring runs with `onlyChanges`, only the new products and the price changes are charged. A page of about 50 products takes 2 to 3 seconds plus the pause between pages: 100 products in about 15 seconds, a full search of about 500 products in about a minute.

### Limits and behaviour worth knowing

- **Search and category results only.** The Actor reads result pages, not product pages: specifications, full descriptions, UPC codes, every variant's price, stock quantities and customer reviews are not available (see the column notes above). Product pages, reviews, seller profiles and store inventories are out of scope.
- **National prices, no store or postal code.** Walmart's prices and stock can depend on the store attached to a visitor; the Actor reads the default national prices of the site, without a store, a postal code or a Walmart+ account. Prices you see in a browser with your own store selected may differ.
- **About 500 unique products per search.** Walmart offers about 13 result pages of about 50 products for a search (25 on walmart.ca), 30 products per page on a category page (up to 50 pages). Sponsored products and "more options" tiles repeat from one page to the next: the scraper removes duplicates by product id across the whole run (within each search in price-monitoring runs; `RUN_STATS.extra.duplicatesSkipped`), stops at Walmart's last page, when two consecutive pages bring nothing new, or at `maxResults` / `maxPages`.
- **Recommendation modules are skipped.** Walmart's result pages mix "4 stars and above", "Don't miss these savings" or "Shop trending items" carousels and ad tiles into the results; only the "Results for …" lists are read (`RUN_STATS.extra.stacksSkipped`). If a page ever has no such list, it is read whole and counted in `RUN_STATS.extra.stackFallbacks` (a layout change to report).
- **Sponsored products.** About 10 products of each page of 50 are sponsored (none when sorting by price); they are flagged in `isSponsored`, counted in `RUN_STATS.extra.sponsoredSeen` and can be skipped with `includeSponsored`. `searchRank` counts every product of the result lists, sponsored ones included.
- **The site changes everything.** The catalogue, the prices, the currency and the language are those of the site: walmart.com rows (USD) and walmart.ca rows (CAD) are not comparable as such, and `viewCountryCode` tells which site each row comes from. walmart.com.mx is not supported.
- **Not verified yet.** The `price_high`, `best_seller`, `rating_high` and `new` sort orders, and the price filter on walmart.ca or on category pages, use Walmart's public URL parameters and were not exercised at build time: they are marked as such in the input form and confirmed at the first runs. Check the order and the prices of the first rows if you rely on them.
- **Rate limit and unusable pages.** Walmart slows down clients that request pages too fast: the scraper pauses `delayMs` between pages, waits when Walmart asks it to (`RUN_STATS.extra.rateLimited`) and retries an unusable page on a new session, then gives up that search after three unusable answers in a row and reports it in the log. Persistent problems are fixed as a priority: open an issue with your run id.
- **No empty successes.** A run that finds no product ends as failed with an explicit message (keywords misspelt, price range too strict, refused requests or a proxy configuration error), so that your schedules and integrations notice. The one exception is a price-monitoring run that compared products and found no change: it succeeds with an empty dataset.

### Integrations and API

Start the Actor from Apify Console, schedule it, or call it from the [Apify API](https://docs.apify.com/api/v2) with any language (the **API** tab shows ready-made code for Node.js, Python and curl). Webhooks notify your systems when a run finishes; the dataset can be pulled as JSON, CSV, Excel, XML or RSS, or pushed to Google Sheets, Make, Zapier, n8n, Slack, Airtable, Google Drive and more through the Apify integrations.

### Use it from your AI assistant

Add this Actor as a tool to Claude, ChatGPT, Cursor, VS Code or any MCP client with the Apify MCP server URL below (sign in with your Apify account when asked):

`https://mcp.apify.com?tools=myth84/walmart-search-scraper`

Then ask in plain words. Copy this prompt and change the details:

```text
Use myth84/walmart-search-scraper to track the prices of the 30 cheapest air fryers between 50 and 100 dollars on walmart.com and tell me which ones dropped since my last check. Input: {"searchQueries": ["air fryer"], "site": "US", "sortBy": "price_low", "priceMin": 50, "priceMax": 100, "maxResults": 30, "monitorPrices": true, "onlyChanges": true, "monitorStoreName": "air-fryers-watch"}. The first run records the prices; from the second run on, show the title, price, previous price, change and link of each product.
```

### For AI agents (MCP)

Through the [Apify MCP server](https://docs.apify.com/mcp) this Actor is a tool that answers questions such as *"what do the cheapest wireless earbuds cost on Walmart right now?"*, *"which air fryers between 50 and 100 dollars are best rated on walmart.com?"* or *"which of these products got cheaper on Walmart since yesterday?"*.

**Minimal input** (every other field keeps its default; raise `maxResults` only when the question needs more rows):

```json
{
  "searchQueries": [
    "air fryer"
  ],
  "site": "US",
  "priceMin": 50,
  "priceMax": 100,
  "maxResults": 20
}
```

- **Key output fields**: `platformProductId`, `title`, `url`, `price`, `originalPrice`, `discountPercent`, `currency`, `inStock`, `rating`, `reviewCount`, `isBestSeller`, `isSponsored`, `brand`, `category`, `attributes.badges`, `searchRank`, `viewCountryCode`; in price-monitoring runs `changeType`, `previousPrice`, `priceDelta`, `priceDeltaPercent`. Every column is always present, in a fixed order; `null` means Walmart did not show the value. The full list is in *What data does Walmart Scraper extract?* above.
- **Use it when** you need current Walmart search or category results for keywords on walmart.com or walmart.ca: prices, was-prices, discounts, stock, ratings, review counts, badges, sponsored flags, images. Pass `searchQueries` (or `startUrls`), `site`, optionally `language`, `sortBy`, `priceMin` / `priceMax`, and a small `maxResults` (20–60 is enough for an answer and fits in one or two pages). To report price changes between two calls, pass `monitorPrices: true`, `onlyChanges: true` and a stable `monitorStoreName`.
- **Do not use it for** product specifications, customer reviews, store-specific prices or stock, seller information, walmart.com.mx or anything behind a login: it only reads public result pages and collects no personal data.
- **Cost per 1,000 results**: 1,000 `result` events, $1.50 per 1,000 on the Free plan and less on paid plans (Pricing tab); nothing else is charged (in price-monitoring runs with `onlyChanges`, unchanged prices are free).
- **Typical time**: about 5 seconds per page of 50 products, pause included: 20 products in a few seconds, a few hundred in about a minute.

### Alternatives and switching

- **Official API.** Walmart's official APIs are made for its marketplace sellers and approved affiliate partners and need an approved account and keys. This Actor reads what any visitor sees in Walmart search and category results (public prices, was-prices, stock, ratings, badges, sponsored flags) with no account, no keys and no approval.
- **Your own scraper.** Nothing to build or maintain: sessions, retries, pagination, deduplication and Walmart page changes are handled for you. The columns stay the same from run to run, a run that finds nothing fails with an explicit message instead of succeeding empty, and a scheduled test run catches Walmart changes early.
- **Another scraper from the Store.** The input names differ from one Actor to the next; the usual ones map to this Actor as follows:

| Usual input | Here | Note |
|---|---|---|
| `search`, `query`, `keyword` | `searchQueries` | Several keywords per run |
| `startUrls` | `startUrls` | Walmart search or category URLs, filters included |
| `maxItems`, `limit` | `maxResults` | Unique products per search, never charged beyond |
| `country`, `domain` | `site` | `US` (walmart.com, USD) or `CA` (walmart.ca, CAD) |
| `language` | `language` | `en` or `fr` (walmart.ca) |
| `sort` | `sortBy` | `best_match` or `price_low` |
| `minPrice`, `maxPrice` | `priceMin`, `priceMax` | In the site currency |
| `includeAds`, `sponsored` | `includeSponsored` | Keep or skip the sponsored products |
| `proxy` | `proxyConfiguration` | Keep the default: proxies are included in the price |

### FAQ

#### Does Walmart Scraper collect personal data?

No. Walmart result pages carry no buyer information, and the scraper never collects review texts or their authors (only the average rating and the number of reviews). Sellers are named only when they are Walmart itself or a registered Walmart Marketplace business; any other seller detail is dropped. Every row goes through a privacy filter before it is saved.

#### Is it legal to scrape Walmart?

The Actor only reads pages that Walmart serves to any visitor without an account, and it stores no personal data. Scraping public data is generally lawful, but Walmart's terms of use and robots policy restrict automated access, and you are responsible for how you use the results and for complying with the laws that apply to you (including copyright on product texts and images). Use the data for analysis, not to republish Walmart's catalogue.

#### Do I need proxies, and do I pay for them?

No extra setup: the default proxy configuration is the one validated for Walmart, and its traffic is included in the price per product: you pay per product, nothing more. Keep the default and do not set a proxy country; other Apify proxy groups and your own proxy URLs are accepted, but they are not needed.

#### Which Walmart sites, currencies and languages are supported?

Two sites: walmart.com (United States, USD, English) and walmart.ca (Canada, CAD, English or French with `language: "fr"`). Both were validated at build time, for keyword searches and for category pages. walmart.com.mx (Mexico) is not supported.

#### Can I scrape a Walmart category instead of a search?

Yes. Paste a category URL (`https://www.walmart.com/browse/...`, or the same on walmart.ca) into `startUrls`: the scraper reads its result pages the same way, about 30 products per page, and fills `searchQuery` with the category name. Search URLs with their own filters (`/search?q=...&facet=...`) are accepted too.

#### What do `price`, `originalPrice`, `discountPercent` and `attributes.priceFrom` mean?

`price` is the current price displayed in the results, shipping excluded. `originalPrice` is the strike-through "was" price of a rollback, clearance or reduced price, and `discountPercent` the percentage off computed from it; `attributes.savings` is the amount saved as Walmart shows it. `attributes.priceFrom` and `attributes.priceMax` give the price range of a product's options, or the lowest price of other sellers' offers ("More options from $6.90").

#### Why are some products sponsored, and why do I get fewer products than Walmart announces?

Walmart mixes about 10 sponsored products into each page of 50 and repeats some of them on the next pages; they are flagged in `isSponsored` and can be skipped with `includeSponsored`. Walmart announces thousands of results but shows only about 13 pages per search; after removing the repeated products a search yields about 500 unique products. Run several related keywords or category URLs to go further.

#### Are the prices those of my local store?

No. The scraper reads the national prices of the site, without a store, a postal code or a Walmart+ membership, so a price may differ from what you see with your own store selected. Store-specific prices and inventories are out of scope for now.

#### How often should I run it, and how do I get only price changes?

Every run fetches live result pages. Prices, rollbacks and rankings change by the day, so schedule the Actor as often as your use case needs (daily is typical for price tracking) and compare runs by `platformProductId` and `currency`, or let the Actor compare them for you: turn on `monitorPrices` and `onlyChanges`, keep the default `monitorStoreName` (or one per schedule) and schedule the run. The first run records every product of the search and returns it as `new`; each later run returns only the products that appeared since and the products whose displayed price changed, with `previousPrice`, `priceDelta` and `priceDeltaPercent`, and charges only those rows. A run without any change succeeds with an empty dataset. Keep the same keywords, site, language, sort and price range from run to run. Turn `onlyChanges` off to get every product with its `changeType`.

#### How do I export or integrate the results, and where do I get support?

From the run's Output tab (JSON, CSV, Excel, XML, RSS) or automatically: Apify API, webhooks, scheduled runs and integrations with Google Sheets, Make, Zapier, n8n, Slack and others; AI agents can call the Actor through the Apify MCP server. For bugs or questions, open an issue in the **Issues** tab of this Actor with your run id and input: page-layout changes are fixed as a priority, feature requests (product pages, store prices, other marketplaces of the studio) are welcome.

### More scrapers by Flatrow Data Studio

The e-commerce scrapers of the studio share the same columns, so products from several marketplaces land in one comparable table:

- [AliExpress Products Scraper & Price Tracker](https://apify.com/myth84/aliexpress-search-scraper): AliExpress prices, discounts, units sold and shipping for any keywords and delivery country, with price-drop alerts.
- [eBay Listings Scraper & Price Tracker](https://apify.com/myth84/ebay-search-scraper): eBay prices, condition, shipping and units sold on 9 marketplaces, with price monitoring.
- [Etsy Listings Scraper & Price Tracker](https://apify.com/myth84/etsy-search-scraper): Etsy prices, sale prices, ratings and review counts for any common search term, with price monitoring.

Did this scraper give you the data you needed? A rating on its Store page helps other people find it. For a bug or a missing field, open an issue in the **Issues** tab.

If this Actor saved you time, a short review helps others find it.

### Legal note

This Actor reads publicly available Walmart search and category pages without logging in and collects no personal data. You are responsible for your use of the data and for complying with Walmart's terms and the laws that apply to you.

Not affiliated with, endorsed or sponsored by Walmart. Walmart is a trademark of Walmart Inc.

# Changelog

This Actor's version history is a separate document: https://apify.com/myth84/walmart-search-scraper/changelog.md

# Actor input Schema

## `searchQueries` (type: `array`):

Enter one search per line, as you would type it in the Walmart search box, e.g. <code>wireless earbuds</code> or <code>coffee maker</code>. Each search gets its own results, up to the maximum number of products below. Default <code>wireless earbuds</code>: only for runs started without any keyword or URL (the form is prefilled with it); a run with URLs only searches just those URLs.

## `startUrls` (type: `array`):

Paste one or more Walmart URLs copied from your browser: search results, e.g. <code>https://www.walmart.com/search?q=coffee+maker</code>, or a category page (<code>https://www.walmart.com/browse/...</code>), on walmart.com or walmart.ca. Their filters are kept and the URL decides the site and the language; the sort order and price range below are applied on top only when you set them. walmart.com.mx is not supported. Default empty: keywords are enough.

## `site` (type: `string`):

Walmart site to search for keywords: walmart.com (United States, prices in USD) or walmart.ca (Canada, prices in CAD). Both were validated at build time. A URL in the field above always uses its own site. Default US: walmart.com in USD, the site of our daily check.

## `language` (type: `string`):

Language of the walmart.ca pages: English or French (titles, categories and badges in French, prices such as 39,99 $). walmart.com is in English only: French requires the CA site. Default en: English, the language of both sites.

## `maxResults` (type: `integer`):

Stop each search (keywords or URL) after this many unique products; you are never charged for more. A search result page holds about 50 products (30 on a category page) and Walmart shows about 13 pages per search, so about 500 unique products per search at most. Default 100: the top of a search in 2 to 4 pages; the form is prefilled with 20 for a quick first run.

## `sortBy` (type: `string`):

Order of the results. Best match (Walmart's default) and price low to high were validated at build time; price high to low, best sellers, highest rating and new arrivals use Walmart's public URL parameters and are not verified yet. Default best_match: Walmart's own order, the one a shopper sees first.

## `priceMin` (type: `number`):

Keep only products priced at least this amount, in the site currency, e.g. <code>20</code> for 20 USD on walmart.com (Walmart's own filter, which rounds its bounds: validated on walmart.com, not verified on walmart.ca nor on category pages). Leave empty for no minimum.

## `priceMax` (type: `number`):

Keep only products priced at most this amount, in the site currency, e.g. <code>50</code> for 50 USD on walmart.com (Walmart's own filter, which rounds its bounds: validated on walmart.com, not verified on walmart.ca nor on category pages); it must be at least the min price. Leave empty for no maximum.

## `includeSponsored` (type: `boolean`):

Walmart mixes about 10 sponsored products into each page of 50 (none when sorting by price). Keep them (they are flagged in the isSponsored column) or skip them; skipped products keep their place in searchRank. Default on: they are real offers shown on the page.

## `monitorPrices` (type: `boolean`):

Off (default): every product is returned and the four monitoring columns stay null. On: every product is compared with the previous run of the same search, by Walmart product id and site, and maxResults becomes the number of products compared per search.

## `onlyChanges` (type: `boolean`):

With price monitoring on: return and charge only the new products and the products whose price changed since the previous run; a run without any change succeeds with an empty dataset. Off (default): every compared product is returned with its changeType (new, price_changed, unchanged). Recommended for scheduled runs.

## `monitorStoreName` (type: `string`):

Name of the key-value store, in your account, that keeps the previous prices (one record per search), e.g. <code>earbuds-daily</code>. Runs sharing a name share the records; use one name per schedule when two schedules run the same search with different settings. Letters, digits and dashes only, at most 63 characters; upper case is lowered. Default walmart-price-monitor.

## `proxyConfiguration` (type: `object`):

Proxy used for the requests to Walmart. Do not set a proxy country: the site is chosen by its domain. You can also provide another Apify proxy group or your own proxy URLs; they are not needed. Default: Apify proxy, automatic datacenter group, the configuration validated for Walmart, its traffic included in the price.

## `maxPages` (type: `integer`):

Safety cap on the number of result pages read for one search. The scraper also stops at Walmart's last page, at maxResults, or when two consecutive pages bring no new product. Default 20: more than the about 13 pages Walmart shows for a search.

## `maxRequests` (type: `integer`):

Safety cap on the number of result pages fetched in one run, all searches and retries included. Default 500: about 25,000 products at 50 per page, far above a usual run.

## `delayMs` (type: `integer`):

Pause between two page requests of the same search, in milliseconds; 0 disables the pause. Default 2500: it avoided Walmart's rate limit (HTTP 429) at build time, 1,500 ms did not always.

## `debugStoreHtml` (type: `boolean`):

Debugging only: save every fetched page in the run's key-value store. Pages weigh 1 to 2 MB: slows the run down and uses storage. Default off: not needed to get the rows.

## `debugSendAccept` (type: `boolean`):

Debugging only: send a browser-like Accept header with every request. Off by default because the validated requests sent only Accept-Language; turn it on only to test Walmart's reaction.

## Actor input object example

```json
{
  "searchQueries": [
    "wireless earbuds"
  ],
  "startUrls": [],
  "site": "US",
  "language": "en",
  "maxResults": 20,
  "sortBy": "best_match",
  "includeSponsored": true,
  "monitorPrices": false,
  "onlyChanges": false,
  "monitorStoreName": "walmart-price-monitor",
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxPages": 20,
  "maxRequests": 500,
  "delayMs": 2500,
  "debugStoreHtml": false,
  "debugSendAccept": false
}
```

# Actor output Schema

## `products` (type: `string`):

All extracted products as dataset items, one flat row per product. Append ?format=csv or ?format=xlsx for spreadsheets. The Overview view is selected by default; Prices, Availability and Ranking views are also available.

## `runStats` (type: `string`):

Requests made, bytes transferred, blocked and rate-limited pages, products seen (sponsored and repeated ones counted), recommendation stacks skipped, products pushed and the estimated platform cost of the run.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQueries": [
        "wireless earbuds"
    ],
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("myth84/walmart-search-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchQueries": ["wireless earbuds"],
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("myth84/walmart-search-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "wireless earbuds"
  ],
  "maxResults": 20
}' |
apify call myth84/walmart-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,myth84/walmart-search-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/nnK33tih16qIehEf8/builds/e9gCN1KV3VsAeGQNj/openapi.json
