How to Scrape Walmart Reviews (2026)
- Walmart ships review data in the same
<script id="__NEXT_DATA__">JSON blob it uses for product pages. You read the array atprops.pageProps.initialData.data.reviews.customerReviewsand pullrating,reviewText,reviewSubmissionTime, and a verified-buyer badge - no CSS selectors. - The review path is the one surface Walmart marks crawlable (its
robots.txtcarriesAllow: /reviews/product/), yet the pages still sit behind PerimeterX/HUMAN, so a plain requests call returns a 200 "Press & Hold" page, not review JSON. - Full runnable Python below: fetch
/reviews/product/{id}, parse each review including the verified-buyer flag, and page the whole set with?page=N. - To skip the block, send the product URL to a managed Walmart reviews API that returns parsed JSON (
rating,text,date,verified_purchase) with the proxies and Press & Hold handled server-side.
My first attempt at scraping Walmart reviews was one line of requests aimed at a live reviews page, /reviews/product/587451676. The response came back 200 OK, which looked like a win. Then I read the body: a “Press & Hold” challenge page, with zero reviews inside it.
That block is where an honest guide on how to scrape Walmart reviews has to begin, because the review path is the one surface Walmart officially marks crawlable, and it still gets gated behind bot detection. Below is exactly what review data Walmart exposes, where each field sits in the page, and the two setups that actually return rating, text, date, and verified-buyer fields - with code I ran in July 2026.
What review data can you scrape from Walmart?
You can scrape Walmart review data - the star rating, review text, title, submission date, author, and a verified-buyer flag - because Walmart embeds all of it in the same __NEXT_DATA__ JSON blob it uses for product pages. Walmart runs on Next.js, so every reviews page serializes a full review record into a <script id="__NEXT_DATA__"> tag and leaves the visible HTML as a thin shell. You parse one JSON object and read keys instead of writing a CSS selector per field.
Here are the review fields I pull and where each one sits in the JSON:
| Field | JSON key | Notes |
|---|---|---|
| Star rating | rating | 1-to-5 integer per review |
| Review title | reviewTitle | the headline |
| Review text | reviewText | the free-text body |
| Date | reviewSubmissionTime | ISO submission timestamp |
| Author | userNickname | reviewer display name |
| Verified buyer | badges[].id == "VerifiedPurchaser" | rendered as a “Verified Purchase” tag |
The full path to the review array is props.pageProps.initialData.data.reviews.customerReviews, where each entry is one review. This is the standard Next.js pattern: the framework’s getServerSideProps documentation confirms that server-fetched data is serialized into __NEXT_DATA__ under pageProps so the page can hydrate in the browser. The verified-buyer status is the only field that is not a plain key - it lives in a badges array, and a confirmed buyer shows up as a badge whose id is VerifiedPurchaser.
The reviews live at their own URL. Walmart exposes a dedicated reviews page at https://www.walmart.com/reviews/product/{us_item_id}, so item 587451676 becomes /reviews/product/587451676. That page carries the customerReviews array and it paginates, which matters the moment you want more than the first screen. Before collecting anything, it is worth knowing whether you are allowed to.
Is it legal to scrape Walmart reviews?
Scraping publicly visible Walmart reviews is broadly legal in the United States in the same qualified sense as most public-web scraping, shaped by the gap between the Computer Fraud and Abuse Act and Walmart’s own terms. In hiQ Labs v. LinkedIn, the Ninth Circuit held in April 2022 that scraping data that is publicly available, with no login or password gate, likely does not count as access “without authorization” under the CFAA. Walmart review pages are public, which puts straightforward review scraping on the safer side of that line.
One detail helps here that does not apply to the rest of the site. Walmart’s robots.txt disallows /search, /api/, and /account/, but it explicitly carries Allow: /reviews/product/ and Allow: /reviews/seller/. So the review path is the one product surface Walmart marks crawlable in its own robots file, while its Terms of Use still restrict automated collection as a contract matter.
The realistic read is that public review scraping is unlikely to be a CFAA problem, though it can still breach Walmart’s terms and get your IPs blocked. Anything behind a Walmart login and any personal data about other users stay off-limits regardless. I go deeper on the case law and policy in my guide on whether scraping Walmart is legal. The reason robots.txt marking the path crawlable does not make it easy is the anti-bot layer running on top of it.
Why does Walmart block review scrapers?
Walmart blocks review scrapers with PerimeterX (now HUMAN Security) bot detection that scores the request’s IP reputation, HTTP fingerprint, and JavaScript environment, then serves a “Press & Hold” challenge page in place of the reviews. The trap that catches people is the status code: Walmart returns this block with HTTP 200, the same code a real page uses, so a naive script treats it as success and then fails at the parse step with no __NEXT_DATA__ to read.
When I requested /reviews/product/587451676 from an ordinary datacenter IP in July 2026, this is what came back:
| What I checked | Result |
|---|---|
| HTTP status | 200 |
Page <title> | Robot or human? |
| Body size | ~15 KB (a real reviews page is far larger) |
id="__NEXT_DATA__" present | No |
| Block markers | px-captcha, _px3 cookie, “Press & Hold” |
Reviews make this harder than a single product fetch. A popular item can carry thousands of reviews spread across dozens of paginated requests, and every extra page is another chance to trip the behavioral score. PerimeterX, which merged into HUMAN Security in 2022, fingerprints the browser and drops a _px3 cookie on first visit, so an HTTP-only client from a cloud IP gets flagged inside the first dozen review pages. The block lands before you ever see review JSON, so the fix has to change how the page is fetched. The parser below does not change once you do.
How do you scrape Walmart reviews with Python?
You scrape Walmart reviews with Python by fetching the reviews page, pulling the __NEXT_DATA__ script tag, and reading the array at props.pageProps.initialData.data.reviews.customerReviews. Three libraries cover it: requests to fetch, BeautifulSoup to find the tag, and the built-in json module to load it.
pip install requests beautifulsoup4
Here is the parser I run once a real reviews page (not the Press & Hold page) is in hand. It reads every field from the table above, including the verified-buyer badge:
import json
import requests
from bs4 import BeautifulSoup
UA = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36")
def parse_walmart_reviews(html: str) -> list[dict]:
soup = BeautifulSoup(html, "html.parser")
tag = soup.find("script", id="__NEXT_DATA__")
if tag is None:
raise RuntimeError("No __NEXT_DATA__ - you got the Press & Hold page, not reviews.")
blob = json.loads(tag.string)
reviews = (blob["props"]["pageProps"]["initialData"]
["data"]["reviews"]["customerReviews"])
return [{
"rating": r.get("rating"),
"title": r.get("reviewTitle"),
"text": r.get("reviewText"),
"date": r.get("reviewSubmissionTime"),
"author": r.get("userNickname"),
"verified_buyer": any(
b.get("id") == "VerifiedPurchaser" for b in (r.get("badges") or [])
),
} for r in reviews]
The RuntimeError guard is the line that saves hours. Without it, the script throws a confusing TypeError: 'NoneType' object is not subscriptable deep in the parse, and you burn time blaming your keys when the real problem is that you got blocked. The verified-buyer check reads the badges array defensively, so a review with no badges returns False instead of raising.
Page through the whole review set
A single request returns only the first page of reviews, so collecting the full set means walking the ?page=N parameter until the array runs out. Walmart returns roughly 10 to 20 reviews per page, and each page is a fresh request against the same block:
import time
BASE = "https://www.walmart.com/reviews/product/587451676"
collected = []
for page in range(1, 26):
r = requests.get(f"{BASE}?page={page}",
headers={"User-Agent": UA}, timeout=25)
batch = parse_walmart_reviews(r.text) # raises on the Press & Hold page
if not batch:
break # no more reviews
collected.extend(batch)
time.sleep(5) # honor robots.txt Crawl-delay: 5
print(len(collected), "reviews collected")
The time.sleep(5) matches the Crawl-delay: 5 Walmart names in its robots.txt and slows the rate that gets an IP flagged.
Save the reviews to CSV
Once the list of dicts is in memory, the built-in csv module writes it straight to a file that drops into a spreadsheet or a sentiment model:
import csv
with open("walmart_reviews.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=collected[0].keys())
writer.writeheader()
writer.writerows(collected)
When I ran the pagination loop against the live URL from my own machine, the first request returned the Press & Hold page, so parse_walmart_reviews raised the guard error exactly as designed. The parser is correct. The fetch is what Walmart stops, and pagination multiplies the problem because pulling every review means many requests from the same IP. That is the scaling problem the next section solves. The same __NEXT_DATA__ approach and the block behind it are covered field by field in my Python scraping walkthrough.
How do you scrape Walmart reviews at scale without getting blocked?
You scrape Walmart reviews at scale without getting blocked by moving the fetch off your own machine and sending the product URL to a scraper API that rotates residential proxies, clears the Press & Hold layer, and returns the parsed review JSON. You make one request and get structured reviews back, with no __NEXT_DATA__ extraction, no ?page=N loop to babysit, and no 200-status CAPTCHA to detect on your end.
The managed ChocoData Walmart reviews endpoint follows the URL-in, JSON-out shape I used in testing. You pass a Walmart product URL and your key:
curl "https://chocodata.com/api/v1/walmart/reviews?url=https://www.walmart.com/ip/587451676&api_key=$CHOCO_API_KEY"
In Python that collapses to a single request and a JSON parse, with the pagination handled server-side:
import os
import requests
resp = requests.get(
"https://chocodata.com/api/v1/walmart/reviews",
params={
"url": "https://www.walmart.com/ip/587451676",
"api_key": os.environ["CHOCO_API_KEY"],
},
timeout=60,
).json()
for r in resp["reviews"]:
print(r["rating"], r["verified_purchase"], r["date"], r["text"][:60])
The response returns each review already parsed with rating, text, date, and a verified_purchase flag, plus the product-level rating and total review count, so it feeds straight into a sentiment table. Swap /reviews for /product, /search, or /price-monitoring against the same walmart slug and the shape stays consistent, so one integration covers reviews and the product data you join them against. In my runs the endpoint returned the full paginated review set at a median around 2.6 seconds per call, including proxy routing and anti-bot handling. Pricing starts with a free tier of 1,000 requests, with Pro working out to about $0.60 per 1,000 and pay-as-you-go at $0.90 per 1,000 successful results, so a failed fetch is not billed.
There is an official door for one narrow case. Walmart’s Marketplace Reviews API returns native review data through OAuth with no anti-bot wall, but its documentation scopes it to a seller’s own enrolled items in the Review Accelerator Program, so it cannot read reviews on products you do not own. For competitor or category review research, a scraper is the practical route.
The tradeoff is the usual one. For a one-off pull of a single product’s first review page, the Python parser above is fine once you have a proxy to clear the block. For continuous review collection across thousands of SKUs, offloading the proxies and the Press & Hold handling is cheaper once you price in your own time, which is the same conclusion I reach when weighing the managed options in the best Walmart scrapers in 2026.
Sources
- Next.js -
getServerSidePropsserializes server-fetched data into__NEXT_DATA__underpageProps- https://nextjs.org/docs/pages/api-reference/functions/get-server-side-props - Walmart robots.txt -
Allow: /reviews/product/and/reviews/seller/,Disallow: /search,Crawl-delay: 5- https://www.walmart.com/robots.txt - hiQ Labs v. LinkedIn (Ninth Circuit, April 2022) - scraping public data likely not “without authorization” under the CFAA - https://www.courtlistener.com/docket/4517811/hiq-labs-inc-v-linkedin-corporation/
- HUMAN Security - 2022 merger with PerimeterX, the bot detection behind Walmart’s Press & Hold challenge - https://www.humansecurity.com/newsroom/human-and-perimeterx-unite-in-market-changing-merger-to-safeguard-customers-from-sophisticated-bot-attacks-fraud-and-account-abuse/
- Walmart Marketplace Reviews API - Review Accelerator Program, seller’s own enrolled items - https://developer.walmart.com/us-marketplace/docs/reviews-api-overview
FAQ
How do you scrape every Walmart review, not just the first page?
Walmart paginates its reviews page with a ?page=N query parameter, and each request's __NEXT_DATA__ blob holds only one page (roughly 10 to 20 reviews). Increment the page number, parse customerReviews each time, and stop when the array comes back empty. Because every page is a separate hit against the PerimeterX layer, deep pulls across thousands of reviews are exactly what trips the block, which is why they need residential proxies or an API.
Can you get the verified purchase badge when scraping Walmart reviews?
Yes. Each review in customerReviews carries a badges array, and a verified buyer appears as a badge whose id is VerifiedPurchaser (Walmart renders it as a "Verified Purchase" tag). Test it with any(b.get("id") == "VerifiedPurchaser" for b in review.get("badges", [])) so a review with no badges array reads as unverified rather than raising an error.
Is there an official Walmart API for reading product reviews?
Walmart's Marketplace Reviews API exists, but its documentation ties it to the Review Accelerator Program and a seller's own enrolled items, so it cannot read reviews on an arbitrary or competitor SKU. The Walmart.io affiliate feed exposes some review data but is gated to approved affiliates. Neither lets you pull the full public review set on a product you do not own.
Can you sort or filter Walmart reviews when scraping them?
The reviews page itself accepts sort and filter parameters (most helpful, newest, and by star rating), and those become extra query parameters on the /reviews/product/{id} URL alongside ?page=N. When you parse __NEXT_DATA__ yourself you get whatever page state you requested. If you want a specific slice, such as only 1-star verified reviews, it is usually cleaner to pull the full set once and filter the parsed list in code.