Kuinka scrapata Walmartia Pythonilla vuonna 2026 (ja välttää esto)

Viimeksi päivitetty April 28, 2026
Kuinka scrapata Walmartia Pythonilla vuonna 2026 (ja välttää esto)

Walmart muuttaa joidenkin tuotteiden hintoja useita kertoja päivässä. Jos olet joskus yrittänyt seurata sitä ohjelmallisesti, tiedät kyllä tunteen: skripti toimii 20 minuuttia ja alkaa sitten hiljaa palauttaa CAPTCHA-sivuja, jotka näyttävät aivan tavallisilta 200 OK -vastauksilta.

Olen käyttänyt paljon aikaa Walmartin anti-bot-suojauksien läpikäyntiin osana datanpoistotyötämme Thunderbitillä, ja haluan jakaa kaiken oppimani — menetelmät, jotka oikeasti toimivat vuonna 2025, hiljaiset epäonnistumiset, jotka pilaavat datasi, sekä rehelliset kompromissit oman scraperin kirjoittamisen, scraping API:n maksamisen ja no-code-työkalun käytön välillä. Tämä opas kattaa kolme poimintatapaa (HTML-parsinta, __NEXT_DATA__-JSON ja sisäisten API-pyyntöjen sieppaus), tuotantokelpoisen virheenkäsittelyn, jonka useimmat ohjeet ohittavat kokonaan, sekä rehellisen päätösmallin oikean lähestymistavan valintaan. Tästä on hyötyä, kirjoitatpa Pythonia tai haluat vain taulukon täynnä hintoja ennen lounasta.

Miksi scrapata Walmartia Pythonilla?

Walmart on liikevaihdolla mitattuna maailman suurin vähittäiskauppias — 680,985 miljardia dollaria tilikaudella 2025, ja se on pitänyt Fortune Global 500 -listan ykkössijaa 12 vuotta putkeen. Sivustolla on noin 420 miljoonaa aktiivista listausta, ja Walmartin talousjohtaja on maininnut markkinapaikalla olevan "puoli miljardia SKU:ta". Noin 95 % näistä listauksista tulee kolmannen osapuolen myyjiltä, mikä tekee katalogista erittäin elävän — myyjät vaihtuvat, variantit muuttuvat ja varastosaatavuus kääntyy päivittäin.

walmart_stats_670d06c6bd.png

Juuri siksi scraping on tärkeää. Kvartaaliraportti ei koskaan tavoita sitä, minkä yöaikainen scrape voi. Tässä ovat yleisimmät käyttötapaukset, joita näen:

KäyttötapausKuka tarvitsee sitäMitä he poimivat
Kilpailijoiden hintaseurantaVerkkokaupan operointi, uudelleenhintaustyökalutHinnat, kampanjat, MAP-vaatimusten noudattaminen
Tuotekatalogin rikastaminenMyynti- ja merchandising-tiimitKuvaukset, kuvat, tekniset tiedot, variantit
Varastosaatavuuden seurantaToimitusketju, dropshipperitVarastotilanne, myyjätiedot
Markkinatutkimus ja trendianalyysiMarkkinointi, tuotepäällikötArvostelut, arvosanat, kategorian valikoima
Liidien hankintaMyyntitiimitMyyjien nimet, tuotemäärät, kategoriat

Pelkkä kilpailijoiden hintaseurantaohjelmistojen markkina oli 1,92 miljardia dollaria vuonna 2025 ja sen ennustetaan kasvavan 5,09 miljardiin dollariin vuoteen 2033 mennessä. Kuluttajakäyttäytyminen ajaa tätä kysyntää: 94 % asiakkaista vertailee hintoja verkossa asioidessaan, ja 83 % tekee hintavertailua useilla sivustoilla.

Python on tämän työn oletuskieli. Apifyn vuoden 2026 Infrastructure Report arvioi, että Pythonin osuus kaikesta web scrapingista on 71,7 %, ja ydinlib (requests) ladataan noin 30 miljoonaa kertaa viikossa. Jos scrapaat yhtään isommassa mittakaavassa, teet sen lähes varmasti Pythonilla.

Miksi Walmart on yksi vaikeimmista sivustoista scrapata

Walmart on erityisen hankala, koska se käyttää kahta kaupallista anti-bot-tuotetta peräkkäin: Akamai Bot Manageria reunalla toimivana WAF- ja TLS-fingerprinttikerroksena sekä PerimeterX:ää (uudelleennimetty HUMAN Securityksi) käyttäytymiseen perustuvana JavaScript-haastekerroksena. Scrape.do kuvaa tätä yhdistelmää "harvinaiseksi ja äärimmäisen vaikeaksi ohittaa".

walmart_antibot_3d67d0119c.png

ScrapeOps arvioi Walmartin vaikeusasteeksi 9/10 yleisessä scraping-vaikeudessa, ja Akamainkin osalta arvosana on 9/10. Kokemukseni mukaan tämä on aika osuva arvio.

Tässä, mitä vastaan oikeasti taistelet:

Akamai Bot Manager tarkistaa TLS-fingerprintin (JA3/JA4-hash), HTTP/2-kehysten järjestyksen, headerien järjestyksen ja kirjainkoon sekä sessiokeksit (_abck, ak_bmsc). Tavallinen Python requests -kutsu tuottaa TLS-fingerprintin, jota mikään oikea selain ei tee — Akamai liputtaa sen ennen kuin pyyntösi edes ehtii Walmartin palvelimille.

PerimeterX/HUMAN toimii Akamain jälkeen ja suorittaa JavaScript-pohjaisen fingerprint-keräyksen (px.js), joka tarkistaa navigator-ominaisuudet, canvas-renderöinnin, WebGL:n, audio contextin ja käyttäytymiseen liittyvät biometriset signaalit (hiiren liike, vierityksen nopeus, näppäilyn rytmi). Näkyvä epäonnistuminen on kuuluisa "Press & Hold" -haaste — painike, jota pitää painaa noin 10 sekuntia samalla kun käyttäytymissignaaleja näytteistetään. Oxylabs sanoo suoraan: "Walmart käyttää PerimeterX:n tarjoamaa 'Press & Hold' -CAPTCHA-mallia, jota on käytännössä lähes mahdoton ratkaista koodista käsin."

Todella vaarallinen ilmiö on hiljainen esto. Walmart palauttaa HTTP 200 -vastauksen CAPTCHA-sisällöllä 403:n sijaan. ScrapingBee vahvistaa: "Walmart palauttaa 200 OK -tilakoodin, vaikka se toimittaa CAPTCHA-sivun. Et voi luottaa pelkkään tilakoodiin tietääksesi, onnistuiko pyyntösi." Skripti parsii CAPTCHA-HTML:n tyytyväisenä "tuotetta ei löydy" -tilanteeksi ja jatkaa eteenpäin. Puolet datastasi on roskaa, etkä tiedä sitä.

Sitten on vielä kauppakohtaisen datan ongelma. Walmartin hinnat ja varasto ovat sijaintikohtaisia, ja niitä ohjaavat keksit kuten locDataV3 ja assortmentStoreId. Ilman oikeita keksejä saat "oletus kansallinen" -dataa, joka voi näyttää täydelliseltä mutta ei vastaa sitä, mitä oikeat ostajat näkevät. Puuttuvat keksit eivät tuota estosivua — ne tuottavat väärää dataa ilman näkyvää virhettä, mikä on pahempaa.

Kolme tapaa poimia dataa Walmartista (ja miten ne vertautuvat)

Ennen vaiheittaista ohjetta tässä ovat kolme pääasiallista poimintatapaa. Useimmat kilpailijoiden oppaat kattavat vain yhden tai kaksi. Käyn läpi kaikki kolme, jotta voit valita tilanteeseesi sopivan.

MenetelmäLuotettavuusDatan täydellisyysAnti-bot-vaikeusYlläpitokuorma
HTML + BeautifulSoup⚠️ Matala (selectorit hajoavat jokaisessa deployssa)KohtalainenKorkeaKorkea
__NEXT_DATA__-JSON✅ HyväKorkeaKeskitaso–korkeaKeskitaso
Sisäisten API-pyyntöjen sieppaus✅ ParasKorkein (variantit, varasto, arvostelut)Keskitaso–korkeaMatala (rakenteinen JSON)
Thunderbit (no-code)✅ HyväKorkeaMatala (AI hoitaa)Ei lainkaan

HTML-parsinta on Walmartille huonoin vaihtoehto — sivusto toimittaa Next.js-bundleja, joissa on hashatut CSS-luokkanimet, ja ne vaihtuvat jokaisessa deployssa. __NEXT_DATA__-JSON on käytännöllinen valinta, jota kaikki vakavasti otettavat vuosien 2024–2026 avoimen lähdekoodin Walmart-scraperit käyttävät. Sisäisten API-pyyntöjen sieppaus on vahvin lähestymistapa, mutta siihen liittyy varauksia, jotka useimmat oppaat ohittavat. Ja Thunderbit on oikea valinta silloin, kun et tarvitse lainkaan omaa putkea.

Kokeile Thunderbitiä Walmart-scrapaukseen

Python-ympäristön valmistelu Walmartin scrapaukseen

Tarvitset seuraavaa:

  • Vaikeustaso: Keskitaso
  • Aika: Noin 30 minuuttia asennukseen, plus koodausaika
  • Tarvitset: Python 3.10+, pipin, koodieditorin ja tuotantokäyttöön proxy-palvelun tai scraping API:n

Luo projektikansio ja virtuaaliympäristö:

mkdir walmart-scraper && cd walmart-scraper
python -m venv venv
source venv/bin/activate  # Windowsissa: venv\Scripts\activate

Asenna tarvittavat kirjastot:

pip install curl_cffi parsel beautifulsoup4 lxml

curl_cffi on vuoden 2025 standardi vaikeiden kohteiden scrapaukseen. Se on libcurl-sidos, joka pystyy tekeytymään täsmälleen oikean selaimen TLS-fingerprintiksi. Bright Data selittää: "Walmart käyttää TLS-fingerprintejä osana bottitunnistustaan, eikä pelkkä User-Agentin asettaminen oikeaa selainta jäljittelemään riitä ohittamaan sitä." Tavallinen requests tai httpx ei pääse Akamain ohi riippumatta siitä, mitä headereita asetat. curl_cffi ja impersonate="chrome124" tekevät ratkaisevan eron.

Tarvitset lisäksi json (sisäänrakennettu), csv (sisäänrakennettu), time, random ja logging myöhemmin käsiteltäviä tuotantomalleja varten.

Vaihe vaiheelta: Walmartin tuotesivujen scrapaus Pythonilla

Vaihe 1: Hae Walmartin tuotesivu

Ensimmäinen tehtäväsi on tehdä HTTP-pyyntö, joka ei esty heti. Tässä on kanoninen header-setti, jota Scrapfly, Scrapingdog, Oxylabs ja ScrapeOps käyttävät vuosina 2024–2026:

from curl_cffi import requests

