PythonでWalmartをスクレイピングする方法(ブロックされないためのコツ付き)

最終更新日 April 15, 2026

Walmartは、一部商品の価格を変えます。これをプログラムで追いかけようとしたことがあるなら、そのしんどさはきっと分かるはずです。スクリプトが20分くらいは普通に動いていたのに、気づいたら200 OKのレスポンスに見せかけたCAPTCHAページを返し始める、なんてことも珍しくありません。

私はでデータ抽出の仕事をする中で、Walmartのボット対策とかなり向き合ってきました。このガイドでは、2025年時点で本当に使えるやり方、気づかないうちにデータを壊してしまう失敗パターン、そして自作スクレイパー・スクレイピングAPI・ノーコードツールの現実的な使い分けまで、学んだことをまとめて全部共有します。ここでは、3つの抽出方法(HTML解析、__NEXT_DATA__ JSON、内部APIの取得)に加えて、多くのチュートリアルが省いてしまう本番向けのエラーハンドリング、さらに自分に合った方法を選ぶための判断軸まで解説します。Pythonを書く人にも、昼までに価格一覧をスプレッドシートで欲しい人にも役立つ内容です。

なぜPythonでWalmartをスクレイピングするのか?

Walmartは売上高ベースで世界最大級の小売企業で、FY2025の売上はに達し、を守っています。サイト上にはおよそがあり、WalmartのCFOはマーケットプレイス上のにも触れています。さらに、そのなので、カタログの動きがかなり激しく、販売者の入れ替わり、バリエーション変更、在庫変動が毎日のように起こります。

walmart_stats_670d06c6bd.png

この変動こそ、スクレイピングが大事になる理由です。四半期レポートだけでは、毎晩のスクレイピングでしか拾えない変化は取りこぼします。よくある用途は次のとおりです。

ユースケース必要とする人抽出する情報
競合価格のモニタリングEC運用担当、価格改定ツール価格、プロモーション、MAP遵守状況
商品カタログの補完営業・販促チーム説明文、画像、仕様、バリエーション
在庫状況の追跡サプライチェーン担当、ドロップシッパー在庫状態、販売者情報
市場調査・トレンド分析マーケティング、プロダクトマネージャー評価、レビュー、カテゴリ構成
リード獲得営業チーム販売者名、商品数、カテゴリ

競合価格モニタリングソフトだけでも、市場規模は2025年にに達し、2033年には50.9億ドルまで伸びると予測されています。消費者行動もこの投資を後押ししていて、うえ、83%が複数サイトをまたいで比較検討しています。

この分野ではPythonがほぼ標準です。Apifyの2026年版Infrastructure Reportでは、とされ、主要ライブラリのrequestsがあります。ある程度まとまった規模でスクレイピングするなら、まずPythonを使うケースが多いでしょう。

Walmartがスクレイピングしづらい理由

Walmartが特に厄介なのは、2種類の商用ボット対策を直列で使っているからです。エッジ側のWAFとTLSフィンガープリント層としてがあり、その後ろで挙動ベースのJavaScriptチャレンジ層としてが動きます。Scrape.doはこの組み合わせを「かなり珍しく、極めて回避しづらい」と表現しています。

walmart_antibot_3d67d0119c.png

しており、Akamai単体でも9/10です。実際の体感でも、だいたいその通りです。

実際に相手にしているのは、次のような仕組みです。

Akamai Bot Manager はTLSフィンガープリント(JA3/JA4ハッシュ)、HTTP/2フレームの並び、ヘッダーの順序や大文字小文字、セッションCookie(_abckak_bmsc)をチェックします。素のPython requests は、本物のブラウザでは出ないTLSフィンガープリントを送るため、Walmartのサーバーに届く前にAkamai側で止められます。

PerimeterX/HUMAN はAkamaiの後段で動き、px.jsによるJavaScriptフィンガープリントを実行して、navigatorのプロパティ、canvas描画、WebGL、audio context、さらにマウス移動・スクロール速度・キー入力の癖といった行動生体情報まで見ています。目に見えて分かる失敗例が、悪名高いです。だいたい10秒ボタンを押し続け、その間に行動シグナルを取られます。Oxylabsもかなり率直に、「WalmartはPerimeterX提供の『Press & Hold』型CAPTCHAを使っており、コードだけで解くのはほぼ無理」と述べています。

本当に厄介なのはサイレントブロックです。Walmartは403ではなくHTTP 200でCAPTCHA本文を返すことがあります。、「WalmartはCAPTCHAページを返していても200 OKを返します。リクエスト成功をステータスコードだけで判断してはいけません。」その結果、スクリプトはCAPTCHAのHTMLを「商品が見つからない」と読み違えて、そのまま処理を続けてしまいます。最悪、データセットの半分が壊れていても気づけません。

