Walmart Veri Çekme Rehberi: Ürün, Fiyat ve Stok Verilerini Güvenle Toplayın

Walmart'ın Akamai + PerimeterX korumasını aşmak, __NEXT_DATA__ JSON'unu ayrıştırmak ve rate-limit uyumlu planlama ile CPG ekipleri için eksiksiz bir scraping rehberi.

Walmart Veri Çekme Rehberi: Ürün, Fiyat ve Stok Verilerini Güvenle Toplayın

API mi, HTML mi? Walmart Veri Çekme Temel Kararı

Walmart, ürün verilerine erişmek için iki ana yol sunar: resmi Walmart Affiliate/Developer API ve doğrudan HTML scraping. API, yapılandırılmış JSON döner ve ToS uyumludur — ancak fiyat geçmişi, stok durumu, 3P satıcı bilgileri ve mağazaya özel envanter gibi kritik alanları ya hiç döndürmez ya da büyük kısıtlamalarla sunar. CPG ve perakende istihbarat ekiplerinin ihtiyaç duyduğu derinlik, HTML tabanlı çekmeyle mümkün olur.

Bu rehber, HTML üzerinden Walmart scraping'inin nasıl yapıldığını, Akamai + PerimeterX engellerinin nasıl aşıldığını ve __NEXT_DATA__ JSON katmanının neden en kolay ayrıştırma yolu olduğunu adım adım anlatıyor.

Walmart Ürün Kataloğu Yapısı

Walmart'ın site mimarisi üç ana sayfa türüne dayanır. Her birinin URL kalıplarını ve DOM/API yapılarını anlamak, verimli bir crawl stratejisi kurmanın ilk adımıdır.

Ürün Sayfaları: /ip/{slug}/{itemId}

Her ürün benzersiz bir itemId ile tanımlanır. URL formatı:

https://www.walmart.com/ip/Apple-AirPods-Pro-2nd-Gen/1752657042

Sayfa, Next.js tabanlı bir SPA olarak render edilir. İçerik, SSR ile gelir ve client-side hydration sonrası __NEXT_DATA__ script etiketi içinde tam ürün JSON'unu barındırır.

Kategori Sayfaları

Kategori sayfaları, breadcrumb hiyerarşisini takip eder:

https://www.walmart.com/cp/electronics/3944
https://www.walmart.com/cp/food/976759

Bu sayfalarda ürün kartları .pb-xl veya [data-testid="list-view"] içinde listelenir. Her kart, ürünün itemId'sini ve kısa metadata'sını içerir. Sayfalama, ?page=2 parametresiyle yapılır.

Arama Sayfaları

Arama, /search endpoint'i üzerinden çalışır:

https://www.walmart.com/search?q=airpods+pro&sort=price_low
https://www.walmart.com/search?q=airpods+pro&page=2

Sonuçlar, [data-testid="search-results"] konteynerında render edilir. Her ürün kartı, aria-label özniteliğinde ürün adını ve href özniteliğinde ürün URL'sini taşır.

Akamai + PerimeterX: Neden Residential Proxy Zorunlu?

Walmart, iki katmanlı bir anti-bot savunması kullanır:

  • Akamai Bot Manager: HTTP isteklerinin parmak izlerini (TLS指纹, JA3 hash, HTTP/2 frame sıralaması) analiz eder. Datacenter IP'leri, yüksek bot skoruyla otomatik olarak işaretlenir.
  • PerimeterX (HUMAN): Client-side JavaScript challenge'ları çalıştırır. _px3 ve _px2 çerezleri, browser parmak izi ve davranışsal sinyalleri doğrular.
Pratik etki: Datacenter proxy'lerle yapılan istekler, ilk 5-10 istekte 403 veya CAPTCHA sayfası döner. Residential proxy'ler ise ISP seviyesinde gerçek kullanıcı gibi görünür ve Akamai'nin IP reputation filtresini geçer.

PerimeterX'i tamamen atlatmak için yalnızca IP rotasyonu yetmez; headless browser (Playwright/Puppeteer) + residential proxy kombinasyonu gerekir. Ancak __NEXT_DATA__ stratejisi, PerimeterX challenge'ını SSR yanıtından dolayı atlatmanıza olanak tanır — çünkü Next.js, ilk render'da veriyi server-side embed eder.