HEADERS = {
    "User-Agent": (
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
        "AppleWebKit/537.36 (KHTML, like Gecko) "
        "Chrome/124.0.0.0 Safari/537.36"
    ),
    "Accept": (
        "text/html,application/xhtml+xml,application/xml;q=0.9,"
        "image/avif,image/webp,*/*;q=0.8"
    ),
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
    "Upgrade-Insecure-Requests": "1",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-User": "?1",
    "Referer": "https://www.google.com/",
}

session = requests.Session(impersonate="chrome124")
url = "https://www.walmart.com/ip/Apple-AirPods-Pro-2nd-Generation/1752657021"
response = session.get(url, headers=HEADERS)

impersonate="chrome124" tekee tässä raskaan työn. Se kertoo curl_cffi:lle, että sen pitää vastata Chrome 124:n tarkkaa TLS ClientHelloa, HTTP/2-kehysten järjestystä ja pseudo-headerien sekvenssiä. Ilman sitä Akamai näkee Python-kohtaisen JA3-hashin ja estää sinut ennen kuin pyyntösi edes saavuttaa Walmartin sovelluskerroksen.

Miltä estetty vastaus näyttää: Jos näet HTML:n otsikossa "Robot or human?" tai jos vastaus ohjautuu walmart.com/blocked-osoitteeseen, sinut on napattu. Hankala osa on se, että Walmart palauttaa usein 200-tilakoodin CAPTCHA-sisällöllä — joten pelkkään response.ok:iin ei voi luottaa.

Kaikessa tuotanto- tai toistuvassa käytössä tarvitset residential proxyja. Datacenter-IP:t palavat heti Akamain IP-reputaatiojärjestelmässä. Käsittelen täyden virheenkäsittelyn ja proxy-strategian tuotanto-osiossa alempana.

Vaihe 2: Parsii tuotedata __NEXT_DATA__-JSONista

Walmart.com on Next.js-sovellus, ja palvelinrenderöity HTML upottaa koko hydration-paketin yhteen script-tagiin: <script id="__NEXT_DATA__" type="application/json">. Tämä on kultasuoni.

Scrapflyn vuoden 2026 opas vahvistaa: "Vuonna 2026 Walmart käyttää Next.js:ää ja rakenteista JSONia __NEXT_DATA__-script-tageissa, mikä tekee piilotetun datan poiminnasta luotettavampaa kuin perinteisestä CSS-selectorien käytöstä." Jokainen tunnettu avoimen lähdekoodin Walmart-scraper — Scrapflyn, Oxylabsin, python-scrapy-playbookin — käyttää tätä menetelmää.

Näin se poimitaan:

import json
from parsel import Selector

sel = Selector(text=response.text)
raw = sel.xpath('//script[@id="__NEXT_DATA__"]/text()').get()
data = json.loads(raw)
product = data["props"]["pageProps"]["initialData"]["data"]["product"]
idml = data["props"]["pageProps"]["initialData"]["data"].get("idml", {})

Useimmat ohjeet pysähtyvät tähän. Alla on täydellinen JSON-polkujen kartta niille kentille, joista oikeasti välität — varmennettu live Walmart-sivuilla vuosina 2024–2026:

TietokenttäJSON-polku (initialData-kohdan alla)TyyppiHuomautukset
Tuotteen nimidata > product > nameMerkkijono
Tuotemerkkidata > product > brandMerkkijono
Nykyinen hinta (numero)data > product > priceInfo > currentPrice > priceLiukulukuVoi vaihdella kauppakansion keksin mukaan
Nykyinen hinta (merkkijono)data > product > priceInfo > currentPrice > priceStringMerkkijonoMuotoiltu esim. "$9.99"
Lyhyt kuvausdata > product > shortDescriptionHTML-merkkijonoParsittava BeautifulSoupilla tekstiksi
Pitkä kuvausdata > idml > longDescriptionHTML-merkkijonoSijaitsee idml:ssä, EI product-kohdan sisällä — tämä on ansa, jonka vanhemmat ohjeet menevät väärin
Kaikki kuvatdata > product > imageInfo > allImagesTaulukkoLista {id, url}-olioista
Keskimääräinen arvosanadata > product > averageRatingLiukulukuAvain on averageRating, ei vanha rating
Arvostelujen määrädata > product > numberOfReviewsKokonaisluku
Variantitdata > product > variantCriteriaTaulukkoVaihtoehtoryhmät (koko, väri)
Saatavuusdata > product > availabilityStatusMerkkijonoIN_STOCK, OUT_OF_STOCK, LIMITED_STOCK
Myyjädata > product > sellerDisplayNameMerkkijono
Valmistajadata > product > manufacturerNameMerkkijono

longDescription-polku on se ansa, johon ihmiset kompastuvat. Vuoden 2023 ScrapeHero-viesti sijoitti sen product.longDescription-polkuun, mutta vuoden 2024+ lähteet asettavat sen johdonmukaisesti sisaravaimeen idml. Lue aina ensin idml.longDescription ja varaa varalle product.longDescription vanhempia sivuja varten.

Tässä turvallinen poimintamalli .get()-ketjuilla:

def extract_product(data):
    product = data["props"]["pageProps"]["initialData"]["data"]["product"]
    idml = data["props"]["pageProps"]["initialData"]["data"].get("idml", {})

    price_info = product.get("priceInfo", {})
    current_price = price_info.get("currentPrice", {})
    image_info = product.get("imageInfo", {})

    return {
        "name": product.get("name"),
        "brand": product.get("brand"),
        "price": current_price.get("price"),
        "price_string": current_price.get("priceString"),
        "short_desc": product.get("shortDescription"),
        "long_desc": idml.get("longDescription", product.get("longDescription")),
        "images": [img.get("url") for img in image_info.get("allImages", [])],
        "rating": product.get("averageRating"),
        "review_count": product.get("numberOfReviews"),
        "variants": product.get("variantCriteria"),
        "availability": product.get("availabilityStatus"),
        "seller": product.get("sellerDisplayName"),
        "manufacturer": product.get("manufacturerName"),
    }

Niille käyttäjille, jotka eivät halua lainkaan käsitellä JSON-polkuja, Thunderbitin AI tunnistaa ja jäsentää nämä kentät automaattisesti — ei manuaalista polkukartoitusta. Klikkaat "AI Suggest Fields", se lukee sivun ja saat taulukon. Mutta jos rakennat omaa putkea, yllä oleva kartta on referenssisi.

Vaihe 3: Sieppaa Walmartin sisäiset API-päätepisteet rikkaampaa dataa varten

Mikään kilpailija-artikkeli ei käsittele tätä menetelmää kunnolla. Se on tehokkain poimintareitti — ja monimutkaisin.