さらに、店舗スコープのデータ問題もあります。Walmartの価格や在庫は地域依存で、locDataV3assortmentStoreIdのようなCookieで制御されています。正しいCookieがないと、「全国共通のデフォルト」データが返り、見た目は正しそうでも、実際の表示とはズレます。Cookieが足りない場合はブロックページすら返さず、間違ったデータを静かに返すので、むしろ厄介です。

Walmartからデータを取る3つの方法(比較付き)

手順に入る前に、主要な3つの抽出アプローチを整理しておきます。競合記事の多くは1〜2個しか扱いませんが、ここでは状況に応じて選べるように全部まとめます。

方法信頼性データの完全性ボット対策の難易度保守負荷
HTML + BeautifulSoup⚠️ 低い(デプロイのたびにセレクタが壊れる)中程度高い高い
__NEXT_DATA__ JSON✅ 良い高い中〜高中程度
内部APIの取得✅ 最も良い最高(バリエーション、在庫、レビュー)中〜高低い(構造化JSON)
Thunderbit(ノーコード)✅ 良い高い低い(AIが処理)なし

WalmartではHTML解析がかなりしんどいです。サイトはNext.jsのバンドルを使っていて、ハッシュ化されたCSSクラス名がデプロイのたびに変わります。__NEXT_DATA__ JSON方式は、2024〜2026年の真面目なオープンソースWalmartスクレイパーが採用している、実用性の高い選択肢です。内部APIの取得は最も強力ですが、多くのチュートリアルが省いている落とし穴があります。そして、カスタムパイプラインが不要ならThunderbitがかなり使いやすいです。

Python環境の準備

必要なものは次のとおりです。

  • 難易度: 中級
  • 所要時間: セットアップ約30分 + コーディング時間
  • 必要なもの: Python 3.10以上、pip、コードエディタ、そして本番運用ならプロキシサービスまたはスクレイピングAPI

プロジェクトフォルダと仮想環境を作成します。

1mkdir walmart-scraper && cd walmart-scraper
2python -m venv venv
3source venv/bin/activate  # Windowsの場合: venv\Scripts\Scriptscriptscript activate

必要なライブラリをインストールします。

1pip install curl_cffi parsel beautifulsoup4 lxml

2025年のハードターゲット対策では、curl_cffiが定番です。これはlibcurlのバインディングで、正確なブラウザTLSフィンガープリントを偽装できます。によると、「Walmartはボット検知の一部としてTLSフィンガープリントを使っており、User-Agentを本物っぽく見せるだけでは回避できません。」素のrequestshttpxでは、ヘッダーをどれだけ整えてもAkamaiを通過できません。違いを生むのはimpersonate="chrome124"付きのcurl_cffiです。

あわせて、あとで本番パターンで使うjson(標準ライブラリ)、csv(標準ライブラリ)、timerandomloggingもあると便利です。

PythonでWalmartの商品ページをスクレイピングする手順

ステップ1: Walmartの商品ページを取得する

まず必要なのは、即ブロックされないHTTPリクエストを送ることです。2024〜2026年にScrapfly、Scrapingdog、Oxylabs、ScrapeOpsが共通して使っている定番ヘッダーは次のとおりです。

1from curl_cffi import requests
2HEADERS = {
3    "User-Agent": (
4        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
5        "AppleWebKit/537.36 (KHTML, like Gecko) "
6        "Chrome/124.0.0.0 Safari/537.36"
7    ),
8    "Accept": (
9        "text/html,application/xhtml+xml,application/xml;q=0.9,"
10        "image/avif,image/webp,*/*;q=0.8"
11    ),
12    "Accept-Language": "en-US,en;q=0.9",
13    "Accept-Encoding": "gzip, deflate, br",
14    "Upgrade-Insecure-Requests": "1",
15    "Sec-Fetch-Dest": "document",
16    "Sec-Fetch-Mode": "navigate",
17    "Sec-Fetch-Site": "none",
18    "Sec-Fetch-User": "?1",
19    "Referer": "https://www.google.com/",
20}
21session = requests.Session(impersonate="chrome124")
22url = "https://www.walmart.com/ip/Apple-AirPods-Pro-2nd-Generation/1752657021"
23response = session.get(url, headers=HEADERS)

ここで大きな役割を持つのがimpersonate="chrome124"です。これにより、curl_cffiはChrome 124のTLS ClientHello、HTTP/2フレーム順序、pseudo-headerの並びまで合わせます。これがないと、AkamaiはPython特有のJA3ハッシュを見つけて、Walmartのアプリ層に届く前にブロックします。

