# Walmart Scraper - Products, Prices, Sellers & Reviews (`abotapi/walmart-scraper`) Actor

Scrape Walmart.com by keyword, URL, or item ID. Extract prices, was-prices, sellers, marketplace offers, stock, ratings, specs, images, and reviews. Track NEW, UPDATED, REAPPEARED, and EXPIRED items with resume and MCP export.

- **URL**: https://apify.com/abotapi/walmart-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.90 / 1,000 product records

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Walmart Scraper - Products, Prices, Sellers & Reviews

Scrape walmart.com, the largest US retailer and the #5 marketplace worldwide:
search or browse the catalog, or look up individual products, and get prices,
was-prices, every seller offer, stock, ratings, specifications, images and the
customer reviews the product page publishes.

### Why This Scraper?

- **Reviews and offers are free.** Every walmart.com product page ships its
  reviews and its seller offers in the same document as the product itself, so
  this actor returns them in the same request. Other Walmart scrapers on the
  Store bill a separate per-review event and a separate per-offer event; here
  they are part of the one detail record.
- **One request, ~45 complete rows.** A search page carries its whole result
  grid as structured data, so a listing-level pull returns full product records
  (price, was-price, rating, review count, seller, stock, badges, category)
  with no per-product request at all.
- **Filters that are actually true.** The storefront's own sort and filter
  parameters are sent with the request, so filtering narrows results before
  they count against your item cap. Walmart injects sponsored tiles into the
  grid regardless of the active filters, so `excludeSponsored` re-checks every
  row and drops the ads.
- **Monitoring built in.** Label every record NEW / UPDATED / REAPPEARED /
  EXPIRED across runs, resume an interrupted crawl, and export through MCP
  connectors.
- **Structured failures.** A run the storefront refuses fails loudly with a
  clear message instead of returning an empty dataset that looks like a search
  with no matches.

### Data You Get

**Search mode** walks each keyword and each pasted listing link page by page and
returns one record per product: item id, title, brand, URL, image, price,
was-price, price range, currency, rating, review count, seller name / id / type,
availability, fulfillment text, badges, sponsored flag, variant count, category
path, and which page and slot the product was found in.

**Detail enrichment** (`fetchDetails`) adds, from the product's own page: model,
UPC, manufacturer part number, full description, specifications, product
highlights, every image, all seller offers with condition and fulfillment,
return policy, warranty, rating histogram, recommended percentage, review
aspects, and the price scope (the store and ZIP the prices were quoted for).

**Reviews** (`includeReviews`) add the reviews the product page itself
publishes: rating, title, text, date, the reviewer's public display name,
verified-purchase marker, helpful votes and photo count. These come from the
same page as the detail data, so they cost no extra request and no extra
charge. The product page publishes up to 10 reviews, which is this actor's
ceiling; the full review count and star breakdown are returned regardless.

**Product mode** reads product links or bare item ids and returns one fully
enriched record per product.

Incremental runs add `changeType`, `changedFields`, `firstSeenAt` and
`lastSeenAt` to every record.

### How to Use

1. Keep the default **Search keywords or pasted listing links** mode, type one
   or more keywords, and run.
2. Want a whole department? Paste browse or category links, for example
   `https://www.walmart.com/browse/electronics/3944`, into **Storefront links**.
   Filters you already selected in a link you copied are kept and this run's
   own filters are added on top.
3. Narrow with the storefront's own filters: sort, brands, sold-by, condition,
   deals, minimum rating, availability and price bounds. Turn on **Hide
   sponsored results** for a clean assortment view.
4. Need full detail? Turn on **Fetch product details**. Need reviews too? Turn
   on **Include customer reviews**; it uses the same page, so it adds no extra
   charge.
5. Need individual products? Switch to **Look up specific products** and list
   product links or item ids.
6. Monitoring over time? Turn on **Incremental runs** and reuse the same input;
   the actor tracks what changed between runs.
7. Optional: connect an MCP connector to push records into Notion or another
   destination after each run.