Walmartin etupää kutsuu federoitua GraphQL-taustajärjestelmää, joka perustuu Apollo Gatewayyn. Päätepisteet sijaitsevat polussa www.walmart.com/orchestra/*:

  • /orchestra/pdp/graphql/... — tuotesivun hydration + varianttivaihdot
  • /orchestra/snb/graphql/... — haku- ja selaussivujen sivutus
  • /orchestra/reviews/graphql/... — sivutetut arvostelut

Nämä palauttavat siistiä, rakenteista JSONia, jossa on dataa, jota __NEXT_DATA__ joskus typistää — varianttikohtainen hinnoittelu, reaaliaikaiset varastomäärät, täysi arvostelujen sivutus.

Se koukku, jota blogikirjoitukset kiertävät: Walmart käyttää Apollon persisted queryjä. Pyyntöbody lähettää vain SHA-256-hashin (persistedQuery.sha256Hash), ei itse query-tekstiä. Jos hashia ei tunnisteta palvelimella, saat virheen PersistedQueryNotFound. Walmart kierrättää nämä hashit deployn yhteydessä. Siksi mikään tunnettu avoimen lähdekoodin Walmart-scraper ei julkaise suoraan kopioitavaa /orchestra/-koodia.

Käytännöllinen ja rehellinen versio tästä menetelmästä on DevTools-harjoitus:

  1. Avaa Walmartin tuotesivu Chromessa
  2. Avaa DevTools → Network-välilehti ja suodata "Fetch/XHR"
  3. Selaa sivua normaalisti — klikkaa variantteja, vieritä arvosteluihin, vaihda kauppasijaintia
  4. Etsi pyyntöjä /orchestra/*-päätepisteisiin, jotka palauttavat JSONia tuotedatan kanssa
  5. Klikkaa pyynnön päällä oikealla → "Copy as cURL"
  6. Muunna cURL-komento Pythoniksi curl_cffi:n avulla

Näin uudelleenajettu API-kutsu näyttää:

import json
from curl_cffi import requests

session = requests.Session(impersonate="chrome124")

# Ensin lämmitä sessio vierailemalla tuotesivulla
session.get("https://www.walmart.com/ip/some-product/1234567", headers=HEADERS)

# Sitten toista sisäinen API-kutsu (kopioitu DevToolsista)
api_url = "https://www.walmart.com/orchestra/pdp/graphql"
api_headers = {
    **HEADERS,
    "accept": "application/json",
    "content-type": "application/json",
    "referer": "https://www.walmart.com/ip/some-product/1234567",
    "wm_qos.correlation_id": "your-copied-correlation-id",
}
payload = {
    # Liitä tarkka request body DevToolsista
    "variables": {"productId": "1234567"},
    "extensions": {
        "persistedQuery": {
            "version": 1,
            "sha256Hash": "the-hash-you-copied"
        }
    }
}

api_response = session.post(api_url, headers=api_headers, json=payload)
api_data = api_response.json()

Sessioiden lämmitys on kriittistä. Walmartin PerimeterX-keksit (_px3, _pxhd, ACID) täytyy asettaa alkuperäisen HTML-haun kautta ennen kuin API-kutsu onnistuu. Ilman niitä saat 412- tai 403-vastauksen.

Milloin tätä menetelmää kannattaa käyttää: Kun tarvitset dataa, jota __NEXT_DATA__ ei sisällä — syvät varianttihinnat, ensimmäistä batchia pidemmälle sivutetut arvostelut tai reaaliaikaiset varastomäärät. Useimpiin käyttötarkoituksiin __NEXT_DATA__ riittää ja on paljon yksinkertaisempi.

Walmartin hakutulosten ja useiden sivujen scrapaus

Hakutulokset noudattavat samantyyppistä __NEXT_DATA__-mallia, mutta eri JSON-polulla:

search_url = "https://www.walmart.com/search?q=laptops&page=1"
response = session.get(search_url, headers=HEADERS)

sel = Selector(text=response.text)
raw = sel.xpath('//script[@id="__NEXT_DATA__"]/text()').get()
data = json.loads(raw)

search_result = data["props"]["pageProps"]["initialData"]["searchResult"]
items = search_result["itemStacks"][0]["items"]

# Suodata sponsoroidut tuotteet pois
organic_items = [i for i in items if i.get("__typename") == "Product"]

for item in organic_items:
    print(item.get("name"), item.get("priceInfo", {}).get("currentPrice", {}).get("price"))

Sivutus toimii kasvattamalla page-parametria: &page=1, &page=2 ja niin edelleen. Mutta tässä on dokumentoimaton rajoitus: Walmart rajoittaa hakutulokset 25 sivuun riippumatta todellisesta kokonaismäärästä. Scrapfly vahvistaa: "Walmart asettaa enimmäismääräksi 25 sivua riippumatta saatavilla olevien sivujen kokonaismäärästä."

Keinoja päästä syvemmälle:

  • Järjestyksen vaihtelu: Aja sama haku &sort=price_low ja sitten &sort=price_high, jolloin saat noin 50 sivua kattavuutta
  • Hintahaarukan pilkkominen: Lisää &min_price=X&max_price=Y jakamaan katalogi pienempiin ikkunoihin
  • Kategoriapilkkuminen: Hae tietyistä kategorioista sivuston laajuisen haun sijaan

Huomaa, että itemStacks on taulukko. Scrapfly kovakoodaa [0]:n repossaan, mutta kategoria- ja selaussivuilla on joskus useita pinoja ("Top picks", "More results"). Kestävä malli käy läpi kaikki pinot:

for stack in search_result.get("itemStacks", []):
    for item in stack.get("items", []):
        if item.get("__typename") == "Product":
            # käsittele item
            pass

Maininnan arvoista on myös, että Walmartin robots.txt kieltää polun /search. Tuotesivut (/ip/...) ja useimmat kategoriat (/cp/...) eivät ole kiellettyjä. Jos huolettaa yhteensopivuus, aloita tuotesivuista ja kategoriapuusta hakusivujen sijaan.

Älä anna hiljaisten estojen pilata dataasi: tuotantokelpoinen virheenkäsittely

Useimmat ohjeet kaatuvat tähän. Ne näyttävät, miten haetaan yksi sivu, parsitaan yksi tuote ja lopetetaan siihen. Tuotannossa haet tuhansia sivuja, ja Walmart yrittää aktiivisesti estää sinua. Demon ja oikeasti toimivan scraperin ero on siinä, miten se käsittelee epäonnistumisia.

Tunnista hiljaiset estot ennen kuin ne pilaavat datasi

Yksittäisen Walmart-scraperin tärkein funktio on estoilmaisin. Vendorien yhteisen näkemyksen perusteella ScrapingBee, Scrapingdog, Oxylabs ja Decodo mukaan tarvitset neljä erillistä tarkistusta:

BLOCK_MARKERS = (
    "Robot or human",
    "Press &amp; Hold",
    "Press & Hold",
    "px-captcha",
    "perimeterx",
)

def is_walmart_blocked(response) -> bool:
    # 1. Uudelleenohjaus erilliseen estopäätepisteeseen
    if "/blocked" in str(response.url):
        return True
    # 2. Kovat tilakoodit
    if response.status_code in (403, 412, 428, 429, 503):
        return True
    # 3. 200 OK CAPTCHA-sisällöllä (hiljainen esto)
    body = response.text or ""
    if any(m.lower() in body.lower() for m in BLOCK_MARKERS):
        return True
    # 4. Vastauksen pituuden järkevyys — oikeat PDP-sivut ovat 300–900 KB
    if len(response.content) < 50_000 and "/ip/" in str(response.url):
        return True
    return False

Tuo neljäs tarkistus — vastauksen pituus — nappaa tapaukset, joissa Walmart palauttaa riisityn sivun, joka ei sisällä ilmeisiä CAPTCHA-merkkejä mutta ei myöskään tarvitsemaasi tuotetietoa.

Uusintayritykset eksponentiaalisella backoffilla ja jitterillä

Kun pyyntö epäonnistuu, et halua hakata Walmartia heti uudelleen. Vakiomalli käyttää eksponentiaalista backoffia ja jitteriä, jotta uusintayritykset eivät synkronoidu:

import time
import random
import logging
from curl_cffi import requests as cffi_requests

log = logging.getLogger("walmart")

def fetch_with_retry(session, url, max_retries=5, base_delay=2, max_delay=60):
    for attempt in range(max_retries):
        try:
            response = session.get(url, headers=HEADERS, timeout=15)

            if response.status_code in (429, 503):
                raise Exception(f"Throttled: {response.status_code}")

            if is_walmart_blocked(response):
                raise Exception("Hiljainen esto havaittu")

            return response

        except Exception as e:
            if attempt == max_retries - 1:
                raise

            wait = min(max_delay, base_delay * (2 ** attempt)) + random.uniform(0, 3)
            log.warning(f"Yritys {attempt + 1} epäonnistui: {e}. Uusitaan {wait:.1f} s kuluttua")
            time.sleep(wait)

    return None

Jitter (random.uniform(0, 3)) ei ole kosmeettinen yksityiskohta — se hajauttaa workerit niin, ettei scraper-laivue yritä uudestaan samana sekuntina ja laukaise Akamain nopeusdetektoreita.

Nopeusrajoitus

Sekä Thunderbit että Scrape.do päätyvät Walmartille 3–6 sekunnin satunnaiseen viiveeseen pyyntöä kohden: "rajoita pyyntöjä odottamalla 3–6 sekuntia sivulatausten välillä ja satunnaistamalla viiveet."

import time
import random

def rate_limited_fetch(session, url):
    response = fetch_with_retry(session, url)
    time.sleep(random.uniform(3.0, 6.0))
    return response

Mittakaavassa kannattaa harkita aiolimiter-kirjastoa async-nopeusrajoitukseen:

from aiolimiter import AsyncLimiter
limiter = AsyncLimiter(max_rate=10, time_period=60)  # 10 pyyntöä minuutissa

Datan validointi

Vaikka vastaus ei olisi estetty, parsittu data voi silti olla väärää (väärä kauppa, heikentynyt payload). Vahvista ennen ulostuloon kirjoittamista:

def validate_product(product):
    """Palauttaa True, jos tuotedata näyttää aidolta."""
    if not product.get("name"):
        return False

    price = (product.get("priceInfo") or {}).get("currentPrice", {}).get("price")
    if not isinstance(price, (int, float)) or price <= 0:
        return False

    if product.get("availabilityStatus") not in ("IN_STOCK", "OUT_OF_STOCK", "LIMITED_STOCK"):
        return False

    return True

Sessiolokitus

Seuraa onnistumisastetta sessiokohtaisesti. Kun se laskee alle 80 %:n 10 minuutin ajaksi, jokin on muuttunut — joko IP:si on palanut, keksit ovat vanhentuneet tai Walmart on ottanut käyttöön uuden anti-bot-säännön.

class ScrapeMetrics:
    def __init__(self):
        self.total = 0
        self.success = 0
        self.blocks = 0
        self.errors = 0

    def record(self, result):
        self.total += 1
        if result == "success":
            self.success += 1
        elif result == "blocked":
            self.blocks += 1
        else:
            self.errors += 1

    @property
    def success_rate(self):
        return (self.success / self.total * 100) if self.total > 0 else 0

    def check_health(self):
        if self.total > 20 and self.success_rate < 80:
            log.critical(f"Onnistumisaste putosi {self.success_rate:.1f} %:iin — harkitse proxyjen vaihtamista tai taukoa")

Ei mikään hohdokas osa. Mutta se pitää datasi siistinä.

DIY-Python vs. scraping API vs. no-code: oikean lähestymistavan valinta Walmartin scrapaukseen

Moni kehittäjä hyppää suoraan oman scraperin kirjoittamiseen kysymättä, onko se oikea valinta. ScrapeOps arvioi Walmartin vaikeusasteeksi 9/10. Foorumikäyttäjät kuvaavat sitä "käytännössä 9/10:ksi" ja pohtivat, olisiko "erillinen web scraping API jo liioittelua". Vastaus riippuu volyymista, budjetista ja teknisestä kapasiteetista.

TekijäDIY Python (requests + proxyt)Scraping API (Oxylabs, Bright Data jne.)No-code-työkalu (Thunderbit)
Aika ensimmäiseen riviinTunteja15–60 minNoin 2 min
Aika tuotantoon40–80 h4–16 hNoin 30 min
Anti-bot-käsittelySinä hoidat (vaikea)Palveluntarjoaja hoitaaHoituu automaattisesti
Kustannus pienessä mittakaavassa (<1K sivua/kk)Matala (proxykustannukset noin 4–8 $/GB)40–49 $/kk aloitustasotIlmainen–15 $/kk
Kustannus mittakaavassa (100K+ sivua/kk)Halvempi per pyyntöKalliimpi per pyyntöVaihtelee
MukautettavuusTäysi hallintaAPI-parametritRajattu UI:n/kenttien mukaan
Jatkuva ylläpito4–8 h/kkLähes nollaEi lainkaan (AI mukautuu)
Paras käyttäjäKehittäjät, jotka rakentavat omia putkiaanKeskisuuri tuotantokaava scrapingLiiketoimintakäyttäjät, nopea kertapoiminta

Milloin DIY Python on järkevä valinta

DIY voittaa, kun omistat jo proxy-sopimuksen, tarvitset tiukkaa hallintaa headereista, postinumerokohdistuksesta tai myyjäryhmistä, indeksoit miljoonia sivuja kuukaudessa, jolloin API-maksut alkavat kasautua, tai tarvitset on-prem-/compliance-takuita. Kompromissi on todellinen suunnitteluaika: tuotantokelpoinen Scrapy-hämähäkki sivutuksella, uudelleenyrittyksillä, proxy-kierrätyksellä, TLS-imitaatiolla ja useilla sivutyyppiskaavoilla vie 40–80 tuntia kokeneen Python-kehittäjän työtä, sekä 4–8 tuntia kuukaudessa ylläpitoa, kun Walmart kierrättää fingerprinttejä.

Milloin scraping API säästää aikaasi

Scraping API:t hoitavat anti-bot-kerroksen puolestasi. ScrapeOpsin benchmarkit näyttävät 99 % onnistumisasteen Zyte API:lle ja 98 %:n Scrape.do:lle Walmartissa. Aloitustason hinnoittelu on 40–49 $/kk työkaluissa kuten ScraperAPI, Oxylabs ja Scrapingdog. Jos olet 2–5 hengen tiimi ja scraping-volyymisi on 10K–1M sivua kuukaudessa, API on lähes aina oikea valinta. Vaihdat per-pyyntö-kustannuksen nollaylläpitoon.

Milloin no-code on oikea valinta

Thunderbit sopii aivan erilaiseen profiiliin. Jos olet PM, analyytikko tai verkkokaupan tekijä ja tarvitset Walmartin tuotetiedot taulukkoon jo tänä iltapäivänä — et seuraavassa sprintissä — no-code-työkalu on rehellinen vastaus.

Työskentelytapa: asenna Thunderbit Chrome -laajennus, siirry Walmartin tuote- tai hakusivulle, klikkaa "AI Suggest Fields", ja Thunderbitin AI lukee sivun ja ehdottaa sarakkeita (tuotteen nimi, hinta, arvosana jne.). Klikkaa "Scrape", ja data täyttyy taulukkoon. Vie Exceliin, Google Sheetsiin, Airtableen tai Notioniin — kaikki ilmaiseksi, ilman paywallia.

Thunderbit hoitaa anti-botin pilvessä, joten et joudu taistelemaan CAPTCHAn, proxyjen tai TLS-fingerprinttien kanssa. AI mukautuu automaattisesti ulkoasun muutoksiin, joten ylläpitoa ei ole. Käyttäjille, jotka eivät halua käsitellä JSON-polkuja lainkaan, tämä on vähiten kitkaa aiheuttava reitti.

Rehelliset rajoitukset: Thunderbit ei ole rakennettu 100K+ sivuun päivässä. Credit-budjetit ja pilvirajat tekevät erittäin suurivolyymisestä ingestistä taloudellisesti huonomman vaihtoehdon kuin raaka API. Et myöskään voi lukita tiettyä postinumeroa tai ASN:ää, ellei työkalu tue sitä. Jatkuviin, suurivolyymisiin putkiin DIY tai scraping API on yhä parempi valinta.

Karkea hinnoittelu: 1 000 Walmartin tuoteriviä Thunderbitissä maksaa noin 2 000 creditiä (noin 0,60–1,10 $ Starter/Pro-suunnitelmilla). Se on samaa luokkaa kuin Oxylabsin Walmart API ja halvempi kuin useimmat harrastetason scraping API:t pienellä volyymilla. Tarkista Thunderbitin hinnoittelu ajantasaiset tiedot.

Scrapaa Walmartin tuotetiedot AI:lla Get Started Free

Scrapatun Walmart-datan vienti

Kun data on kasassa, tarvitset sille käyttökelpoisen paikan. Kolme formaattia kattaa useimmat tarpeet:

CSV — vähimmäisformaatti, jonka analyytikot oikeasti avaavat:

import csv

def export_csv(products, filename="walmart_products.csv"):
    fieldnames = ["name", "price", "availability", "rating", "review_count", "seller", "url"]
    with open(filename, "w", newline="", encoding="utf-8-sig") as f:
        writer = csv.DictWriter(f, fieldnames=fieldnames, quoting=csv.QUOTE_MINIMAL)
        writer.writeheader()
        for p in products:
            writer.writerow({k: p.get(k) for k in fieldnames})

Käytä utf-8-sig-koodausta Excel-yhteensopivuuden vuoksi. BOM-merkki estää Exceliä sotkemasta erikoismerkkejä.

JSONL — tuotantomuoto scraping-putkille:

import json
import gzip

def export_jsonl(products, filename="walmart_products.jsonl.gz"):
    with gzip.open(filename, "at", encoding="utf-8") as f:
        for p in products:
            f.write(json.dumps(p, ensure_ascii=False) + "\n")

JSONL on kaatumisturvallinen (keskeytynyt kirjoitus hukkaa vain viimeisen rivin), se on streamattavissa vakion muistinkäytön kanssa ja säilyttää sisäkkäisen datan kuten variantit ja arvostelut.

Excel — kertaluonteiseen analyytikkoluovutukseen:

from openpyxl import Workbook

def export_excel(products, filename="walmart_products.xlsx"):
    wb = Workbook(write_only=True)
    ws = wb.create_sheet("Products")
    ws.append(["Nimi", "Hinta", "Saatavuus", "Arvosana", "Arvostelut", "Myyjä"])
    for p in products:
        ws.append([p.get("name"), p.get("price"), p.get("availability"),
                    p.get("rating"), p.get("review_count"), p.get("seller")])
    wb.save(filename)

Thunderbit kattaa vientitarpeen myös muille kuin Python-käyttäjille: yhden klikkauksen vienti Google Sheetiin, Airtableen, Notioniin, Exceliin, CSV:ksi ja JSONiksi — kaikki ilmaiseksi perustasolla. Jatkuvaan seurantaan Thunderbitin scheduled scraper -ominaisuus voi ajaa toistuvat poiminnat automaattisesti.

Yksi ajoitukseen liittyvä huomio: älä käytä GitHub Actionsia Walmart-scrapaukseen. GitHub Actionsin ajurit sijaitsevat Azure-IP-alueilla, jotka Walmartin anti-bot estää heti. Käytä APScheduleria VPS:llä tai reititä koko liikenne residential-proxyjen kautta.

Walmartin scrapauksen lailliset ja eettiset ohjeet

Foorumikäyttäjät ilmaisevat tämän huolen suoraan: "Minulle sopii kehittäjien kanssa hiirikissa ja -hiiri -leikki, mutta juristitiimin kanssa leikkiminen vähän arveluttaa."

Walmartin käyttöehdot kieltävät nimenomaisesti käyttämästä "mitään robottia, spideriä… tai muuta manuaalista tai automaattista välinettä Materialsin hakemiseen, indeksointiin, 'scrappaamiseen', 'data miningiin' tai muuten keräämiseen" ilman "ennalta annettua kirjallista lupaa".

Walmartin robots.txt kieltää polut /search, /account, /api/ sekä kymmeniä sisäisiä päätepisteitä. Tuotesivut (/ip/...) ja arvostelut (/reviews/product/) eivät ole kiellettyjä.

hiQ v. LinkedIn -ennakkotapaus (9. piiri, 2022) vahvisti, että julkisesti saatavilla olevan datan scraping ei todennäköisesti riko liittovaltion CFAA-lakia. Mutta sama tuomioistuin totesi myöhemmin, että hiQ rikkoi LinkedInin käyttöehtoja ja määräsi sitä vastaan 500 000 dollarin sovintosumman. Tuoreemmat vuoden 2024 päätökset (Meta v. Bright Data, X Corp. v. Bright Data) rajasivat CFAA:n soveltamista edelleen ja loivat tekijänoikeuden etusijaan liittyviä puolustuksia, mutta nuo ratkaisut perustuivat hyvin tietynlaiseen ToU-tekstiin, joka ei siirry suoraviivaisesti Walmartiin.

Käytännön ohjeet: Älä kuormita palvelimia liikaa. Noudata nopeusrajoja. Älä scrapea henkilö- tai käyttäjätietoja. Käytä dataa vastuullisesti. Julkisten Walmartin tuotesivujen scrapaus kohtuullisella tahdilla henkilökohtaista tutkimusta varten on aivan eri riskiluokassa kuin kaupallinen scraping Walmartin ehtoja vastaan. Jos rakennat tuotetta Walmart-datan varaan, keskustele lakimiehen kanssa ja selvitä Walmartin viralliset affiliate- ja seller API:t.

Vastuuvapauslauseke: Tämä on opetuksellista tietoa, ei oikeudellista neuvontaa.

Johtopäätös ja tärkeimmät opit

Walmartin scrapaus Pythonilla on 9/10-vaikeustason haaste sen kaksois-anti-bot-kerroksen, Akamain ja PerimeterX:n, vuoksi. Ei mahdotonta — mutta tarvitset oikeat työkalut ja mallipohjat.

Tärkeimmät opit:

  • __NEXT_DATA__-JSONin poiminta on käytännöllisin vaihtoehto useimpiin käyttötarkoituksiin. Sitä käyttävät kaikki vakavasti otettavat vuosien 2024–2026 avoimen lähdekoodin Walmart-scraperit. Peruspolku on props.pageProps.initialData.data.product PDP-sivuille ja searchResult.itemStacks haku-/selaussivuille.
  • curl_cffi ja impersonate="chrome124" ovat pakollisia. Tavallinen requests tai httpx ei pääse Akamain TLS-fingerprinttien ohi headereista riippumatta.
  • Hiljaiset estot ovat todellinen vaara. Walmart palauttaa 200 OK -vastauksia CAPTCHA-sisällöllä. Tarkista vastauksen sisältö, älä vain tilakoodeja.
  • Tuotantocrappaajat tarvitsevat enemmän kuin onnellisen polun koodin. Eksponentiaalinen backoff jitterillä, neljän signaalin estoilmaisu, 3–6 sekunnin nopeusrajoitus per pyyntö, datan validointi ja session kunnon seuranta ovat kaikki olennaisia.
  • Sisäisten API-pyyntöjen sieppaus /orchestra/*-reitillä on tehokasta mutta haurasta. Käytä sitä DevTools-harjoituksena tiettyihin datatarpeisiin, älä ensisijaisena poimintamenetelmänä.
  • Walmart rajoittaa hakutulokset 25 sivuun. Mene laajemmaksi vaihtamalla järjestystä ja pilkkomalla hintaWalmart muuttaa joidenkin tuotteiden hintoja useita kertoja päivässä. Jos olet joskus yrittänyt seurata sitä ohjelmallisesti, tiedät tunteen: skripti pyörii 20 minuuttia ja alkaa sitten salaa palauttaa CAPTCHA-sivuja, jotka näyttävät tavallisilta 200 OK -vastauksilta.

Olen käyttänyt paljon aikaa Walmartin anti-bot-suojauksien läpikäyntiin osana datanpoistotyötämme Thunderbitillä, ja haluan jakaa kaiken oppimani — menetelmät, jotka oikeasti toimivat vuonna 2025, hiljaiset epäonnistumiset, jotka pilaavat datasi, sekä rehelliset kompromissit oman scraperin rakentamisen, scraping API:n maksamisen ja no-code-työkalun käytön välillä. Tämä opas kattaa kolme poimintatapaa (HTML-parsinta, __NEXT_DATA__-JSON ja sisäisten API-pyyntöjen sieppaus), tuotantokelpoisen virheenkäsittelyn, jonka useimmat ohjeet ohittavat täysin, sekä rehellisen päätösmallin oikean lähestymistavan valintaan. Tästä on hyötyä, kirjoitatpa Pythonia tai haluat vain taulukon täynnä hintoja ennen lounasta.

Miksi scrapata Walmartia Pythonilla?

Walmart on liikevaihdolla mitattuna maailman suurin vähittäiskauppias — 680,985 miljardia dollaria tilikaudella 2025, ja se on pitänyt Fortune Global 500 -listan ykkössijaa 12 vuotta putkeen. Sivustolla on noin 420 miljoonaa aktiivista listausta, ja Walmartin talousjohtaja on maininnut markkinapaikalla olevan "puoli miljardia SKU:ta". Noin 95 % näistä listauksista tulee kolmannen osapuolen myyjiltä, mikä tekee katalogista erittäin elävän — myyjät vaihtuvat, variantit muuttuvat ja varastosaatavuus kääntyy päivittäin.

walmart_stats_670d06c6bd.png

Juuri siksi scraping on tärkeää. Kvartaaliraportti ei koskaan näe sitä, minkä yöaikainen scrape voi poimia. Tässä yleisimmät käyttötapaukset, joita näen:

KäyttötapausKuka tarvitsee sitäMitä he poimivat
Kilpailijoiden hintaseurantaVerkkokaupan operointi, uudelleenhintaustyökalutHinnat, kampanjat, MAP-vaatimusten noudattaminen
Tuotekatalogin rikastaminenMyynti- ja merchandising-tiimitKuvaukset, kuvat, tekniset tiedot, variantit
Varastosaatavuuden seurantaToimitusketju, dropshipperitVarastotilanne, myyjätiedot
Markkinatutkimus ja trendianalyysiMarkkinointi, tuotepäällikötArvostelut, arvosanat, kategorian valikoima
Liidien hankintaMyyntitiimitMyyjien nimet, tuotemäärät, kategoriat

Pelkkä kilpailijoiden hintaseurantaohjelmistojen markkina oli 1,92 miljardia dollaria vuonna 2025 ja sen ennustetaan kasvavan 5,09 miljardiin dollariin vuoteen 2033 mennessä. Kuluttajakäyttäytyminen ruokkii tätä kysyntää: 94 % asiakkaista vertailee hintoja verkossa asioidessaan, ja 83 % tekee hintavertailua useilla sivustoilla.

Python on tämän työn oletuskieli. Apifyn vuoden 2026 Infrastructure Report arvioi, että Pythonin osuus kaikesta web scrapingista on 71,7 %, ja ydinlib (requests) ladataan noin 30 miljoonaa kertaa viikossa. Jos scrapaat yhtään mittakaavassa, teet sen lähes varmasti Pythonilla.

Miksi Walmart on yksi vaikeimmista sivustoista scrapata

Walmart on erityisen hankala, koska se käyttää kahta kaupallista anti-bot-tuotetta peräkkäin: Akamai Bot Manageria reunalla toimivana WAF- ja TLS-fingerprinttikerroksena sekä PerimeterX:ää (uudelleennimetty HUMAN Securityksi) käyttäytymiseen perustuvana JavaScript-haastekerroksena. Scrape.do kuvaa tätä yhdistelmää "harvinaiseksi ja äärimmäisen vaikeaksi ohittaa".

walmart_antibot_3d67d0119c.png

ScrapeOps arvioi Walmartin vaikeusasteeksi 9/10 yleisessä scraping-vaikeudessa, ja Akamainkin osalta arvosana on 9/10. Kokemukseni mukaan tämä on aika osuva arvio.

Tässä, mitä vastaan oikeasti taistelet:

Akamai Bot Manager tarkistaa TLS-fingerprintin (JA3/JA4-hash), HTTP/2-kehysten järjestyksen, headerien järjestyksen ja kirjainkoon sekä sessiokeksit (_abck, ak_bmsc). Tavallinen Python requests -kutsu tuottaa TLS-fingerprintin, jota mikään oikea selain ei tee — Akamai liputtaa sen ennen kuin pyyntösi edes ehtii Walmartin palvelimille.

PerimeterX/HUMAN toimii Akamain jälkeen ja suorittaa JavaScript-pohjaisen fingerprint-keräyksen (px.js), joka tarkistaa navigator-ominaisuudet, canvas-renderöinnin, WebGL:n, audio contextin ja käyttäytymiseen liittyvät biometriset signaalit (hiiren liike, vierityksen nopeus, näppäilyn rytmi). Näkyvä epäonnistuminen on kuuluisa "Press & Hold" -haaste — painike, jota pitää painaa noin 10 sekuntia samalla kun käyttäytymissignaaleja näytteistetään. Oxylabs sanoo suoraan: "Walmart käyttää PerimeterX:n tarjoamaa 'Press & Hold' -CAPTCHA-mallia, jota on käytännössä lähes mahdoton ratkaista koodista käsin."

Todella vaarallinen ilmiö on hiljainen esto. Walmart palauttaa HTTP 200 -vastauksen CAPTCHA-sisällöllä 403:n sijaan. ScrapingBee vahvistaa: "Walmart palauttaa 200 OK -tilakoodin, vaikka se toimittaa CAPTCHA-sivun. Et voi luottaa pelkkään tilakoodiin tietääksesi, onnistuiko pyyntösi." Skripti parsii CAPTCHA-HTML:n tyytyväisenä "tuotetta ei löydy" -tilanteeksi ja jatkaa eteenpäin. Puolet datastasi on roskaa, etkä tiedä sitä.

Sitten on vielä kauppakohtaisen datan ongelma. Walmartin hinnat ja varasto ovat sijaintikohtaisia, ja niitä ohjaavat keksit kuten locDataV3 ja assortmentStoreId. Ilman oikeita keksejä saat "oletus kansallinen" -dataa, joka voi näyttää täydelliseltä mutta ei vastaa sitä, mitä oikeat ostajat näkevät. Puuttuvat keksit eivät tuota estosivua — ne tuottavat väärää dataa ilman näkyvää virhettä, mikä on pahempaa.

Kolme tapaa poimia dataa Walmartista (ja miten ne vertautuvat)

Ennen vaiheittaista ohjetta tässä ovat kolme pääasiallista poimintatapaa. Useimmat kilpailijoiden oppaat kattavat vain yhden tai kaksi. Käyn läpi kaikki kolme, jotta voit valita tilanteeseesi sopivan.

MenetelmäLuotettavuusDatan täydellisyysAnti-bot-vaikeusYlläpitokuorma
HTML + BeautifulSoup⚠️ Matala (selectorit hajoavat jokaisessa deployssa)KohtalainenKorkeaKorkea
__NEXT_DATA__-JSON✅ HyväKorkeaKeskitaso–korkeaKeskitaso
Sisäisten API-pyyntöjen sieppaus✅ ParasKorkein (variantit, varasto, arvostelut)Keskitaso–korkeaMatala (rakenteinen JSON)
Thunderbit (no-code)✅ HyväKorkeaMatala (AI hoitaa)Ei lainkaan

HTML-parsinta on Walmartille huonoin vaihtoehto — sivusto toimittaa Next.js-bundleja, joissa on hashatut CSS-luokkanimet, ja ne vaihtuvat jokaisessa deployssa. __NEXT_DATA__-JSON on käytännöllinen valinta, jota kaikki vakavasti otettavat vuosien 2024–2026 avoimen lähdekoodin Walmart-scraperit käyttävät. Sisäisten API-pyyntöjen sieppaus on tehokkain lähestymistapa, mutta siihen liittyy varauksia, jotka useimmat oppaat ohittavat. Ja Thunderbit on oikea valinta silloin, kun et tarvitse lainkaan omaa putkea.

Kokeile Thunderbitiä Walmart-scrapaukseen

Python-ympäristön valmistelu Walmartin scrapaukseen

Tarvitset seuraavaa:

  • Vaikeustaso: Keskitaso
  • Aika: Noin 30 minuuttia asennukseen, plus koodausaika
  • Tarvitset: Python 3.10+, pipin, koodieditorin ja tuotantokäyttöön proxy-palvelun tai scraping API:n

Luo projektikansio ja virtuaaliympäristö:

mkdir walmart-scraper && cd walmart-scraper
python -m venv venv
source venv/bin/activate  # Windowsissa: venv\Scripts\activate

Asenna tarvittavat kirjastot:

pip install curl_cffi parsel beautifulsoup4 lxml

curl_cffi on vuoden 2025 standardi vaikeiden kohteiden scrapaukseen. Se on libcurl-sidos, joka pystyy tekeytymään täsmälleen oikean selaimen TLS-fingerprintiksi. Bright Data selittää: "Walmart käyttää TLS-fingerprintejä osana bottitunnistustaan, eikä pelkkä User-Agentin asettaminen oikeaa selainta jäljittelemään riitä ohittamaan sitä." Tavallinen requests tai httpx ei pääse Akamain ohi riippumatta siitä, mitä headereita asetat. curl_cffi ja impersonate="chrome124" tekevät ratkaisevan eron.

Tarvitset lisäksi json (sisäänrakennettu), csv (sisäänrakennettu), time, random ja logging myöhemmin käsiteltäviä tuotantomalleja varten.

Vaihe vaiheelta: Walmartin tuotesivujen scrapaus Pythonilla

Vaihe 1: Hae Walmartin tuotesivu

Ensimmäinen tehtäväsi on tehdä HTTP-pyyntö, joka ei esty heti. Tässä on kanoninen header-setti, jota Scrapfly, Scrapingdog, Oxylabs ja ScrapeOps käyttävät vuosina 2024–2026:

from curl_cffi import requests

HEADERS = {
    "User-Agent": (
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
        "AppleWebKit/537.36 (KHTML, like Gecko) "
        "Chrome/124.0.0.0 Safari/537.36"
    ),
    "Accept": (
        "text/html,application/xhtml+xml,application/xml;q=0.9,"
        "image/avif,image/webp,*/*;q=0.8"
    ),
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
    "Upgrade-Insecure-Requests": "1",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-User": "?1",
    "Referer": "https://www.google.com/",
}

