Как извлечь данные о товарах Walmart: JSON, гео-цены, блокировки

У Walmart нет публичного API, каждая страница персонализирована, а скраперы блокируются CAPTCHA с удержанием кнопки. Но его Next.js JSON предоставляет чистые структурированные данные — если ваш IP пройдет проверку. Вот полный метод.

Walmart — крупнейший розничный продавец в мире, что делает его ценообразование живым экономическим сигналом — и нет публичного API Walmart для его чтения. Поэтому люди извлекают данные. Хорошая новость: Walmart — это сайт на Next.js, и каждая страница товара содержит единственный JSON-блок с полными, уже разобранными данными. Плохая новость: IP-адрес центра обработки данных сталкивается с CAPTCHA с удержанием кнопки, прежде чем увидеть этот JSON. Это руководство охватывает надежный метод — читайте JSON гидратации вместо стилизованного HTML, обходите защиту от ботов HUMAN с правильным IP и получайте гео-цены на уровне магазинов.

Перестаньте разбирать теги. Читайте JSON __NEXT_DATA__

Большинство учебников учат находить h1 для заголовка и span для цены. Это работает до тех пор, пока Walmart не изменит свои имена классов, что происходит часто. Надежный подход: Walmart рендерит React из тега скрипта с id="__NEXT_DATA__", содержащего всю модель товара в формате JSON. Захватите это один раз, и каждое поле будет структурировано:

import requests, json
from bs4 import BeautifulSoup

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                  "(KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36",
    "Accept-Language": "en-US,en;q=0.9",
}
proxies = {"http": "http://USER:PASS@gate.quantumproxies.io:8000",
           "https": "http://USER:PASS@gate.quantumproxies.io:8000"}

url = "https://www.walmart.com/ip/1756765288"
r = requests.get(url, headers=headers, proxies=proxies, timeout=20)

soup = BeautifulSoup(r.text, "html.parser")
blob = soup.find("script", id="__NEXT_DATA__")
data = json.loads(blob.string)
product = data["props"]["pageProps"]["initialData"]["data"]["product"]
print(product["name"], product["priceInfo"]["currentPrice"]["price"])

Точный путь к ключу меняется со временем, поэтому распечатайте верхнеуровневые ключи один раз и двигайтесь оттуда. Но принцип остается: JSON — это источник истины, и он включает цену, доступность, продавца, варианты и рейтинги в одном месте — без селектора для каждого поля, который может сломаться.

Дверь: "Робот или человек?"

Запустите запрос с чистого IP-адреса центра обработки данных, и вы не получите JSON товара — вы получите страницу с надписью "Робот или человек? Активируйте и удерживайте кнопку, чтобы подтвердить, что вы человек." Это HUMAN (ранее PerimeterX), слой защиты от ботов, который использует Walmart. Он оценивает репутацию IP, отпечаток TLS и заголовки вместе, и вызов с удержанием кнопки — это то, что он предлагает, когда оценка низкая.

Вы не решаете эту CAPTCHA; вы избегаете ее срабатывания. Самый большой рычаг — это IP. Резидентный прокси представляется как соединение реального покупателя Walmart, что поддерживает оценку достаточно высокой для предоставления реальной страницы. Диапазоны центра обработки данных заранее оцениваются как подозрительные и получают стену при первом запросе. Наш анализ как HUMAN обнаруживает автоматизацию охватывает, что еще влияет на эту оценку.

Конвейер для извлечения данных о товарах Walmart: URL товара через резидентный выход к JSON __NEXT_DATA__ и структурированным строкам
Маршрут через резидентный выход, затем читайте JSON гидратации — никаких хрупких HTML-селекторов на пути.

Гео-цены: один товар, много цен

Цены и наличие товаров Walmart зависят от конкретного магазина. Один и тот же товар показывает разную цену и доступность в зависимости от места покупки, поэтому скрапер без установленного местоположения читает данные одного произвольного магазина. Установите местоположение по ZIP, чтобы контролировать, какой магазин вы оцениваете — Walmart сохраняет его в cookie местоположения, поэтому отправляйте его при каждом запросе:

# pin the store location by US ZIP before reading price/stock
cookies = {"assortmentStoreId": "3081", "locationData": '{"postalCode":"10001"}'}

r = requests.get(url, headers=headers, cookies=cookies,
                 proxies=proxies, timeout=20)
# now priceInfo + availabilityStatus reflect that store

Чтобы сравнить товар на разных рынках, переберите свой список ZIP и сопоставьте каждый с резидентным выходом в этом регионе — покупатель из Нью-Йорка, читающий цены магазина NYC, гораздо более логичен, чем запрос, который заявляет одно местоположение, но выходит в другом месте. Эта гео-согласованность — это именно то, на чем основывается мониторинг цен конкурентов.

