# Walmart Category Scraper: Prices, Stock & Ratings (`farzanahmed/walmart-products`) Actor

Scrape walmart.com category pages into clean product rows: title, price, stock, rating, review count, sponsored flag, position and link. For price tracking and category ranking. Blocked pages and repeated products aren't charged. Not affiliated with Walmart.

- **URL**: https://apify.com/farzanahmed/walmart-products.md
- **Developed by:** [Farzan Ahmed](https://apify.com/farzanahmed) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 listing rows

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 Category Scraper turns walmart.com **category pages** into clean listing rows: each product's title, price,
stock status, rating, review count, sponsored flag, position on the page and link. Use it to track prices across a
category, watch which products rank where, or build an assortment list, then download the rows as JSON, CSV or Excel,
or read them through the Apify API.

This actor is not affiliated with, endorsed by or sponsored by Walmart Inc.

### What does Walmart Category Scraper do?

Give it one or more walmart.com category pages (URLs starting `https://www.walmart.com/browse/`). It reads each page,
follows the category's next pages up to your page limit, and saves one row per product tile.

- **Category pages only.** Search pages (`/search`), product pages (`/ip/`) and other sites are rejected before any
  request is made, with a message naming the path.
- **US walmart.com.** It runs through Apify's residential proxy in the US by default. Prices and stock on walmart.com
  depend on the shopper's location, so the values you get may differ from what you see in your own browser.
- **Sponsored rows are left out by default.** Turn on *Include sponsored rows* to keep them, marked
  `sponsored: true`.
- **Each product once per run, even across categories.** A product already saved is dropped, and not charged, when
  it shows up again on a later page or in another of your categories; its row keeps the first position it was seen
  at. (A rare platform migration can still repeat a few rows; see the limits below.)

### What data can it extract?

One row per product, with these fields:

| Field | Example | Notes |
|---|---|---|
| `id` | `"16044016485"` | Walmart's item id. A product appears once per run (see the limits below) |
| `title` | `"Example 50 in Class 4K Smart TV"` | As listed |
| `price` | `158.0` | The single current price. Empty (`null`) when the page shows none |
| `currency` | `"USD"` | Empty exactly when `price` is |
| `availability` | `"in_stock"` | `in_stock`, `out_of_stock` or `unknown` |
| `rating` | `4.4` | Average stars, 0 to 5. Empty for items without reviews |
| `reviewCount` | `1873` | Number of reviews |
| `sellerName` | `"Walmart.com"` | Only with *Include seller name*; empty otherwise |
| `sponsored` | `false` | `true` for an ad tile |
| `url` | `"https://www.walmart.com/ip/example/16044016485"` | The product page, without tracking parameters |
| `position` | `7` | Position of the tile on its category page |
| `sourceUrl` | `"https://www.walmart.com/browse/...?page=2"` | The category page the row came from |
| `scrapedAt` | `"2026-10-09T12:00:00Z"` | When the row was read (UTC) |

**Not collected:** product descriptions or specifications, images, review texts or reviewer names, seller addresses
or contact details, variants, delivery promises, or anything behind a login or a cart.

### How to use it

1. Open a category on walmart.com in your browser, for example *Electronics > TVs > All TVs*, and copy its URL from
   the address bar. It must start with `https://www.walmart.com/browse/`: department pages (`/cp/...`) aren't
   accepted, so open a subcategory until the address shows `/browse/`.
2. Paste it into *Category URLs*. Add more categories if you like, up to 100.
3. Set *Max rows*, the most rows you want (and pay for) across all categories, and *Max pages per URL*.
4. Click **Start**. When the run finishes, open the **Output** tab to view the rows or download them.

To track prices over time, save the input as a task and run it on a schedule; each run gives a fresh snapshot with
its own `scrapedAt` time.

### Input

| Input | Default | Notes |
|---|---|---|
| Category URLs | required (the form is prefilled with a TV category) | 1 to 100 walmart.com category pages. A `page=` in a URL is the first page read |
| Max rows | 100 | Rows saved (and charged) across all URLs, 1 to 10,000 |
| Max pages per URL | 10 | 1 to 50 |
| Include seller name | off | |
| Include sponsored rows | off | |
| Proxy | Apify residential, US | With datacenter proxy or no proxy, Walmart will likely block most pages |

### How much does it cost?

You pay per row saved, plus a tiny fee per run; Apify's platform usage (compute, proxy) is included in that price. The
price per 1,000 rows depends on your Apify Store discount tier, which follows your Apify plan:

| Apify plan | Price per 1,000 rows |
|---|---|
| Free | $4.50 |
| Starter | $3.50 |
| Scale | $2.75 |
| Business | $2.00 |

- **Per run:** a start fee of $0.00005 (5 cents per 1,000 runs). Memory is capped at 1 GB, so it is charged once.
- **Never charged:** blocked or empty pages, repeated products (except in the rare migration case below), sponsored
  rows that were left out, and anything beyond *Max rows*.
- **Example:** 1,000 rows on the Starter plan cost $3.50 plus $0.00005.
- **Free plan:** Apify's free plan includes $5 of usage a month, which at $4.50 per 1,000 is about 1,100 rows.
- **Your limit is respected.** If you set a maximum cost per run, the actor stops saving rows when it is reached.

### Limits and how blocks are handled

- **Blocked pages are reported, not charged.** If Walmart answers a page with a block or a bot check, the actor tries
  that page at most 4 times, each on a fresh IP, after a short pause. It never solves or interacts with a challenge.
  Pages it gave up on are listed in the run's `BLOCKED_URLS` record, and the `RUN_SUMMARY` record counts pages,
  attempts and blocks. When Walmart redirects a page away from the category pages, the log names where it was sent
  (the host and path only, never the query string or fragment), and `RUN_SUMMARY` counts those destinations (the
  first 20 distinct ones each by name, any later new one under `(other)`).
- **Partial page changes are flagged.** If Walmart changes its pages so that some products can't be read, shows
  product tiles of a kind the actor doesn't know or in a second list, or no longer gives a usable count of the
  category's pages (none, or one lower than the page's own number), the run still succeeds with the rows it could
  read. Its status message then says "layout drift", the log names each affected page, and `RUN_SUMMARY` counts the
  products and tiles it couldn't read and the pages without a usable page count. Without one, the actor doesn't guess
  further pages of that category.