session = requests.Session(impersonate="chrome124")
url = "https://www.walmart.com/ip/Apple-AirPods-Pro-2nd-Generation/1752657021"
response = session.get(url, headers=HEADERS)

impersonate="chrome124" tekee tässä raskaan työn. Se kertoo curl_cffi:lle, että sen pitää vastata Chrome 124:n tarkkaa TLS ClientHelloa, HTTP/2-kehysten järjestystä ja pseudo-headerien sekvenssiä. Ilman sitä Akamai näkee Python-kohtaisen JA3-hashin ja estää sinut ennen kuin pyyntösi edes saavuttaa Walmartin sovelluskerroksen.

Miltä estetty vastaus näyttää: Jos näet HTML:n otsikossa "Robot or human?" tai jos vastaus ohjautuu walmart.com/blocked-osoitteeseen, sinut on napattu. Hankala osa on se, että Walmart palauttaa usein 200-tilakoodin CAPTCHA-sisällöllä — joten pelkkään response.ok:iin ei voi luottaa.

Kaikessa tuotanto- tai toistuvassa käytössä tarvitset residential proxyja. Datacenter-IP:t palavat heti Akamain IP-reputaatiojärjestelmässä. Käsittelen täyden virheenkäsittelyn ja proxy-strategian tuotanto-osiossa alempana.