### Input Parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| mode | select | search | Search keywords / pasted links, or look up specific products |
| queries | array | laptop | Search mode: keywords, each walked separately |
| searchUrls | array | empty | Search mode: walmart.com search, browse, shop or category links |
| productInputs | array | empty | Product mode: product links or bare item ids |
| sortBy | select | best\_match | Storefront sort: best match, price low/high, best seller, highly rated, new |
| brands | array | empty | Keep only these brands, spelled as the storefront spells them |
| retailerType | select | any | Walmart, Pro Sellers, or marketplace sellers fulfilled by Walmart |
| condition | select | any | New, restored or pre-owned |
| specialOffer | select | any | Reduced price, clearance or rollback |
| minRating | select | any | 4 stars and up, or 3 stars and up |
| inStockOnly | boolean | false | Hide items the storefront cannot sell right now |
| excludeSponsored | boolean | false | Drop advertising tiles from the results |
| minPrice | integer | empty | Only keep products at or above this price |
| maxPrice | integer | empty | Only keep products at or below this price |
| fetchDetails | boolean | false | Read each product's own page (per-record surcharge) |
| includeReviews | boolean | false | Add the reviews the product page publishes (no extra charge) |
| maxReviews | integer | 10 | Reviews kept per product, up to the 10 the page publishes |
| maxItems | integer | 20 | Stop after this many records (0 = unlimited) |
| maxPages | integer | 0 | Max result pages per keyword or link (0 = every page offered) |
| incrementalMode | boolean | false | Track NEW / UPDATED / REAPPEARED / EXPIRED between runs |
| emitUnchanged | boolean | false | Also return (and bill) unchanged records |
| emitExpired | boolean | false | Also return (and bill) records gone from a complete scan |
| stateKey | string | empty | Name a monitoring campaign explicitly |
| resumeFromRunId | string | empty | Skip records already collected by a run or dataset |
| mcpConnectors | array | empty | MCP connector export |
| notionParentPageUrl | string | empty | Notion parent page for the Notion connector |
| maxNotifyListings | integer | 50 | Cap per connector per run |
| proxy | object | proxy on | Apify Proxy; a US residential exit is required |

### Output Example

```json
{
  "kind": "product",
  "itemId": "000000000000",
  "url": "https://www.walmart.com/ip/Sample-Product-Name/000000000000",
  "title": "Sample Product Name 15 Laptop",
  "brand": "Sample Brand",
  "model": "SAMPLE-MODEL-01",
  "upc": "0000000000000",
  "price": 199.0,
  "wasPrice": 249.0,
  "currency": "USD",
  "rating": 4.5,
  "reviewCount": 123,
  "ratingHistogram": {"5": 80, "4": 25, "3": 10, "2": 5, "1": 3},
  "recommendedPercentage": 90,
  "sellerName": "Sample Seller",
  "sellerType": "INTERNAL",
  "offerCount": 2,
  "offers": [
    {"sellerName": "Sample Seller", "price": 199.0, "condition": "New",
     "fulfilledByWalmart": false, "isBuyBoxWinner": true},
    {"sellerName": "Sample Reseller", "price": 209.5, "condition": "New",
     "fulfilledByWalmart": true, "isBuyBoxWinner": false}
  ],
  "availabilityStatus": "IN_STOCK",
  "inStock": true,
  "condition": "New",
  "categoryPath": "Electronics / Sample Category / Sample Subcategory",
  "badges": ["Sample badge"],
  "sponsored": false,
  "fulfillmentOptions": ["DELIVERY", "PICKUP", "SHIPPING"],
  "returnPolicy": {"returnable": true, "freeReturns": true, "windowDays": 90,
                   "text": "Free 90-day returns"},
  "specifications": [{"name": "Sample specification", "value": "Sample value"}],
  "reviews": [
    {"reviewId": "000000000", "rating": 5, "title": "Sample review title",
     "text": "Sample review text written for this example.",
     "submittedAt": "1/1/2026", "authorNickname": "SampleShopper",
     "verifiedPurchase": true, "helpfulVotes": 3}
  ],
  "priceScope": {"postalCode": "00000", "city": "Sample City", "state": "ST",
                 "storeId": "00000"},
  "searchQuery": "sample keyword",
  "resultPage": 1,
  "resultPosition": 4,
  "changeType": "NEW",
  "firstSeenAt": "2026-09-04T02:00:00+00:00",
  "lastSeenAt": "2026-09-04T02:00:00+00:00"
}
```