Proxy Türleri Karşılaştırması

ÖzellikDatacenter ProxyResidential ProxyMobile Proxy
Walmart başarı oranı%5–15%85–95%95+
Akamai bot skoruYüksek (şüpheli)Düşük (normal)Çok düşük
IP başına maliyet$0.5–1/GB$3–8/GB
Uygun use caseTest / debugÜrün sayfası scrapingHesap gerektiren işlemler

__NEXT_DATA__: En Kolay Ayrıştırma Yolu

Walmart, Next.js framework'ü kullanır. Her sayfada, <script id="__NEXT_DATA__"> etiketi içinde, sayfanın tamamını tanımlayan bir JSON nesnesi gömülüdür. Bu JSON, server-side rendering sırasında üretilir ve client-side hydration için kullanılır.

Neden önemli? Çünkü bu JSON, PerimeterX challenge'ından önce yüklenir. İlk HTTP yanıtında zaten mevcuttur. DOM manipulation veya JavaScript execution gerektirmez. Bir HTTP GET isteği + JSON parse ile tüm verilere ulaşırsınız.

JSON yapısı şu yolu izler:

{
  "props": {
    "pageProps": {
      "initialData": {
        "data": {
          "product": {
            "itemId": 1752657042,
            "name": "Apple AirPods Pro...",
            "priceInfo": { ... },
            "availabilityStatus": "IN_STOCK",
            "sellerInfo": { ... },
            "ratings": { ... }
          }
        }
      }
    }
  }
}

CSS / XPath Seçiciler

Eğer __NEXT_DATA__'ya erişemezseniz (nadiren olur), DOM seçicileri:

  • Fiyat: [data-testid="product-price"] veya .price-characteristic
  • Ürün adı: [data-testid="product-title"]
  • Stok durumu: [data-testid="fulfillment-badge"]
  • Değerlendirme: [data-testid="product-rating"]

Python ile __NEXT_DATA__ Çekme ve Ayrıştırma

Aşağıdaki örnek, ProxyHat residential proxy üzerinden bir Walmart ürün sayfasını çeker, __NEXT_DATA__ JSON'unu ayrıştırır ve fiyat, stok, değerlendirme ve satıcı verilerini çıkarır:

import requests
import json
import re
from urllib.parse import quote

PROXY_URL = "http://user-country-US:YOUR_PASSWORD@gate.proxyhat.com:8080"

PROXIES = {
    "http": PROXY_URL,
    "https": PROXY_URL,
}

HEADERS = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                  "(KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
}

def fetch_product(item_id: str) -> dict:
    """Walmart ürün sayfasını çek ve __NEXT_DATA__'yı ayrıştır."""
    url = f"https://www.walmart.com/ip/{item_id}"
    resp = requests.get(url, headers=HEADERS, proxies=PROXIES, timeout=30)
    resp.raise_for_status()

    # __NEXT_DATA__ script etiketini bul
    match = re.search(
        r'<script id="__NEXT_DATA__"[^>]*>(.*?)</script>',
        resp.text,
        re.DOTALL
    )
    if not match:
        raise ValueError("__NEXT_DATA__ bulunamadı — muhtemelen CAPTCHA sayfası")

    next_data = json.loads(match.group(1))
    product = next_data["props"]["pageProps"]["initialData"]["data"]["product"]

    return {
        "item_id": product["itemId"],
        "name": product.get("name", ""),
        "price": product.get("priceInfo", {}).get("currentPrice", {}).get("price", None),
        "currency": product.get("priceInfo", {}).get("currentPrice", {}).get("currencyUnit", "USD"),
        "availability": product.get("availabilityStatus", "UNKNOWN"),
        "rating": product.get("ratings", {}).get("averageRating", None),
        "review_count": product.get("ratings", {}).get("totalReviews", 0),
        "seller_id": product.get("sellerInfo", {}).get("id", None),
        "seller_name": product.get("sellerInfo", {}).get("name", None),
        "is_marketplace": product.get("sellerInfo", {}).get("isMarketplaceSeller", False),
    }

# Kullanım
result = fetch_product("1752657042")
print(json.dumps(result, indent=2))

Örnek çıktı (kısaltılmış):