ブロックされた応答の見分け方: HTMLタイトルに"Robot or human?"が入っている、またはwalmart.com/blockedへリダイレクトされる場合は、すでに止められています。しかもWalmartは、CAPTCHA本文であっても200ステータスを返すことが多いので、response.okだけを見ても意味がありません。

本番運用や繰り返しの利用では、住宅プロキシが必要です。データセンターIPはAkamaiのIPレピュテーションで即座に焼かれます。完全なエラーハンドリングとプロキシ戦略は、後の本番セクションで説明します。

ステップ2: __NEXT_DATA__ JSONから商品データを解析する

Walmart.comはNext.jsアプリケーションで、サーバー描画されたHTMLの中に、単一のscriptタグ <script id="__NEXT_DATA__" type="application/json"> としてハイドレーション用の完全なペイロードを埋め込んでいます。ここがかなりの宝の山です。

「2026年のWalmartはNext.jsを使っており、__NEXT_DATA__ scriptタグ内の構造化JSONから隠れたデータを取る方法は、従来のCSSセレクタ解析より信頼性が高い」と述べています。有名なオープンソースWalmartスクレイパーも、この方法を使っています。

抽出方法は以下のとおりです。

1import json
2from parsel import Selector
3sel = Selector(text=response.text)
4raw = sel.xpath('//script[@id="__NEXT_DATA__"]/text()').get()
5data = json.loads(raw)
6product = data["props"]["pageProps"]["initialData"]["data"]["product"]
7idml = data["props"]["pageProps"]["initialData"]["data"].get("idml", {})

多くのチュートリアルはここで終わりますが、実際に必要な項目については以下の完全なJSONパス対応表が役立ちます。2024〜2026年のライブWalmartページで確認済みです。

データ項目JSONパス(initialData 配下)備考
商品名data > product > nameString
ブランドdata > product > brandString
現在価格(数値)data > product > priceInfo > currentPrice > priceFloat店舗Cookieによって異なる場合あり
現在価格(文字列)data > product > priceInfo > currentPrice > priceStringString例: "$9.99"
短い説明data > product > shortDescriptionHTML Stringテキスト化するならBeautifulSoupで解析
長い説明data > idml > longDescriptionHTML Stringproduct ではなく idml にある — 古いチュートリアルがよく間違えるポイント
画像一覧data > product > imageInfo > allImagesArray{id, url} の配列
平均評価data > product > averageRatingFloat旧式の rating ではなく averageRating
レビュー数data > product > numberOfReviewsInteger
バリエーションdata > product > variantCriteriaArrayサイズや色などの選択肢
在庫状況data > product > availabilityStatusStringIN_STOCKOUT_OF_STOCKLIMITED_STOCK
販売者data > product > sellerDisplayNameString
製造元data > product > manufacturerNameString

特に注意したいのがlongDescriptionの位置です。2023年のScrapeHero記事ではproduct.longDescriptionとしていましたが、2024年以降のソースでは一貫して兄弟キーのidml側に置かれています。必ず先にidml.longDescriptionを見て、古いページだけproduct.longDescriptionへフォールバックするのが安全です。

.get()をつないで安全に取るなら、こう書けます。

1def extract_product(data):
2    product = data["props"]["pageProps"]["initialData"]["data"]["product"]
3    idml = data["props"]["pageProps"]["initialData"]["data"].get("idml", {})
4    price_info = product.get("priceInfo", {})
5    current_price = price_info.get("currentPrice", {})
6    image_info = product.get("imageInfo", {})
7    return {
8        "name": product.get("name"),
9        "brand": product.get("brand"),
10        "price": current_price.get("price"),
11        "price_string": current_price.get("priceString"),
12        "short_desc": product.get("shortDescription"),
13        "long_desc": idml.get("longDescription", product.get("longDescription")),
14        "images": [img.get("url") for img in image_info.get("allImages", [])],
15        "rating": product.get("averageRating"),
16        "review_count": product.get("numberOfReviews"),
17        "variants": product.get("variantCriteria"),
18        "availability": product.get("availabilityStatus"),
19        "seller": product.get("sellerDisplayName"),
20        "manufacturer": product.get("manufacturerName"),
21    }

JSONパスを自分で追いたくない人には、がページを自動で見分け、これらの項目を構造化してくれます。手動でパスを指定する必要はありません。「AIで項目を提案」をクリックするとページを読み取り、表を作ってくれます。カスタムパイプラインを作るなら、上のマップが基準になります。