- **Repeated products are dropped, not charged.** Walmart sometimes shows a product again on a later page of the same
  category, and categories overlap. The actor pushes each product once per run, across all your category URLs, and
  `RUN_SUMMARY` counts the repeats by page number, beside the rows each page number offered.
- **The run stops early when Walmart refuses it.** If most recent attempts were blocked, the actor stops instead of
  spending more. A run that could read no page at all ends as failed.
- **Page depth.** Walmart reports up to about 25 pages for a large category, but pages near or past that number can
  come back empty. The actor stops a category at its first empty page.
- **Polite by design.** At most 3 requests at a time and 20 a minute, which you can't raise.
- **Runs survive a server move.** If Apify moves a run to another server, the actor saves its progress in the run's
  `CRAWL_STATE` record and carries on from it. It is built not to save or charge a row twice, but an interruption at
  the wrong moment, or a failed save just before it, can still push and charge some rows again (usually at most one
  page's). If the restart doesn't come, the run fails and can be resurrected to continue.

### What it doesn't do

- **No keyword search.** It reads category pages only; walmart.com's `robots.txt` disallows `/search`.
- **No ZIP code or store choice.** Rows reflect what a US visitor on the proxy's location sees.
- **US only.** Not walmart.ca or other Walmart sites.
- **Listing fields only.** No product-page details such as specifications, variants, UPCs, review texts or seller
  offers, and no was-price, brand or image fields.

### FAQ

#### Why are some prices different from what I see on walmart.com?

Walmart shows prices and stock for the shopper's location and store. The actor runs from a US residential IP chosen by
the proxy, so its location is not yours.

#### Why did I get fewer rows than *Max rows*?

The category may have fewer products than that, its later pages may be empty, sponsored rows are left out by default,
and repeats are dropped. Pages Walmart blocked are listed in `BLOCKED_URLS`; `RUN_SUMMARY` gives the counts.

#### Can I use it without the residential proxy?

You can, but Walmart will likely block most pages from datacenter IPs or no proxy, and blocked pages give no rows.

#### Can I use it through the API or with other tools?

Yes. Like any Apify actor, you can start it and read its dataset through the Apify API and client libraries, run it
on a schedule, and connect it to Apify's integrations, such as webhooks, Make, Zapier or Google Sheets.

#### Is it legal to scrape Walmart?

The actor collects only what a logged-out visitor can see on public category pages, and no personal data unless you
turn on *Include seller name*. Whether your use is lawful depends on what you do with the data and where you are; see
below.

### Your responsibility

You are responsible for how you use the data you collect, including compliance with walmart.com's terms and the laws
that apply to you. The data comes as it was shown on walmart.com at the time of the run, without any guarantee that it
is accurate, complete or up to date. Walmart is a trademark of Walmart Inc.; this actor is independent of it.

# Actor input Schema

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

walmart.com category pages: open a category in your browser and copy its URL (it must start with https://www.walmart.com/browse/; department pages under /cp/ aren't accepted). Search pages, product pages and other sites are rejected before any request. A page= parameter in a URL is the first page read.

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

The most rows saved across all category URLs. You pay per row saved; blocked pages, repeated products and left-out sponsored rows aren't charged.

## `maxPagesPerStartUrl` (type: `integer`):

How many pages of each category to read, following its next page. Large categories have up to about 25 pages; the actor stops a category at its first empty page.

## `includeSeller` (type: `boolean`):

Fill sellerName where the tile shows a seller; null otherwise. Sellers are usually businesses, but a few trade under a person's name, so this is off by default.

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

Also save (and charge) sponsored ad tiles, marked sponsored: true. Off by default.

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

Apify residential proxy in the US by default, included in the price. With datacenter proxy or no proxy, Walmart will likely block most pages.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.walmart.com/browse/electronics/all-tvs/3944_1060825_447913"
    }
  ],
  "maxItems": 100,
  "maxPagesPerStartUrl": 10,
  "includeSeller": false,
  "includeSponsored": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `results` (type: `string`):