{
  "item_id": 1752657042,
  "name": "Apple AirPods Pro (2nd Generation)",
  "price": 189.0,
  "currency": "USD",
  "availability": "IN_STOCK",
  "rating": 4.5,
  "review_count": 28431,
  "seller_id": "F55CDC31AB754BB68C851B92E6A3E38B",
  "seller_name": "Walmart.com",
  "is_marketplace": false
}

curl ile Hızlı Test

curl -x http://user-country-US:YOUR_PASSWORD@gate.proxyhat.com:8080 \
  -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ..." \
  "https://www.walmart.com/ip/1752657042" \
  | grep -o '<script id="__NEXT_DATA__"[^>]*>.*</script>' \
  | sed 's/<script[^>]*>//;s/<\/script>//' \
  | python3 -m json.tool | head -50

Marketplace (3P) vs 1P Katalog: Farkları Anlamak

Walmart'ın ürün kataloğu iki ana kaynaktan oluşur:

1P — Walmart Doğrudan Satış

  • Satıcı: Walmart.com
  • isMarketplaceSeller alanı: false
  • Fulfillment: Walmart depolarından, Walmart lojistiğiyle
  • Stok verisi: fulfillmentBadge ile uyumlu — mağazaya özel stok sorgulanabilir

3P — Marketplace Satıcıları

  • Satıcı: Bağımsız merchant (ör. SellerName_123)
  • isMarketplaceSeller alanı: true
  • Fulfillment: Satıcı kendi gönderir veya Walmart fulfillment (WFS) kullanır
  • Aynı ürün birden fazla satıcıda listelenebilir — offer sayısı ürün sayfasında görünür

Stratejik fark: CPG ekipleri için 3P satıcı izleme, kanal çakışması (channel conflict) tespiti ve MAP (Minimum Advertised Price) ihlallerini yakalamak için kritiktir. Aynı SKU için 15 farklı satıcı farklı fiyat sunabilir.

3P Offer'ları Çekme

Ürün sayfasındaki __NEXT_DATA__ içinde, product.offerGroups veya product.buyboxOffers alanı tüm satıcı tekliflerini içerir. Her offer'ın fiyatı, kargo ücreti, estimated delivery tarihi ve satıcı bilgisi mevcuttur.

def extract_all_offers(next_data: dict) -> list:
    """Bir ürünün tüm 3P offer'larını çıkar."""
    product = next_data["props"]["pageProps"]["initialData"]["data"]["product"]
    offers = []
    
    # Buybox offers (ilk 2-3 offer)
    buybox = product.get("buyboxOffers", [])
    for offer in buybox:
        offers.append({
            "seller": offer.get("sellerName", ""),
            "price": offer.get("price", 0),
            "shipping": offer.get("shippingPrice", 0),
            "delivery_date": offer.get("fulfillment", {}).get("deliveryDate", ""),
            "is_marketplace": offer.get("isMarketplaceSeller", False),
        })
    
    # Tüm offer'lar için ayrı istek gerekli
    # /api/product/{itemId}/offers endpoint'i
    return offers

Not: Tüm offer'ları görmek için /api/product/{itemId}/offers endpoint'ine ayrı bir istek gerekir. Bu endpoint, PerimeterX tarafından korunur ve residential proxy + session persistence gerektirir.

Rate-Limit Uyumlu Planlama

Walmart, IP başına ve session başına request rate limiting uygular. Gözlemlenen eşikler:

  • Tekil IP başına: ~30-50 request/dakika üstü → 429 veya sessiz CAPTCHA
  • Tekil session başına: ~100-150 request/saat üstü → PerimeterX challenge
  • Arama sayfaları: Daha agresif koruma — ~10-15 request/dakika üstü → blok

Akıllı Crawl Stratejisi

  1. Sticky session kullanın: Aynı IP ile 80-100 istek yapın, ardından yeni session'a geçin. ProxyHat'ta user-session-SESSION_ID formatıyla sticky session oluşturabilirsiniz.
  2. Request aralığı: Ürün sayfaları için 2-4 saniye, arama sayfaları için 5-8 saniye bekleme.
  3. Gece saatlerini tercih edin: EST 00:00-06:00 arası trafik düşük, blok riski daha az.
  4. Exponential backoff: 429 alırsanız, 30 saniye bekle, tekrar dene. 3 deneme sonrası IP değiştir.