Vaihe 2: Parsii tuotedata __NEXT_DATA__-JSONista

Walmart.com on Next.js-sovellus, ja palvelinrenderöity HTML upottaa koko hydration-paketin yhteen script-tagiin: <script id="__NEXT_DATA__" type="application/json">. Tämä on kultasuoni.

Scrapflyn vuoden 2026 opas vahvistaa: "Vuonna 2026 Walmart käyttää Next.js:ää ja rakenteista JSONia __NEXT_DATA__-script-tageissa, mikä tekee piilotetun datan poiminnasta luotettavampaa kuin perinteisestä CSS-selectorien käytöstä." Jokainen tunnettu avoimen lähdekoodin Walmart-scraper — Scrapflyn, Oxylabsin, python-scrapy-playbookin — käyttää tätä menetelmää.

Näin se poimitaan:

import json
from parsel import Selector

sel = Selector(text=response.text)
raw = sel.xpath('//script[@id="__NEXT_DATA__"]/text()').get()
data = json.loads(raw)
product = data["props"]["pageProps"]["initialData"]["data"]["product"]
idml = data["props"]["pageProps"]["initialData"]["data"].get("idml", {})

Useimmat ohjeet pysähtyvät tähän. Alla on täydellinen JSON-polkujen kartta niille kentille, joista oikeasti välität — varmennettu live Walmart-sivuilla vuosina 2024–2026:

TietokenttäJSON-polku (initialData-kohdan alla)TyyppiHuomautukset
Tuotteen nimidata > product > nameMerkkijono
Tuotemerkkidata > product > brandMerkkijono
Nykyinen hinta (numero)data > product > priceInfo > currentPrice > priceLiukulukuVoi vaihdella kauppakansion keksin mukaan
Nykyinen hinta (merkkijono)data > product > priceInfo > currentPrice > priceStringMerkkijonoMuotoiltu esim. "$9.99"
Lyhyt kuvausdata > product > shortDescriptionHTML-merkkijonoParsittava BeautifulSoupilla tekstiksi
Pitkä kuvausdata > idml > longDescriptionHTML-merkkijonoSijaitsee idml:ssä, EI product-kohdan sisällä — tämä on ansa, jonka vanhemmat ohjeet menevät väärin
Kaikki kuvatdata > product > imageInfo > allImagesTaulukkoLista {id, url}-olioista
Keskimääräinen arvosanadata > product > averageRatingLiukulukuAvain on averageRating, ei vanha rating
Arvostelujen määrädata > product > numberOfReviewsKokonaisluku
Variantitdata > product > variantCriteriaTaulukkoVaihtoehtoryhmät (koko, väri)
Saatavuusdata > product > availabilityStatusMerkkijonoIN_STOCK, OUT_OF_STOCK, LIMITED_STOCK
Myyjädata > product > sellerDisplayNameMerkkijono
Valmistajadata > product > manufacturerNameMerkkijono

longDescription-polku on se ansa, johon ihmiset kompastuvat. Vuoden 2023 ScrapeHero-viesti sijoitti sen product.longDescription-polkuun, mutta vuoden 2024+ lähteet asettavat sen johdonmukaisesti sisaravaimeen idml. Lue aina ensin idml.longDescription ja varaa varalle product.longDescription vanhempia sivuja varten.

Tässä turvallinen poimintamalli .get()-ketjuilla:

def extract_product(data):
    product = data["props"]["pageProps"]["initialData"]["data"]["product"]
    idml = data["props"]["pageProps"]["initialData"]["data"].get("idml", {})

    price_info = product.get("priceInfo", {})
    current_price = price_info.get("currentPrice", {})
    image_info = product.get("imageInfo", {})

    return {
        "name": product.get("name"),
        "brand": product.get("brand"),
        "price": current_price.get("price"),
        "price_string": current_price.get("priceString"),
        "short_desc": product.get("shortDescription"),
        "long_desc": idml.get("longDescription", product.get("longDescription")),
        "images": [img.get("url") for img in image_info.get("allImages", [])],
        "rating": product.get("averageRating"),
        "review_count": product.get("numberOfReviews"),
        "variants": product.get("variantCriteria"),
        "availability": product.get("availabilityStatus"),
        "seller": product.get("sellerDisplayName"),
        "manufacturer": product.get("manufacturerName"),
    }

Niille käyttäjille, jotka eivät halua lainkaan käsitellä JSON-polkuja, Thunderbitin AI tunnistaa ja jäsentää nämä kentät automaattisesti — ei manuaalista polkukartoitusta. Klikkaat "AI Suggest Fields", se lukee sivun ja saat taulukon. Mutta jos rakennat omaa putkea, yllä oleva kartta on referenssisi.

Vaihe 3: Sieppaa Walmartin sisäiset API-päätepisteet rikkaampaa dataa varten

Mikään kilpailija-artikkeli ei käsittele tätä menetelmää kunnolla. Se on tehokkain poimintareitti — ja monimutkaisin.