One row per product: item id, title, price, currency, stock, rating, review count, seller (only with Include seller name), sponsored flag, product link, position, source page and read time.

## `runSummary` (type: `string`):

Counts for the run: pages read, attempts, blocks by reason, rows pushed and charged, dropped sponsored rows and duplicates, and the layout-drift signals the actor counts. Not written when the input is invalid, a saved crawl state can't be continued, or a migrated run doesn't restart.

## `blockedUrls` (type: `string`):

Category pages the actor gave up on: blocked or failed after its attempts, or never attempted after a stop that ended the crawl. No rows from them were charged. Not written when the input is invalid, a saved crawl state can't be continued, or a migrated run doesn't restart.

# 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 = {
    "startUrls": [
        {
            "url": "https://www.walmart.com/browse/electronics/all-tvs/3944_1060825_447913"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("farzanahmed/walmart-products").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 = {
    "startUrls": [{ "url": "https://www.walmart.com/browse/electronics/all-tvs/3944_1060825_447913" }],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("farzanahmed/walmart-products").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 '{
  "startUrls": [
    {
      "url": "https://www.walmart.com/browse/electronics/all-tvs/3944_1060825_447913"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call farzanahmed/walmart-products --silent --output-dataset

```

## MCP server setup

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

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/9aiJ8g3cOLCXA6To8/builds/4CC4rVSTizFtRaWB6/openapi.json