Every value above is illustrative and fictional, invented for this example, not
a real walmart.com product, price, seller or customer. Records returned by a
real run carry what walmart.com prints publicly beside each product; they never
carry an email address, a phone number or a profile link, because the product
page does not publish those.

### Send results into your apps (MCP connectors)

Optionally pipe results into Notion, Linear, Airtable or Apify via MCP connectors, in the
**Integrations** section of the input. Each connector receives a condensed summary per
product; the complete record always stays in the dataset, so nothing is lost if you leave
this off.

- `mcpConnectors` - the MCP connectors to export this run's products into (Notion, Linear,
  Airtable, Apify). Leave it empty and nothing is exported.
- `notionParentPageUrl` - Notion connector only: the page under which one child page per
  product is created. Required when `mcpConnectors` includes Notion, ignored otherwise.
- `maxNotifyListings` - how many products are exported to each connector in one run,
  default 50. This caps the export only; it never changes what the dataset returns.

Export runs after the dataset is complete and is best-effort: if a connector is unreachable
the run still succeeds with a warning, and your products are still in the dataset.

### Monitoring the same search over time

Turn on `incrementalMode` and schedule the actor. The first run returns everything as
`changeType: NEW`; later runs return only what is new, changed or back in stock, each
with `changedFields`, `firstSeenAt` and `lastSeenAt`. Set `emitUnchanged` or `emitExpired`
if you also want those rows (both bill extra rows). A product's position in the result
grid is deliberately excluded from change detection, because Walmart re-ranks its grid on
every request. Review text IS part of change detection, so leave `includeReviews` off when
you only want to track prices and stock.

`resumeFromRunId` is a different feature: it continues one specific interrupted crawl by
skipping records that run already collected.

### Plan Requirement & Notes

- Pay per event: one unit per returned record, plus an Actor Start event, plus a
  detail-enrichment unit for each record actually enriched from its product page.
  A record whose product page could not be read still ships, uncharged. In
  incremental mode a suppressed unchanged record is neither returned nor charged.
- **A US residential Apify Proxy exit is required.** walmart.com serves its home
  page to any connection but refuses search and product pages on datacenter
  exits. No browser runs and no challenge solver is used: the actor keeps one
  warm session over one sticky exit for the whole run, which is what the
  storefront accepts.
- The actor reads walmart.com, the US storefront, and prices are quoted for the
  store the session resolves to. Every record carries that store and ZIP in
  `priceScope` so a price is never ambiguous.
- Reviews are limited to the 10 the product page publishes. The complete review
  count, the star histogram and the recommended percentage are always returned.

# Actor input Schema

## `mode` (type: `string`):

Choose 'search' to run keyword searches and walk pasted search, browse or category links. Choose 'products' to look up specific products by their walmart.com link or item id.

## `queries` (type: `array`):

One or more keywords to search on walmart.com, for example 'laptop' or 'coffee maker'. Each keyword is searched separately and walked page by page.

## `searchUrls` (type: `array`):

Paste walmart.com listing links to walk, for example https://www.walmart.com/browse/electronics/3944 or a search link you copied from your browser. Filters you had already selected in that link are kept, and this run's own filters are added on top. Product links do not belong here; use Product mode for those.

## `productInputs` (type: `array`):

Only used when mode = products. Mix freely: full product links such as https://www.walmart.com/ip/Apple-MacBook-Air/19699754154 or bare item ids such as 19699754154.

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

The storefront's own sort order for search results.

## `brands` (type: `array`):

Optional. Keep only products from these brands, exactly as the storefront spells them (for example 'Apple', 'HP', 'Lenovo'). Several brands are combined as 'any of these'.

## `retailerType` (type: `string`):

Optional. Narrow to who sells the item: Walmart itself, Pro Sellers, or marketplace sellers whose orders Walmart fulfills.

## `condition` (type: `string`):

Optional. Narrow to new, restored or pre-owned items.

## `specialOffer` (type: `string`):

Optional. Narrow to items currently carrying a deal flag.

## `minRating` (type: `string`):