Страницы поиска и пагинация

Для работы с каталогом извлекайте результаты поиска, а не только страницы товаров. Две вещи, которые нужно знать: Walmart персонализирует порядок поиска для каждого пользователя, поэтому не ожидайте стабильного ранжирования между запусками, и результаты охватывают несколько страниц, которые вы пролистываете с помощью параметра page. Та же схема __NEXT_DATA__ применяется — JSON поиска содержит полный список товаров с ценами и идентификаторами, поэтому вам редко нужно касаться страницы товара, если только вы не хотите получить детали на уровне вариантов:

def search(query, pages=5):
    items = []
    for page in range(1, pages + 1):
        url = f"https://www.walmart.com/search?q={query}&page={page}"
        html = requests.get(url, headers=headers, cookies=cookies,
                            proxies=proxies, timeout=20).text
        blob = BeautifulSoup(html, "html.parser").find("script", id="__NEXT_DATA__")
        data = json.loads(blob.string)
        stacks = data["props"]["pageProps"]["initialData"]["searchResult"]["itemStacks"]
        for stack in stacks:
            items += stack["items"]
    return items

Когда стоит прекратить делать это вручную

Сырые запросы плюс резидентные IP позволяют далеко продвинуться на Walmart. Момент, когда это перестает окупаться, — это масштаб: вращение выходов на каждый запрос, повторение тех, которые все еще сталкиваются с блокировкой, и поддержание логики cookie магазина в согласованности для тысяч ZIP — это настоящая нагрузка на обслуживание. Scraper API, который включает отпечаток браузера, вращает резидентные IP и может возвращать разобранный JSON, сворачивает это в один вызов — вы отправляете URL Walmart и получаете обратно модель товара, блокировки обработаны. Если ваша страница возвращается как оболочка CAPTCHA вместо данных, это классический симптом пустой страницы, и это проблема рендеринга и IP, а не ошибка парсера.

CAPTCHA с удержанием кнопки Walmart HUMAN блокирует IP центра обработки данных, в то время как резидентный IP проходит к чистому JSON товара
Вы не решаете ворота с удержанием кнопки — вы поддерживаете свой уровень доверия достаточно высоким, чтобы они никогда не появлялись.

Получите резидентные IP, которые достигают Walmart

Часто задаваемые вопросы

Есть ли у Walmart API для данных о товарах?

Нет открытого публичного API для произвольных данных о товарах и ценах, поэтому скрапинг — это обычный путь. Существуют API для аффилиатов и продавцов на маркетплейсе Walmart, но они ограничены и имеют ограничения по объему. Для широкого сбора данных о товарах, ценах и доступности чтение JSON __NEXT_DATA__ страницы через резидентные IP — это практический метод.

Как извлечь цены Walmart, не будучи заблокированным?

Направляйте запросы через резидентные прокси, чтобы защита от ботов HUMAN оценила вас как реального покупателя, отправляйте согласованный браузерный User-Agent и Accept-Language и читайте JSON гидратации, а не делайте много запросов селекторов. Закрепите магазин по cookie ZIP и держите регион выхода в соответствии с ним. Эта комбинация избегает CAPTCHA с удержанием кнопки в большинстве запросов.

Почему Walmart показывает разные цены на один и тот же товар?

Цены и наличие товаров Walmart зависят от уровня магазина. Цена, которую вы видите, зависит от местоположения, установленного для сессии, поэтому два запроса с разными местоположениями ZIP законно возвращают разные цены. Чтобы собрать сопоставимые данные, зафиксируйте ZIP явно и сопоставьте свой выход прокси с этим регионом, а не позволяйте Walmart угадывать по IP.

Является ли JSON __NEXT_DATA__ лучше, чем разбор HTML?

Да, для надежности. Видимые имена классов Walmart часто меняются, ломая скраперы на основе CSS-селекторов, но JSON гидратации Next.js — это стабильная структурированная модель товара с ценой, вариантами, продавцом и доступностью в одном объекте. Разберите JSON один раз, и вы избежите стека хрупких селекторов для каждого поля.

Walmart не сложен, потому что данные скрыты — они прямо там в JSON страницы. Он сложен, потому что дверь проверяет, кто стучится. Читайте __NEXT_DATA__ вместо тегов, установите магазин по ZIP и стучитесь с резидентным IP, и вы получите чистые, сопоставимые данные о товарах в масштабе. Для работы с ценами в больших магазинах в более широком смысле тот же подход распространяется на Best Buy и Target.

Извлечение данных Walmart с одним вызовом API