import time
import random

SESSION_SIZE = 80      # IP başına istek sayısı
DELAY_RANGE = (2, 4)   # saniye
MAX_RETRIES = 3

def crawl_products(item_ids: list) -> list:
    results = []
    session_counter = 0
    session_id = f"sess-{random.randint(10000,99999)}"

    for i, item_id in enumerate(item_ids):
        # Her SESSION_SIZE istekte yeni session
        if session_counter >= SESSION_SIZE:
            session_id = f"sess-{random.randint(10000,99999)}"
            session_counter = 0
            time.sleep(10)  # Session geçişi arası bekleme

        proxy_url = f"http://user-country-US-session-{session_id}:YOUR_PASSWORD@gate.proxyhat.com:8080"
        proxies = {"http": proxy_url, "https": proxy_url}

        for attempt in range(MAX_RETRIES):
            try:
                data = fetch_product_with_proxy(item_id, proxies)
                results.append(data)
                break
            except Exception as e:
                wait = (2 ** attempt) * 15 + random.uniform(0, 5)
                print(f"Deneme {attempt+1} başarısız: {e}. {wait:.1f}s bekleniyor...")
                time.sleep(wait)

        session_counter += 1
        time.sleep(random.uniform(*DELAY_RANGE))

    return results

Yaygın Hatalar ve Çözümleri

  • 403 Forbidden: IP bloklanmış. Residential proxy'ye geçin veya yeni session oluşturun.
  • Boş __NEXT_DATA__: CAPTCHA sayfası dönmüş. İstek rate'ini düşürün veya IP değiştirin.
  • Eksik fiyat verisi: Bazı ürünlerde priceInfo.currentPrice null olabilir. priceInfo.linePrice veya offer verisini kontrol edin.
  • Stale data: Walmart CDN cache'i 5-15 dakika sürebilir. Gerçek zamanlı stok için /api/product/{itemId}/fulfillment endpoint'ini kullanın — ancak bu endpoint daha sıkı koruma altındadır.

Etik ve Yasal Hususlar

Walmart scraping yaparken şu noktaları göz önünde bulundurun:

  • robots.txt: Walmart'ın robots.txt dosyası belirli path'leri (/api/, /account/) yasaklar. Ürün sayfaları genellikle izinlidir ancak durumu kontrol edin.
  • ToS: Walmart Kullanım Koşulları, otomatik veri toplamayı yasaklar. Ticari scraping için yasal danışmanlık alın.
  • GDPR / CCPA: Kişisel veri (kullanıcı yorumları, hesap bilgileri) topluyorsanız, ilgili düzenlemelere uyum sağlayın.
  • Rate limiting: Walmart'ın altyapısına zarar verecek düzeyde istek göndermeyin.

Daha fazla scraping stratejisi için web scraping use case sayfamızı inceleyin.

Temel Çıkarımlar

  • __NEXT_DATA__ en kolay yoldur: DOM parsing yerine gömülü JSON'u ayrıştırın — hızlı, güvenilir, PerimeterX'i atlatır.
  • Residential proxy zorunludur: Datacenter IP'ler Akamai tarafından anında işaretlenir. ProxyHat residential proxy'leri ile %85+ başarı oranı elde edin.
  • Sticky session + rate limiting: IP başına 80-100 istek, 2-4 saniye aralık, session geçişinde 10 saniye bekleme.
  • 1P ve 3P verisini ayırın: isMarketplaceSeller alanı ile satıcı tipini belirleyin, MAP ihlallerini tespit edin.
  • Gece crawl tercih edin: EST 00:00-06:00 arası blok riski minimumdur.

ProxyHat ile Walmart scraping'e başlamak için fiyatlandırma sayfamızı ziyaret edin veya dashboard'dan hemen hesap oluşturun. Residential proxy'lerimiz, 195+ ülkede geo-targeting desteğiyle Walmart'ın anti-bot korumasını güvenle aşmanızı sağlar.

Başlamaya hazır mısınız?

148+ ülkede 50M+ konut IP'sine AI destekli filtreleme ile erişin.

Fiyatlandırmayı GörüntüleKonut Proxy'leri
← Bloga Dön