Optional. The storefront publishes two rating buckets and this filter uses them; each returned row is also checked against the number, so a row below the bucket never reaches the dataset.

## `inStockOnly` (type: `boolean`):

Optional. Hide items the storefront currently cannot sell or deliver.

## `excludeSponsored` (type: `boolean`):

Optional. Drop advertising tiles from the results. The storefront injects sponsored products into the grid regardless of the filters above, so turn this on when you want a clean, filter-true assortment view.

## `minPrice` (type: `integer`):

Optional. Only keep products priced at or above this amount.

## `maxPrice` (type: `integer`):

Optional. Only keep products priced at or below this amount.

## `fetchDetails` (type: `boolean`):

Read each product's own page to add brand, model, UPC, full description, specifications, all images, every seller offer, the return policy and the rating breakdown. Charged once per record enriched. Leave off for a fast, cheap listing-level pull.

## `includeReviews` (type: `boolean`):

Add the customer reviews the product page itself publishes, each with the reviewer's public display name, rating, title, text, date and verified-purchase marker. This reads the same product page as Fetch product details, so it costs no extra request and no extra charge; it does turn detail enrichment on. Reviews take part in change detection, so leave this off for price-only monitoring.

## `maxReviews` (type: `integer`):

How many of the product page's own reviews to keep per product, newest-first as the storefront orders them. The product page publishes up to 10, which is the ceiling here; the full rating breakdown and review counts are returned regardless.

## `maxItems` (type: `integer`):

Maximum number of records to return across the whole run. Use 0 for unlimited.

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

Maximum result pages walked per keyword or pasted link. 0 = walk every page the storefront offers for that search; the run then stops at Max products, at the storefront's own last page, or when a page returns nothing new.

## `resumeFromRunId` (type: `string`):

Paste a previous run ID or dataset ID to continue a large crawl without returning or charging for products already collected there. For recurring monitoring of the same search, use Incremental mode below instead.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring. The first run returns every matching product as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED products. State is kept separately for each keyword, link, filter and detail setup; use State key when you want to name or deliberately share a monitoring campaign.

## `stateKey` (type: `string`):

Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently configured runs. Leave empty to derive a key automatically from this run's search and filter setup.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return products that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return products that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search, never when Max products capped it or when Resume was used. This returns, and bills, extra synthetic rows.

## `proxy` (type: `object`):

The storefront answers search and product pages only on US residential connections. A datacenter exit is refused, so leave this on the default unless you are supplying your own US residential exits.

## `mcpConnectors` (type: `array`):

Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write or digest. Leave empty to skip; this never changes the dataset output. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL or id of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "mode": "search",
  "queries": [
    "laptop"
  ],
  "searchUrls": [
    "https://www.walmart.com/browse/electronics/3944"
  ],
  "productInputs": [
    "https://www.walmart.com/ip/19699754154"
  ],
  "sortBy": "best_match",
  "retailerType": "any",
  "condition": "any",
  "specialOffer": "any",
  "minRating": "any",
  "inStockOnly": false,
  "excludeSponsored": false,
  "fetchDetails": false,
  "includeReviews": false,
  "maxReviews": 10,
  "maxItems": 20,
  "maxPages": 0,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  },
  "maxNotifyListings": 50
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# 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 = {
    "mode": "search",
    "queries": [
        "laptop"
    ],
    "searchUrls": [
        "https://www.walmart.com/browse/electronics/3944"
    ],
    "productInputs": [
        "https://www.walmart.com/ip/19699754154"
    ],
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/walmart-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 = {
    "mode": "search",
    "queries": ["laptop"],
    "searchUrls": ["https://www.walmart.com/browse/electronics/3944"],
    "productInputs": ["https://www.walmart.com/ip/19699754154"],
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/walmart-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 '{
  "mode": "search",
  "queries": [
    "laptop"
  ],
  "searchUrls": [
    "https://www.walmart.com/browse/electronics/3944"
  ],
  "productInputs": [
    "https://www.walmart.com/ip/19699754154"
  ],
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call abotapi/walmart-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/walmart-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/gXMsqLx6bNLqCR0BK/builds/RapMsecgX8rOsPJ10/openapi.json