Walmartin etupää kutsuu federoitua GraphQL-taustajärjestelmää, joka perustuu Apollo Gatewayyn. Päätepisteet sijaitsevat polussa www.walmart.com/orchestra/*:

  • /orchestra/pdp/graphql/... — tuotesivun hydration + varianttivaihdot
  • /orchestra/snb/graphql/... — haku- ja selaussivujen sivutus
  • /orchestra/reviews/graphql/... — sivutetut arvostelut

Nämä palauttavat siistiä, rakenteista JSONia, jossa on dataa, jota __NEXT_DATA__ joskus typistää — varianttikohtainen hinnoittelu, reaaliaikaiset varastomäärät, täysi arvostelujen sivutus.

Se koukku, jota blogikirjoitukset kiertävät: Walmart käyttää Apollon persisted queryjä. Pyyntöbody lähettää vain SHA-256-hashin (persistedQuery.sha256Hash), ei itse query-tekstiä. Jos hashia ei tunnisteta palvelimella, saat virheen PersistedQueryNotFound. Walmart kierrättää nämä hashit deployn yhteydessä. Siksi mikään tunnettu avoimen lähdekoodin Walmart-scraper ei julkaise suoraan kopioitavaa /orchestra/-koodia.

Käytännöllinen ja rehellinen versio tästä menetelmästä on DevTools-harjoitus:

  1. Avaa Walmartin tuotesivu Chromessa
  2. Avaa DevTools → Network-välilehti ja suodata "Fetch/XHR"
  3. Selaa sivua normaalisti — klikkaa variantteja, vieritä arvosteluihin, vaihda kauppasijaintia
  4. Etsi pyyntöjä /orchestra/*-päätepisteisiin, jotka palauttavat JSONia tuotedatan kanssa
  5. Klikkaa pyynnön päällä oikealla → "Copy as cURL"
  6. Muunna cURL-komento Pythoniksi curl_cffi:n avulla

Näin uudelleenajettu API-kutsu näyttää:

import json
from curl_cffi import requests

session = requests.Session(impersonate="chrome124")

# Ensin lämmitä sessio vierailemalla tuotesivulla
session.get("https://www.walmart.com/ip/some-product/1234567", headers=HEADERS)

# Sitten toista sisäinen API-kutsu (kopioitu DevToolsista)
api_url = "https://www.walmart.com/orchestra/pdp/graphql"
api_headers = {
    **HEADERS,
    "accept": "application/json",
    "content-type": "application/json",
    "referer": "https://www.walmart.com/ip/some-product/1234567",
    "wm_qos.correlation_id": "your-copied-correlation-id",
}
payload = {
    # Liitä tarkka request body DevToolsista
    "variables": {"productId": "1234567"},
    "extensions": {
        "persistedQuery": {
            "version": 1,
            "sha256Hash": "the-hash-you-copied"
        }
    }
}

api_response = session.post(api_url, headers=api_headers, json=payload)
api_data = api_response.json()

Sessioiden lämmitys on kriittistä. Walmartin PerimeterX-keksit (_px3, _pxhd, ACID) täytyy asettaa alkuperäisen HTML-haun kautta ennen kuin API-kutsu onnistuu. Ilman niitä saat 412- tai 403-vastauksen.

Milloin tätä menetelmää kannattaa käyttää: Kun tarvitset dataa, jota __NEXT_DATA__ ei sisällä — syvät varianttihinnat, ensimmäistä batchia pidemmälle sivutetut arvostelut tai reaaliaikaiset varastomäärät. Useimpiin käyttötarkoituksiin __NEXT_DATA__ riittää ja on paljon yksinkertaisempi.

Walmartin hakutulosten ja useiden sivujen scrapaus

Hakutulokset noudattavat samantyyppistä __NEXT_DATA__-mallia, mutta eri JSON-polulla:

search_url = "https://www.walmart.com/search?q=laptops&page=1"
response = session.get(search_url, headers=HEADERS)

sel = Selector(text=response.text)
raw = sel.xpath('//script[@id="__NEXT_DATA__"]/text()').get()
data = json.loads(raw)

search_result = data["props"]["pageProps"]["initialData"]["searchResult"]
items = search_result["itemStacks"][0]["items"]

# Suodata sponsoroidut tuotteet pois
organic_items = [i for i in items if i.get("__typename") == "Product"]

for item in organic_items:
    print(item.get("name"), item.get("priceInfo", {}).get("currentPrice", {}).get("price"))

Sivutus toimii kasvattamalla page-parametria: &page=1, &page=2 ja niin edelleen. Mutta tässä on dokumentoimaton rajoitus: Walmart rajoittaa hakutulokset 25 sivuun riippumatta todellisesta kokonaismäärästä. Scrapfly vahvistaa: "Walmart asettaa enimmäismääräksi 25 sivua riippumatta saatavilla olevien sivujen kokonaismäärästä."

Keinoja päästä syvemmälle:

  • Järjestyksen vaihtelu: Aja sama haku &sort=price_low ja sitten &sort=price_high, jolloin saat noin 50 sivua kattavuutta
  • Hintahaarukan pilkkominen: Lisää &min_price=X&max_price=Y jakamaan katalogi pienempiin ikkunoihin
  • Kategoriapilkkuminen: Hae tietyistä kategorioista sivuston laajuisen haun sijaan

Huomaa, että itemStacks on taulukko. Scrapfly kovakoodaa [0]:n repossaan, mutta kategoria- ja selaussivuilla on joskus useita pinoja ("Top picks", "More results"). Kestävä malli käy läpi kaikki pinot:

for stack in search_result.get("itemStacks", []):
    for item in stack.get("items", []):
        if item.get("__typename") == "Product":
            # käsittele item
            pass

Maininnan arvoista on myös, että Walmartin robots.txt kieltää polun /search. Tuotesivut (/ip/...) ja useimmat kategoriat (/cp/...) eivät ole kiellettyjä. Jos huolettaa yhteensopivuus, aloita tuotesivuista ja kategoriapuusta hakusivujen sijaan.

Älä anna hiljaisten estojen pilata dataasi: tuotantokelpoinen virheenkäsittely

Useimmat ohjeet kaatuvat tähän. Ne näyttävät, miten haetaan yksi sivu, parsitaan yksi tuote ja lopetetaan siihen. Tuotannossa haet tuhansia sivuja, ja Walmart yrittää aktiivisesti estää sinua. Demon ja oikeasti toimivan scraperin ero on siinä, miten se käsittelee epäonnistumisia.

Tunnista hiljaiset estot ennen kuin ne pilaavat datasi

Yksittäisen Walmart-scraperin tärkein funktio on estoilmaisin. Vendorien yhteisen näkemyksen perusteella ScrapingBee, Scrapingdog, Oxylabs ja Decodo mukaan tarvitset neljä erillistä tarkistusta:

BLOCK_MARKERS = (
    "Robot or human",
    "Press &amp; Hold",
    "Press & Hold",
    "px-captcha",
    "perimeterx",
)

def is_walmart_blocked(response) -> bool:
    # 1. Uudelleenohjaus erilliseen estopäätepisteeseen
    if "/blocked" in str(response.url):
        return True
    # 2. Kovat tilakoodit
    if response.status_code in (403, 412, 428, 429, 503):
        return True
    # 3. 200 OK CAPTCHA-sisällöllä (hiljainen esto)
    body = response.text or ""
    if any(m.lower() in body.lower() for m in BLOCK_MARKERS):
        return True
    # 4. Vastauksen pituuden järkevyys — oikeat PDP-sivut ovat 300–900 KB
    if len(response.content) < 50_000 and "/ip/" in str(response.url):
        return True
    return False

Tuo neljäs tarkistus — vastauksen pituus — nappaa tapaukset, joissa Walmart palauttaa riisityn sivun, joka ei sisällä ilmeisiä CAPTCHA-merkkejä mutta ei myöskään tarvitsemaasi tuotetietoa.

Uusintayritykset eksponentiaalisella backoffilla ja jitterillä

Kun pyyntö epäonnistuu, et halua hakata Walmartia heti uudelleen. Vakiomalli käyttää eksponentiaalista backoffia ja jitteriä, jotta uusintayritykset eivät synkronoidu:

import time
import random
import logging
from curl_cffi import requests as cffi_requests

log = logging.getLogger("walmart")

def fetch_with_retry(session, url, max_retries=5, base_delay=2, max_delay=60):
    for attempt in range(max_retries):
        try:
            response = session.get(url, headers=HEADERS, timeout=15)

            if response.status_code in (429, 503):
                raise Exception(f"Throttled: {response.status_code}")

            if is_walmart_blocked(response):
                raise Exception("Hiljainen esto havaittu")

            return response

        except Exception as e:
            if attempt == max_retries - 1:
                raise

            wait = min(max_delay, base_delay * (2 ** attempt)) + random.uniform(0, 3)
            log.warning(f"Yritys {attempt + 1} epäonnistui: {e}. Uusitaan {wait:.1f} s kuluttua")
            time.sleep(wait)

    return None

Jitter (random.uniform(0, 3)) ei ole kosmeettinen yksityiskohta — se hajauttaa workerit niin, ettei scraper-laivue yritä uudestaan samana sekuntina ja laukaise Akamain nopeusdetektoreita.

Nopeusrajoitus

Sekä Thunderbit että Scrape.do päätyvät Walmartille 3–6 sekunnin satunnaiseen viiveeseen pyyntöä kohden: "rajoita pyyntöjä odottamalla 3–6 sekuntia sivulatausten välillä ja satunnaistamalla viiveet."

import time
import random

def rate_limited_fetch(session, url):
    response = fetch_with_retry(session, url)
    time.sleep(random.uniform(3.0, 6.0))
    return response

Mittakaavassa kannattaa harkita aiolimiter-kirjastoa async-nopeusrajoitukseen:

from aiolimiter import AsyncLimiter
limiter = AsyncLimiter(max_rate=10, time_period=60)  # 10 pyyntöä minuutissa

Datan validointi

Vaikka vastaus ei olisi estetty, parsittu data voi silti olla väärää (väärä kauppa, heikentynyt payload). Vahvista ennen ulostuloon kirjoittamista:

def validate_product(product):
    """Palauttaa True, jos tuotedata näyttää aidolta."""
    if not product.get("name"):
        return False

    price = (product.get("priceInfo") or {}).get("currentPrice", {}).get("price")
    if not isinstance(price, (int, float)) or price <= 0:
        return False

    if product.get("availabilityStatus") not in ("IN_STOCK", "OUT_OF_STOCK", "LIMITED_STOCK"):
        return False

    return True

Sessiolokitus

Seuraa onnistumisastetta sessiokohtaisesti. Kun se laskee alle 80 %:n 10 minuutin ajaksi, jokin on muuttunut — joko IP:si on palanut, keksit ovat vanhentuneet tai Walmart on ottanut käyttöön uuden anti-bot-säännön.

class ScrapeMetrics:
    def __init__(self):
        self.total = 0
        self.success = 0
        self.blocks = 0
        self.errors = 0

    def record(self, result):
        self.total += 1
        if result == "success":
            self.success += 1
        elif result == "blocked":
            self.blocks += 1
        else:
            self.errors += 1

    @property
    def success_rate(self):
        return (self.success / self.total * 100) if self.total > 0 else 0

    def check_health(self):
        if self.total > 20 and self.success_rate < 80:
            log.critical(f"Onnistumisaste putosi {self.success_rate:.1f} %:iin — harkitse proxyjen vaihtamista tai taukoa")

Ei mikään hohdokas osa. Mutta se pitää datasi siistinä.

DIY-Python vs. scraping API vs. no-code: oikean lähestymistavan valinta Walmartin scrapaukseen

Moni kehittäjä hyppää suoraan oman scraperin kirjoittamiseen kysymättä, onko se oikea valinta. ScrapeOps arvioi Walmartin vaikeusasteeksi 9/10. Foorumikäyttäjät kuvaavat sitä "käytännössä 9/10:ksi" ja pohtivat, olisiko "erillinen web scraping API jo liioittelua". Vastaus riippuu volyymista, budjetista ja teknisestä kapasiteetista.

TekijäDIY Python (requests + proxyt)Scraping API (Oxylabs, Bright Data jne.)No-code-työkalu (Thunderbit)
Aika ensimmäiseen riviinTunteja15–60 minNoin 2 min
Aika tuotantoon40–80 h4–16 hNoin 30 min
Anti-bot-käsittelySinä hoidat (vaikea)Palveluntarjoaja hoitaaHoituu automaattisesti
Kustannus pienessä mittakaavassa (<1K sivua/kk)Matala (proxykustannukset noin 4–8 $/GB)40–49 $/kk aloitustasotIlmainen–15 $/kk
Kustannus mittakaavassa (100K+ sivua/kk)Halvempi per pyyntöKalliimpi per pyyntöVaihtelee
MukautettavuusTäysi hallintaAPI-parametritRajattu UI:n/kenttien mukaan
Jatkuva ylläpito4–8 h/kkLähes nollaEi lainkaan (AI mukautuu)
Paras käyttäjäKehittäjät, jotka rakentavat omia putkiaanKeskisuuri tuotantokaava scrapingLiiketoimintakäyttäjät, nopea kertapoiminta

Milloin DIY Python on järkevä valinta

DIY voittaa, kun omistat jo proxy-sopimuksen, tarvitset tiukkaa hallintaa headereista, postinumerokohdistuksesta tai myyjäryhmistä, indeksoit miljoonia sivuja kuukaudessa, jolloin API-maksut alkavat kasautua, tai tarvitset on-prem-/compliance-takuita. Kompromissi on todellinen suunnitteluaika: tuotantokelpoinen Scrapy-hämähäkki sivutuksella, uudelleenyrittyksillä, proxy-kierrätyksellä, TLS-imitaatiolla ja useilla sivutyyppiskaavoilla vie 40–80 tuntia kokeneen Python-kehittäjän työtä, sekä 4–8 tuntia kuukaudessa ylläpitoa, kun Walmart kierrättää fingerprinttejä.

Milloin scraping API säästää aikaasi

Scraping API:t hoitavat anti-bot-kerroksen puolestasi. ScrapeOpsin benchmarkit näyttävät 99 % onnistumisasteen Zyte API:lle ja 98 %:n Scrape.do:lle Walmartissa. Aloitustason hinnoittelu on 40–49 $/kk työkaluissa kuten ScraperAPI, Oxylabs ja Scrapingdog. Jos olet 2–5 hengen tiimi ja scraping-volyymisi on 10K–1M sivua kuukaudessa, API on lähes aina oikea valinta. Vaihdat per-pyyntö-kustannuksen nollaylläpitoon.

Milloin no-code on oikea valinta

Thunderbit sopii aivan erilaiseen profiiliin. Jos olet PM, analyytikko tai verkkokaupan tekijä ja tarvitset Walmartin tuotetiedot taulukkoon jo tänä iltapäivänä — et seuraavassa sprintissä — no-code-työkalu on rehellinen vastaus.

Työskentelytapa: asenna Thunderbit Chrome -laajennus, siirry Walmartin tuote- tai hakusivulle, klikkaa "AI Suggest Fields", ja Thunderbitin AI lukee sivun ja ehdottaa sarakkeita (tuotteen nimi, hinta, arvosana jne.). Klikkaa "Scrape", ja data täyttyy taulukkoon. Vie Exceliin, Google Sheetsiin, Airtableen tai Notioniin — kaikki ilmaiseksi, ilman paywallia.

Thunderbit hoitaa anti-botin pilvessä, joten et joudu taistelemaan CAPTCHAn, proxyjen tai TLS-fingerprinttien kanssa. AI mukautuu automaattisesti ulkoasun muutoksiin, joten ylläpitoa ei ole. Käyttäjille, jotka eivät halua käsitellä JSON-polkuja lainkaan, tämä on vähiten kitkaa aiheuttava reitti.

Rehelliset rajoitukset: Thunderbit ei ole rakennettu 100K+ sivuun päivässä. Credit-budjetit ja pilvirajat tekevät erittäin suurivolyymisestä ingestistä taloudellisesti huonomman vaihtoehdon kuin raaka API. Et myöskään voi lukita tiettyä postinumeroa tai ASN:ää, ellei työkalu tue sitä. Jatkuviin, suurivolyymisiin putkiin DIY tai scraping API on yhä parempi valinta.

Karkea hinnoittelu: 1 000 Walmartin tuoteriviä Thunderbitissä maksaa noin 2 000 creditiä (noin 0,60–1,10 $ Starter/Pro-suunnitelmilla). Se on samaa luokkaa kuin Oxylabsin Walmart API ja halvempi kuin useimmat harrastetason scraping API:t pienellä volyymilla. Tarkista Thunderbitin hinnoittelu ajantasaiset tiedot.

Scrapaa Walmartin tuotetiedot AI:lla Get Started Free

Scrapatun Walmart-datan vienti

Kun data on kasassa, tarvitset sille käyttökelpoisen paikan. Kolme formaattia kattaa useimmat tarpeet:

CSV — vähimmäisformaatti, jonka analyytikot oikeasti avaavat:

import csv

def export_csv(products, filename="walmart_products.csv"):
    fieldnames = ["name", "price", "availability", "rating", "review_count", "seller", "url"]
    with open(filename, "w", newline="", encoding="utf-8-sig") as f:
        writer = csv.DictWriter(f, fieldnames=fieldnames, quoting=csv.QUOTE_MINIMAL)
        writer.writeheader()
        for p in products:
            writer.writerow({k: p.get(k) for k in fieldnames})

Käytä utf-8-sig-koodausta Excel-yhteensopivuuden vuoksi. BOM-merkki estää Exceliä sotkemasta erikoismerkkejä.

JSONL — tuotantomuoto scraping-putkille:

import json
import gzip

def export_jsonl(products, filename="walmart_products.jsonl.gz"):
    with gzip.open(filename, "at", encoding="utf-8") as f:
        for p in products:
            f.write(json.dumps(p, ensure_ascii=False) + "\n")

JSONL on kaatumisturvallinen (keskeytynyt kirjoitus hukkaa vain viimeisen rivin), se on streamattavissa vakion muistinkäytön kanssa ja säilyttää sisäkkäisen datan kuten variantit ja arvostelut.

Excel — kertaluonteiseen analyytikkoluovutukseen:

from openpyxl import Workbook

def export_excel(products, filename="walmart_products.xlsx"):
    wb = Workbook(write_only=True)
    ws = wb.create_sheet("Products")
    ws.append(["Nimi", "Hinta", "Saatavuus", "Arvosana", "Arvostelut", "Myyjä"])
    for p in products:
        ws.append([p.get("name"), p.get("price"), p.get("availability"),
                    p.get("rating"), p.get("review_count"), p.get("seller")])
    wb.save(filename)

Thunderbit kattaa vientitarpeen myös muille kuin Python-käyttäjille: yhden klikkauksen vienti Google Sheetiin, Airtableen, Notioniin, Exceliin, CSV:ksi ja JSONiksi — kaikki ilmaiseksi perustasolla. Jatkuvaan seurantaan Thunderbitin scheduled scraper -ominaisuus voi ajaa toistuvat poiminnat automaattisesti.

Yksi ajoitukseen liittyvä huomio: älä käytä GitHub Actionsia Walmart-scrapaukseen. GitHub Actionsin ajurit sijaitsevat Azure-IP-alueilla, jotka Walmartin anti-bot estää heti. Käytä APScheduleria VPS:llä tai reititä koko liikenne residential-proxyjen kautta.

Walmartin scrapauksen lailliset ja eettiset ohjeet

Foorumikäyttäjät ilmaisevat tämän huolen suoraan: "Minulle sopii kehittäjien kanssa hiirikissa ja -hiiri -leikki, mutta juristitiimin kanssa leikkiminen vähän arveluttaa."

Walmartin käyttöehdot kieltävät nimenomaisesti käyttämästä "mitään robottia, spideriä… tai muuta manuaalista tai automaattista välinettä Materialsin hakemiseen, indeksointiin, 'scrappaamiseen', 'data miningiin' tai muuten keräämiseen" ilman "ennalta annettua kirjallista lupaa".

Walmartin robots.txt kieltää polut /search, /account, /api/ sekä kymmeniä sisäisiä päätepisteitä. Tuotesivut (/ip/...) ja arvostelut (/reviews/product/) eivät ole kiellettyjä.

hiQ v. LinkedIn -ennakkotapaus (9. piiri, 2022) vahvisti, että julkisesti saatavilla olevan datan scraping ei todennäköisesti riko liittovaltion CFAA-lakia. Mutta sama tuomioistuin totesi myöhemmin, että hiQ rikkoi LinkedInin käyttöehtoja ja määräsi sitä vastaan 500 000 dollarin sovintosumman. Tuoreemmat vuoden 2024 päätökset (Meta v. Bright Data, X Corp. v. Bright Data) rajasivat CFAA:n soveltamista edelleen ja loivat tekijänoikeuden etusijaan liittyviä puolustuksia, mutta nuo ratkaisut perustuivat hyvin tietynlaiseen ToU-tekstiin, joka ei siirry suoraviivaisesti Walmartiin.

Käytännön ohjeet: Älä kuormita palvelimia liikaa. Noudata nopeusrajoja. Älä scrapea henkilö- tai käyttäjätietoja. Käytä dataa vastuullisesti. Julkisten Walmartin tuotesivujen scrapaus kohtuullisella tahdilla henkilökohtaista tutkimusta varten on aivan eri riskiluokassa kuin kaupallinen scraping Walmartin ehtoja vastaan. Jos rakennat tuotetta Walmart-datan varaan, keskustele lakimiehen kanssa ja selvitä Walmartin viralliset affiliate- ja seller API:t.

Vastuuvapauslauseke: Tämä on opetuksellista tietoa, ei oikeudellista neuvontaa.

Johtopäätös ja tärkeimmät opit

Walmartin scrapaus Pythonilla on 9/10-vaikeustason haaste sen kaksois-anti-bot-kerroksen, Akamain ja PerimeterX:n, vuoksi. Ei mahdotonta — mutta tarvitset oikeat työkalut ja mallipohjat.

Tärkeimmät opit:

  • __NEXT_DATA__-JSONin poiminta on käytännöllisin vaihtoehto useimpiin käyttötarkoituksiin. Sitä käyttävät kaikki vakavasti otettavat vuosien 2024–2026 avoimen lähdekoodin Walmart-scraperit. Peruspolku on props.pageProps.initialData.data.product PDP-sivuille ja searchResult.itemStacks haku-/selaussivuille.
  • curl_cffi ja impersonate="chrome124" ovat pakollisia. Tavallinen requests tai httpx ei pääse Akamain TLS-fingerprinttien ohi headereista riippumatta.
  • Hiljaiset estot ovat todellinen vaara. Walmart palauttaa 200 OK -vastauksia CAPTCHA-sisällöllä. Tarkista vastauksen sisältö, älä vain tilakoodeja.
  • Tuotantocrappaajat tarvitsevat enemmän kuin onnellisen polun koodin. Eksponentiaalinen backoff jitterillä, neljän signaalin estoilmaisu, 3–6 sekunnin nopeusrajoitus per pyyntö, datan validointi ja session kunnon seuranta ovat kaikki olennaisia.
  • Sisäisten API-pyyntöjen sieppaus /orchestra/*-reitillä on tehokasta mutta haurasta. Käytä sitä DevTools-harjoituksena tiettyihin datatarpeisiin, älä ensisijaisena poimintamenetelmänä.
  • Walmart rajoittaa hakutulokset 25 sivuun. Mene laajemmaksi vaihtamalla järjestystä ja pilkkomalla hinta-alueita.
  • Valitse lähestymistapa rehellisesti: DIY Python kehittäjille, joilla on omat tarpeet ja suuri volyymi. Scraping API:t keskikokoisille tiimeille ilman scraping-insinööriä. Thunderbit liiketoimintakäyttäjille, jotka haluavat datan Google Sheetiin jo tänä iltapäivänä.

Jos haluat kokeilla no-code-reittiä, Thunderbit Chrome -laajennuksella on ilmainen taso — voit scrapata muutaman Walmart-sivun ja nähdä tulokset itse. Jos olet menossa Python-reittiä, tämän artikkelin koodimallit on testattu tuotannossa. Kummalla tahansa tavalla sinulla on nyt kartta Walmartin puolustuksista ja kolme polkua niiden läpi.

Lisää web scraping -tekniikoista löydät oppaistamme kuinka tehdä web scraping Pythonilla, parhaat automaattiset web scraping -työkalut ja web scraping ilman estoa. Voit katsoa myös opetusvideoita Thunderbit YouTube -kanavalta.

UKK

Onko Walmartin tuotetietojen scrapaus laillista?

Walmartin käyttöehdot kieltävät automaattisen scrapauksen ilman kirjallista lupaa. 9. piirin hiQ v. LinkedIn -päätös (2022) totesi, että liittovaltion CFAA ei todennäköisesti sovellu julkisten sivujen scrapaukseen, mutta sama tapaus päättyi 500 000 dollarin sopimusrikkomustuomioon scrapaajaa vastaan. Julkisten tuotesivujen scrapauksella kohtuullisella tahdilla henkilökohtaista tutkimusta varten on hyvin erilainen riskiprofiili kuin kaupallisella mittakaavalla tehdyllä poiminnalla. Kysy lakimieheltä, jos rakennat liiketoimintaa Walmart-datan varaan.

Miksi Walmart-scraperini estetään jatkuvasti?

Yleisimmät syyt ovat: tavallisen requests- tai httpx-kirjaston käyttö (joka tuottaa Python-kohtaisen TLS-fingerprintin, jonka Akamai liputtaa heti), puuttuvat tai virheelliset headerit, proxy-kierrätyksen puute, pyyntötahdit nopeampina kuin 3–6 sekuntia sivua kohden sekä puuttuvat session keksit (_px3, _abck, locDataV3). Vaihda curl_cffi-kirjastoon ja käytä impersonate="chrome124", hyödynnä residential proxyja ja ota käyttöön tämän artikkelin kuvaamat esto- ja uudelleenyrittämismallit.

Mitä dataa voin scrapata Walmartista Pythonilla?

Tuotteiden nimet, hinnat (nykyiset ja rollback-hinnat), kuvat, lyhyet ja pitkät kuvaukset, arvosanat, arvostelujen määrät, varastosaatavuus, myyjien nimet, valmistajatiedot, varianttivaihtoehdot (koko, väri) ja kategoriasijoitus. __NEXT_DATA__-menetelmällä kaikki nämä ovat saatavilla rakenteisena JSONina. Sisäisten API-pyyntöjen sieppaus voi lisäksi palauttaa varianttikohtaisen hinnoittelun, reaaliaikaiset varastomäärät ja sivutetut arvostelutiedot.

Tarvitsenko proxyt Walmartin scrapaukseen?

Kyllä, tuotanto- tai toistuvassa käytössä. Walmartin anti-bot-järjestelmät estävät tavalliset pyynnöt johdonmukaisesti — vaikka headerit olisivat täydelliset, ei-residential-IP liputetaan Akamain IP-reputaatiojärjestelmässä. Residential- tai mobile-proxyja tarvitaan. Datacenter-IP:t palavat lähes välittömästi. Budjetoi suunnilleen 3–17 dollaria per 1 000 sivua proxy-palveluntarjoajasta ja tasosta riippuen.

Voinko scrapata Walmartia kirjoittamatta koodia?

Kyllä. Thunderbit on AI-pohjainen Chrome-laajennus, joka scrapaa Walmartin kahdella klikkauksella: "AI Suggest Fields" tunnistaa tuotedatasarakkeet automaattisesti, ja "Scrape" poimii datan. Se hoitaa anti-bot-haasteet pilvessä ja vie tiedot suoraan Exceliin, Google Sheetiin, Airtableen tai Notioniin — kaikki ilmaiseksi. Se sopii parhaiten analyytikoille, PM:ille ja liiketoimintakäyttäjille, jotka tarvitsevat dataa nopeasti ilman oman putken rakentamista. Suurivolyymiseen tai vahvasti räätälöityyn scrapaukseen Python tai scraping API on yhä parempi vaihtoehto.

Kokeile Thunderbitiä AI-Walmart-scrapaukseen Get Started Free

Lisää tietoa

Shuai Guan
Shuai Guan
Thunderbitin toimitusjohtaja | AI:n ja tiedon automaation asiantuntija Shuai Guan on Thunderbitin toimitusjohtaja ja Michiganin yliopiston insinööritieteiden alumni. Lähes kymmenen vuoden kokemuksella teknologian ja SaaS-arkkitehtuurin parissa hän on erikoistunut muuttamaan monimutkaiset tekoälymallit käytännöllisiksi, koodittomiksi tiedon poimintatyökaluiksi. Tässä blogissa hän jakaa suodattamattomia, kentällä koeteltuja näkemyksiä verkkosivujen datan keruusta ja automaatiostrategioista, jotta voit rakentaa älykkäämpiä, dataohjautuvia työnkulkuja. Kun hän ei optimoi tietotyönkulkuja, hän hyödyntää samaa tarkkuutta myös valokuvauksen parissa.
Sisällysluettelo

Poimi verkkosivu pelkällä pyynnöllä

Kerro mitä tarvitset selkeällä englannilla. Tai vielä parempaa, älä kerro mitään.

Kokeile Thunderbitiä ilmaista
Poimi dataa AI:n avulla
Siirrä data helposti Google Sheetiin, Airtableen tai Notioniin
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week