ステップ3: Walmartの内部APIエンドポイントを取得して、より豊富なデータを取る

この方法をちゃんと扱っている競合記事はほとんどありません。最も強力ですが、同時に最も複雑な抽出ルートです。

Walmartのフロントエンドは、を呼び出しています。エンドポイントはwww.walmart.com/orchestra/*配下にあります。

  • /orchestra/pdp/graphql/... — 商品詳細のハイドレーションとバリアント切り替え
  • /orchestra/snb/graphql/... — 検索・閲覧のページネーション
  • /orchestra/reviews/graphql/... — ページ分割されたレビュー

これらは、__NEXT_DATA__では取り切れない、よりきれいで構造化されたJSONを返します。たとえば、バリエーションごとの価格、リアルタイム在庫、レビューの全ページなどです。

多くのブログ記事がぼかしている注意点: Walmartはを使っています。リクエスト本文にはクエリ文字列ではなく、SHA-256ハッシュ(persistedQuery.sha256Hash)だけが送られます。このハッシュがサーバー側で知られていないと、PersistedQueryNotFoundになります。しかもWalmartはデプロイ時にこのハッシュを更新します。高名なオープンソースWalmartスクレイパーが/orchestra/コードをそのまま使える形で公開していないのは、このためです。

現実的で正直なやり方は、DevToolsで調べることです。

  1. ChromeでWalmartの商品ページを開く
  2. DevToolsを開き、Networkタブで「Fetch/XHR」に絞る
  3. 普段どおりページを操作する — バリエーションをクリックする、レビューまでスクロールする、店舗を変える
  4. 商品データを返す /orchestra/* へのJSONリクエストを探す
  5. リクエストを右クリックして「Copy as cURL」を選ぶ
  6. そのcURLをcurl_cffiでPythonに移す

APIを再現するコード例は以下です。

1import json
2from curl_cffi import requests
3session = requests.Session(impersonate="chrome124")
4# まず商品ページを開いてセッションを温める
5session.get("https://www.walmart.com/ip/some-product/1234567", headers=HEADERS)
6# その後、DevToolsからコピーした内部API呼び出しを再現する
7api_url = "https://www.walmart.com/orchestra/pdp/graphql"
8api_headers = {
9    **HEADERS,
10    "accept": "application/json",
11    "content-type": "application/json",
12    "referer": "https://www.walmart.com/ip/some-product/1234567",
13    "wm_qos.correlation_id": "コピーしたcorrelation-id",
14}
15payload = {
16    # DevToolsから取得したリクエスト本文をそのまま貼る
17    "variables": {"productId": "1234567"},
18    "extensions": {
19        "persistedQuery": {
20            "version": 1,
21            "sha256Hash": "コピーしたハッシュ"
22        }
23    }
24}
25api_response = session.post(api_url, headers=api_headers, json=payload)
26api_data = api_response.json()

セッションのウォーミングアップはかなり重要です。WalmartのPerimeterX Cookie(_px3_pxhdACID)は、最初のHTML取得でセットされていないとAPIが通りません。これがないと、412や403が返ってきます。

この方法を使うべき場面: __NEXT_DATA__に入っていないデータが必要なとき、たとえばバリエーション別の詳細価格、最初の一括取得を超えるレビューのページネーション、リアルタイム在庫数などです。ほとんどの用途では__NEXT_DATA__で十分で、ずっと簡単です。

Walmartの検索結果と複数ページをスクレイピングする

検索結果も同様に__NEXT_DATA__を使いますが、JSONパスが少し違います。

1search_url = "https://www.walmart.com/search?q=laptops&page=1"
2response = session.get(search_url, headers=HEADERS)
3sel = Selector(text=response.text)
4raw = sel.xpath('//script[@id="__NEXT_DATA__"]/text()').get()
5data = json.loads(raw)
6search_result = data["props"]["pageProps"]["initialData"]["searchResult"]
7items = search_result["itemStacks"][0]["items"]
8# スポンサー商品を除外する
9organic_items = [i for i in items if i.get("__typename") == "Product"]
10for item in organic_items:
11    print(item.get("name"), item.get("priceInfo", {}).get("currentPrice", {}).get("price"))

ページネーションはpageパラメータを増やすだけです。&page=1&page=2という形ですね。ただし、公開されていない制限として、Walmartは実際の総件数に関係なく検索結果を25ページまでに制限しています。、「Walmartはアクセス可能な結果ページの最大数を、総ページ数にかかわらず25に設定している」とされています。

より深くカバーするための回避策は次のとおりです。

  • 並び順を切り替える: 同じ検索語で&sort=price_low&sort=price_highを使い、約50ページ分のカバーを狙う
  • 価格帯で分ける: &min_price=X&max_price=Yを追加し、カタログを細かく分割する
  • カテゴリで分ける: サイト全体ではなく、特定カテゴリ内で検索する

itemStacksが配列である点にも注意が必要です。Scrapflyのリポジトリでは [0] を固定していますが、カテゴリページやブラウズページには「Top picks」「More results」のように複数スタックが入ることがあります。より堅牢なのは、全部のスタックを回す方法です。

1for stack in search_result.get("itemStacks", []):
2    for item in stack.get("items", []):
3        if item.get("__typename") == "Product":
4            # itemを処理する
5            pass

ちなみに、Walmartのrobots.txtではされています。商品詳細ページ(/ip/...)や多くのカテゴリページ(/cp/...)は禁止対象ではありません。コンプライアンスが気になるなら、まずは検索結果よりも商品ページやカテゴリツリーから始めるのが無難です。

サイレントブロックでデータを壊さないための、本番向けエラーハンドリング

多くのチュートリアルはここで崩れます。1ページを取って1商品を解析したら終わり、という内容だからです。実運用では何千ページも取り、その間Walmartは本気で止めに来ます。デモ用スクレイパーと実際に動くスクレイパーの差は、失敗時の扱い方にあります。

サイレントブロックをデータ汚染の前に検知する

Walmartスクレイパーでかなり重要なのが、ブロック検知関数です。の見解をまとめると、独立した4つのチェックが必要です。

1BLOCK_MARKERS = (
2    "Robot or human",
3    "Press &amp; Hold",
4    "Press & Hold",
5    "px-captcha",
6    "perimeterx",
7)
8def is_walmart_blocked(response) -> bool:
9    # 1. 専用ブロック先へのリダイレクト
10    if "/blocked" in str(response.url):
11        return True
12    # 2. 明確なステータスコード
13    if response.status_code in (403, 412, 428, 429, 503):
14        return True
15    # 3. 200 OKだがCAPTCHA本文(サイレントブロック)
16    body = response.text or ""
17    if any(m.lower() in body.lower() for m in BLOCK_MARKERS):
18        return True
19    # 4. レスポンス長の健全性チェック — 本物のPDPは通常300〜900KB
20    if len(response.content) &lt; 50_000 and "/ip/" in str(response.url):
21        return True
22    return False

4つ目のチェック、つまりレスポンス長は、Walmartが目立つCAPTCHA文言を含まない軽いページを返していても、必要な商品データが入っていないケースを拾うのに役立ちます。

指数バックオフ + ジッターで再試行する

リクエスト失敗時に、すぐWalmartへ連打するのは避けるべきです。定番は、再試行のタイミングをずらすために、指数バックオフにジッターを足すやり方です。

1import time
2import random
3import logging
4from curl_cffi import requests as cffi_requests
5log = logging.getLogger("walmart")
6def fetch_with_retry(session, url, max_retries=5, base_delay=2, max_delay=60):
7    for attempt in range(max_retries):
8        try:
9            response = session.get(url, headers=HEADERS, timeout=15)
10            if response.status_code in (429, 503):
11                raise Exception(f"Throttled: {response.status_code}")
12            if is_walmart_blocked(response):
13                raise Exception("Silent block detected")
14            return response
15        except Exception as e:
16            if attempt == max_retries - 1:
17                raise
18            wait = min(max_delay, base_delay * (2 ** attempt)) + random.uniform(0, 3)
19            log.warning(f"Attempt {attempt + 1} failed: {e}. Retrying in {wait:.1f}s")
20            time.sleep(wait)
21    return None

ここでのジッター(random.uniform(0, 3))は飾りではありません。複数のワーカーが同じ秒に一斉再試行して、Akamaiの速度検知に引っかかるのを防ぎます。

レート制限

はどちらも、Walmartに対しては1リクエストあたり3〜6秒のランダム遅延に落ち着いています。「ページ読み込みの間に3〜6秒待ち、遅延時間をランダム化する」ことが推奨されています。

1import time
2import random
3def rate_limited_fetch(session, url):
4    response = fetch_with_retry(session, url)
5    time.sleep(random.uniform(3.0, 6.0))
6    return response

規模が大きいなら、非同期のレート制御にaiolimiterを使うのもありです。

1from aiolimiter import AsyncLimiter
2limiter = AsyncLimiter(max_rate=10, time_period=60)  # 1分あたり10リクエスト

データ検証

レスポンスがブロックされていなくても、解析結果が間違っていることはあります(店舗違い、ペイロード劣化など)。出力前に検証しましょう。

1def validate_product(product):
2    """商品データが妥当ならTrueを返す。"""
3    if not product.get("name"):
4        return False
5    price = (product.get("priceInfo") or {}).get("currentPrice", {}).get("price")
6    if not isinstance(price, (int, float)) or price &lt;= 0:
7        return False
8    if product.get("availabilityStatus") not in ("IN_STOCK", "OUT_OF_STOCK", "LIMITED_STOCK"):
9        return False
10    return True

セッションログの記録

セッションごとの成功率を追ってください。10分間で80%を下回ったら、何かが変わっています。IPが焼かれた、Cookieが期限切れになった、あるいはWalmartが新しいボット対策を入れた可能性があります。

1class ScrapeMetrics:
2    def __init__(self):
3        self.total = 0
4        self.success = 0
5        self.blocks = 0
6        self.errors = 0
7    def record(self, result):
8        self.total += 1
9        if result == "success":
10            self.success += 1
11        elif result == "blocked":
12            self.blocks += 1
13        else:
14            self.errors += 1
15    @property
16    def success_rate(self):
17        return (self.success / self.total * 100) if self.total &gt; 0 else 0
18    def check_health(self):
19        if self.total &gt; 20 and self.success_rate &lt; 80:
20            log.critical(f"Success rate dropped to {self.success_rate:.1f}% — consider rotating proxies or pausing")

派手ではありませんが、データ品質を守るにはかなり大事です。

自作Python vs. Scraping API vs. ノーコード: Walmartに最適な方法を選ぶ

多くの開発者は、「本当にそれが最善か」を考えずに、いきなり自作スクレイパーを書き始めます。しています。フォーラムでは「実質9/10だ」とか「専用のWebスクレイピングAPIって大げさじゃない?」という声もあります。答えは、件数、予算、エンジニアリング余力次第です。

要素自作Python(requests + プロキシ)スクレイピングAPI(Oxylabs、Bright Dataなど)ノーコードツール(Thunderbit
最初の1行を取るまでの時間数時間15〜60分約2分
本番運用までの時間40〜80時間4〜16時間約30分
ボット対策対応自分で対応(難しい)ベンダーが対応自動対応
小規模コスト(<月1,000ページ)低い(プロキシ費は約4〜8ドル/GB)月40〜49ドル程度の入門プラン無料〜15ドル/月
大規模コスト(月10万ページ以上)1件あたりは安い1件あたりは高め変動あり
カスタマイズ性完全に自由APIパラメータ次第UI/項目定義の範囲内
継続保守月4〜8時間ほぼ不要なし(AIが追従)
向いている人自前パイプラインを作る開発者中規模の本番スクレイピングビジネスユーザー、短期の単発抽出

自作Pythonが向いているケース

すでにプロキシ契約がある、ヘッダーや郵便番号ターゲット、販売者セグメントを細かく制御したい、月に何百万ページも扱うのでAPIの従量課金が積み上がる、オンプレミスやコンプライアンス要件がある、こういう場合は自作が有利です。代わりに、それなりの実装工数が必要です。ページネーション、再試行、プロキシローテーション、TLS偽装、複数ページ種別のスキーマ対応を備えた本番用Scrapyスパイダーは、に加え、Walmartがフィンガープリントを更新するたびに月4〜8時間の保守がかかります。

スクレイピングAPIが時間を節約してくれるケース

スクレイピングAPIはボット対策層を代わりに処理してくれます。では、Walmartでの成功率は 、**Scrape.doが98%**とされています。のようなツールは、入門価格が月40〜49ドルくらいです。2〜5人のエンジニアで、月1万〜100万ページ規模なら、APIを選ぶのがかなり現実的です。1リクエストごとのコストと引き換えに、保守はほぼゼロになります。

ノーコードが正解のケース

はまったく別のニーズに向いています。PM、アナリスト、EC運用担当で、来週ではなく今日の午後にWalmartの商品データをスプレッドシートへ入れたいなら、ノーコードが率直な答えです。

使い方は、を入れて、Walmartの商品ページまたは検索ページを開き、「AIで項目を提案」をクリックします。ThunderbitのAIがページを読み取り、商品名・価格・評価などの列を提案します。「スクレイプ」を押せば表にデータが入ります。Excel、Google Sheets、Airtable、Notionへエクスポートできて、しかも無料です。

Thunderbitはクラウド側でボット対策を処理するので、CAPTCHAやプロキシ、TLSフィンガープリントを気にしなくて済みます。レイアウト変更にもAIが自動で追従するため、保守もほぼ不要です。JSONパスを自分で追いたくない人には、いちばん手間の少ない選択肢です。

ただし、正直な制約もあります。Thunderbitは1日10万ページ以上の用途には向きません。クレジット予算とクラウド上限の関係で、大量取り込みは生のAPIより割高になります。また、ツールが対応していなければ、特定の郵便番号やASNを固定することもできません。継続的で高ボリュームなパイプラインなら、やはり自作かスクレイピングAPIが向いています。

ざっくりした料金感: ThunderbitでWalmartの商品1,000行を取る場合、約2,000クレジットで、Starter/Proプランだとおよそ0.60〜1.10ドルです。低ボリュームなら、OxylabsのWalmart APIと同等か、それより安いこともあります。で最新情報を確認してください。

スクレイピングしたWalmartデータの出力方法

データを取ったら、使いやすい形で保存する必要があります。よく使われるのは次の3形式です。

CSV — アナリストが実際に開く、いちばん無難な形式です。

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

Excelとの相性のため、utf-8-sigを使います。BOMがあることで、Excelが特殊文字を壊しにくくなります。

JSONL — スクレイピングパイプラインの本番向け形式です。

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

(書き込み中断があっても最後の1行だけ失う)、一定メモリでストリーミングでき、バリエーションやレビューのような入れ子データもそのまま保てます。

Excel — 一度きりの引き渡しに向いています。

1from openpyxl import Workbook
2def export_excel(products, filename="walmart_products.xlsx"):
3    wb = Workbook(write_only=True)
4    ws = wb.create_sheet("Products")
5    ws.append(["Name", "Price", "Availability", "Rating", "Reviews", "Seller"])
6    for p in products:
7        ws.append([p.get("name"), p.get("price"), p.get("availability"),
8                    p.get("rating"), p.get("review_count"), p.get("seller")])
9    wb.save(filename)

Thunderbitは、Pythonを使わない人向けのエクスポート体験もカバーしています。Google Sheets、Airtable、Notion、Excel、CSV、JSONへワンクリックで出力でき、ベースプランでも無料です。継続的な監視には、Thunderbitのスケジュールスクレイパー機能で定期抽出も自動化できます。

スケジューリングでひとつ注意するなら、。GitHub ActionsのランナーはAzureのIPレンジ上にあり、Walmartのボット対策にすぐブロックされます。APScheduerをVPSで動かすか、通信を全部住宅プロキシ経由にしてください。

Walmartスクレイピングの法的・倫理的ガイドライン

フォーラムの利用者も、この点はかなり気にしています。「開発者とのいたちごっこはまだしも、法務チーム相手は怖い」という感じです。

Walmartの利用規約では、、「事前の書面による明示的な同意」がない限り、ロボット、スパイダー、その他の手動・自動手段で素材を取得・索引化・『scrape』・『data mine』・収集することを禁じています。

Walmartのrobots.txtでは、/account/api/、多数の内部エンドポイントがされています。一方で、商品詳細ページ(/ip/...)やレビュー(/reviews/product/)は禁止対象ではありません。

hiQ v. LinkedInの前例(第9巡回区控訴裁判所、)では、公開情報のスクレイピングが連邦CFAAに違反する可能性は低いとされました。ただし同じ裁判で、hiQはLinkedInの利用規約に違反したとされ、が出ています。2024年のより新しい判決()ではCFAAの適用範囲がさらに狭まり、著作権の優先排除に関する防御も示されましたが、これらはWalmartにそのまま当てはまるわけではなく、個別の利用規約文言に依存します。

実務上の指針: サーバーに負荷をかけない。レート制限を守る。個人データやユーザーデータは取らない。データは責任を持って扱う。少量の公開Walmart商品ページを個人研究のために取るのと、Walmartの規約に反して商用規模で集めるのとでは、リスクがまるで違います。Walmartデータを使って製品を作るなら、弁護士に相談し、Walmartの公式も検討してください。

免責事項: これは教育目的の情報であり、法律相談ではありません。

まとめと重要ポイント

PythonでWalmartをスクレイピングするのは、です。AkamaiとPerimeterXの二重ボット対策があるからです。無理ではありませんが、ちゃんとしたツールとやり方が必要です。

重要なポイント:

  • __NEXT_DATA__ JSONの抽出が、ほとんどの用途でいちばん実用的です。2024〜2026年の主要なオープンソースWalmartスクレイパーは、ほぼこれを使っています。PDPではprops.pageProps.initialData.data.product、検索・閲覧ではsearchResult.itemStacksが基本パスです。
  • impersonate="chrome124"付きのcurl_cffiは必須です。素のrequestshttpxでは、ヘッダーを整えてもAkamaiのTLSフィンガープリント検知を突破できません。
  • 本当に怖いのはサイレントブロックです。Walmartは200 OKでCAPTCHA本文を返します。ステータスコードだけでなく、レスポンス本文も見てください。
  • 本番スクレイパーには、うまくいく前提のコード以上が必要です。指数バックオフとジッター、4シグナルでのブロック検知、1リクエストあたり3〜6秒のレート制限、データ検証、セッション健全性の監視が必須です。
  • /orchestra/*経由の内部API取得は強力ですが壊れやすいです。メイン手法ではなく、特定データが必要なときのDevTools調査として使いましょう。
  • Walmartの検索結果は25ページで打ち止めです。並び順の切り替えや価格帯分割でカバー範囲を広げてください。
  • 方法は正直に選ぶべきです。カスタム要件と大規模処理がある開発者には自作Python。中規模チームでスクレイピング担当がいないならAPI。は、今日の午後にGoogle Sheetsへデータが欲しいビジネスユーザー向けです。

ノーコードで試したいなら、には無料枠があります。Walmartのページをいくつかスクレイピングして結果を確かめられます。Pythonで進めるなら、この記事のコードパターンは本番で検証済みです。どちらの道を選んでも、Walmartの防御と、それを抜ける3つの道筋が見えるはずです。

Webスクレイピングの他の手法については、もご覧ください。ではチュートリアル動画も公開しています。

FAQ

Walmartの商品データをスクレイピングするのは合法ですか?

Walmartの利用規約では、書面による同意なしの自動スクレイピングは禁止されています。第9巡回区のhiQ v. LinkedIn判決(2022年)では、公開ページのスクレイピングに連邦CFAAが適用される可能性は低いとされましたが、同じ事件はスクレイパー側に対するで終わっています。個人研究のために公開商品ページを少量取るのと、商用規模で抽出するのとでは、リスクがかなり違います。Walmartデータで事業を作るなら、弁護士に相談してください。

Walmartスクレイパーが頻繁にブロックされるのはなぜですか?

よくある原因は、素のrequestshttpxを使っていること(Python固有のTLSフィンガープリントが即座にAkamaiに検知される)、ヘッダー不足または不適切、プロキシローテーションなし、1ページあたり3〜6秒より速いリクエスト、セッションCookie(_px3_abcklocDataV3)の欠落です。impersonate="chrome124"付きのcurl_cffiに切り替え、住宅プロキシを使い、この記事で説明したブロック検知と再試行のパターンを実装してください。

PythonでWalmartからどんなデータが取れますか?

商品名、価格(現在価格と値下げ前価格)、画像、短い説明、長い説明、評価、レビュー数、在庫状況、販売者名、製造元情報、バリエーション(サイズ、色)、カテゴリ上の位置などです。__NEXT_DATA__方式を使えば、これらはすべて構造化JSONとして取れます。内部APIの取得を使えば、さらにバリエーション別価格、リアルタイム在庫、ページ分割されたレビューも取れます。

Walmartをスクレイピングするのにプロキシは必要ですか?

はい。本番運用や繰り返し利用では必要です。 — ヘッダーが完璧でも、非住宅IPはAkamaiのIPレピュテーションで弾かれます。住宅プロキシまたはモバイルプロキシが必須です。データセンターIPはかなり早く焼かれます。プロキシ業者やプランにもよりますが、1,000ページあたり約3〜17ドルを見込んでください。

コードを書かずにWalmartをスクレイピングできますか?

できます。はAI搭載のChrome拡張で、2クリックでWalmartをスクレイピングできます。まず「AIで項目を提案」で商品データ列を自動検出し、次に「スクレイプ」で抽出します。クラウドでボット対策を処理し、Excel、Google Sheets、Airtable、Notionへ直接エクスポートできて、しかも無料です。カスタムパイプラインを作らずにすぐデータが欲しいアナリスト、PM、ビジネスユーザーにぴったりです。大規模または高度にカスタマイズされたスクレイピングには、PythonまたはスクレイピングAPIが引き続き有力です。

AIでWalmartスクレイピングを試す

詳しくはこちら

Shuai Guan
Shuai Guan
Co-founder/CEO @ Thunderbit. Passionate about cross section of AI and Automation. He's a big advocate of automation and loves making it more accessible to everyone. Beyond tech, he channels his creativity through a passion for photography, capturing stories one picture at a time.
目次

Thunderbitを試す

リードや各種データをたった2クリックで取得。AI搭載。

Thunderbitを入手 無料です
AIでデータを抽出
Google Sheets、Airtable、Notionへ簡単にデータを転送
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week