Scrape Walmart.com (US) product and price data by search term, product URL, or item ID — title, current price, was/strike-through price, in-stock status, rating, review count, and Walmart-vs-marketplace seller type. Export to JSON or CSV. Use as a Walmart price API for repricing and monitoring.
Fixes two defects that blocked the first publish, both confirmed on
real cloud runs (RESIDENTIAL/US proxy) before and after the fix:
Proxy default was datacenter, and Walmart hard-blocks it. Every
request hit block-interstitial and exhausted retries (cloud run
XxG3uTzWtds0ZlQSt). proxyConfiguration now defaults to
apifyProxyGroups: ["RESIDENTIAL"] + apifyProxyCountry: "US" in
both input_schema.json and ActorInput.
price_current/price_was were always null. Root cause:
parser.py assumed one wire shape (priceInfo.currentPrice.price)
for both PDP and search-result payloads. Live cloud recon (runs
lLBpstp7wmdjeYcOJ and Fk29gWbreiH6e3TvS, raw payload dumped via
the new fail-loud guard) confirmed the PDP shape was already correct,
but search-result items carry a plain top-level numeric price
field instead, with priceInfo reduced to a display-string bag
(wasPrice: "" or a dollar string, not a nested price object).
parser.py now tries the PDP shape first, falls back to the
search-result shape, and parses wasPrice dollar-strings. Also
hardened _derive_availability to fall back to isOutOfStock /
availabilityStatusV2.value for search-result items, which don't
carry the PDP's availabilityStatus string.
Bonus fix found during recon: productIds validation rejected
legitimate 11-digit Walmart item IDs (e.g. 15949610846, "Nintendo
Switch 2 System") — widened ITEM_ID_RE from 8-10 to 8-11 digits.
New: a fail-loud guard (main._guard_against_null_prices) now
fails the run and dumps up to 3 raw pre-parse payloads to
KVS[NULL_PRICE_DEBUG_PAYLOADS] if every scraped row comes back with
price_current: null — never ships priced-looking rows with no
prices again.