איך לגרוף נתוני Walmart באמצעות Python ב-2026 (ולא להיחסם)

עודכן לאחרונה ב- April 28, 2026
איך לגרוף נתוני Walmart באמצעות Python ב-2026 (ולא להיחסם)

Walmart משנה את המחירים של חלק מהמוצרים כמה פעמים ביום. אם אי פעם ניסית לעקוב אחרי זה בצורה תכנותית, אתה מכיר את הכאב: הסקריפט עובד 20 דקות, ואז מתחיל בשקט להחזיר דפי CAPTCHA שמוסווים כתשובות רגילות של 200 OK.

השקעתי לא מעט זמן בהתמודדות עם מערכות ההגנה של Walmart נגד בוטים כחלק מעבודת חילוץ הנתונים שלנו ב-Thunderbit, ואני רוצה לשתף את כל מה שלמדתי — השיטות שבאמת עובדות ב-2025, הכשלים השקטים שמזהמים את הנתונים שלך, והפשרות הכנות בין כתיבת scraper משלך, תשלום על API לגריפה, או פשוט שימוש בכלי ללא קוד. המדריך הזה מכסה שלוש שיטות חילוץ (ניתוח HTML, JSON של __NEXT_DATA__, ויירוט של API פנימי), טיפול בשגיאות ברמת production שרוב המדריכים מדלגים עליו לגמרי, ומסגרת החלטה כנה לבחירת הגישה הנכונה. יש כאן משהו בין אם אתה כותב Python ובין אם אתה רק רוצה גיליון מלא במחירים עד ארוחת הצהריים.

למה לגרוף את Walmart עם Python?

Walmart היא הקמעונאית הגדולה בעולם לפי הכנסות — 680.985 מיליארד דולר בשנת הכספים 2025, ומחזיקה במקום הראשון ב-Fortune Global 500 במשך 12 שנים רצופות. האתר מארח בערך 420 מיליון רישומים פעילים, כאשר סמנכ"ל הכספים של Walmart ציין "חצי מיליארד SKU" במרקטפלייס. כ-95% מאותם רישומים מגיעים ממוכרים צד שלישי, מה שאומר שהקטלוג תנודתי — מוכרים נכנסים ויוצאים, וריאנטים משתנים, והמלאי מתהפך מדי יום.

walmart_stats_670d06c6bd.png

התנודתיות הזו היא בדיוק הסיבה שגריפה חשובה. דוח רבעוני לא יכול ללכוד את מה שגריפה לילית כן יכולה. הנה מקרי השימוש הנפוצים ביותר שאני רואה:

מקרה שימושמי צריך את זהמה הם מחלצים
ניטור מחירי מתחריםתפעול e-commerce, כלי repricingמחירים, מבצעים, עמידה ב-MAP
העשרת קטלוג מוצריםצוותי מכירות ומרצ'נדייזינגתיאורים, תמונות, מפרטים, וריאנטים
מעקב אחר זמינות מלאישרשרת אספקה, dropshippersמצב מלאי, מידע על מוכר
מחקר שוק וניתוח מגמותשיווק, מנהלי מוצרדירוגים, ביקורות, היצע בקטגוריות
יצירת לידיםצוותי מכירותשמות מוכרים, מספרי מוצרים, קטגוריות

שוק תוכנות ניטור המחירים של מתחרים לבדו הגיע ל-1.92 מיליארד דולר ב-2025 וצפוי להגיע ל-5.09 מיליארד דולר עד 2033. התנהגות הצרכנים מניעה את ההוצאה הזו: 94% מהלקוחות משווים מחירים בזמן קנייה אונליין, ו-83% עושים השוואת מחירים בכמה אתרים.

Python היא שפת ברירת המחדל לעבודה הזו. דוח התשתית של Apify ל-2026 מעריך ש-Python אחראית ל-71.7% מכל הגריפות ברשת, והספרייה המרכזית (requests) מורידה כ-30 מיליון הורדות בשבוע. אם אתה גורף בהיקף כלשהו, סביר מאוד שאתה עושה את זה ב-Python.

למה Walmart הוא אחד האתרים הקשים ביותר לגריפה

Walmart קשה במיוחד כי הוא מריץ שני מוצרי אנטי-בוט מסחריים ברצף: Akamai Bot Manager כשכבת ה-edge WAF ו-TLS fingerprinting, ו-PerimeterX (שממותג מחדש כ-HUMAN Security) כשכבת האתגר ההתנהגותי ב-JavaScript. ב-Scrape.do מתארים את השילוב הזה כ"נדיר וקשה מאוד לעקיפה".

walmart_antibot_3d67d0119c.png

ScrapeOps מדרגים את Walmart ב-9/10 ברמת הקושי הכוללת לגריפה, כאשר Akamai לבדו מקבל 9/10. מהניסיון שלי, זה די מדויק.

הנה מול מה אתה באמת מתמודד:

Akamai Bot Manager בודק את טביעת ה-TLS שלך (hash מסוג JA3/JA4), את סדר מסגרות ה-HTTP/2, את סדר וכותרות ה-headers, ואת עוגיות הסשן (_abck, ak_bmsc). קריאת requests סטנדרטית ב-Python מפיקה טביעת TLS שאף דפדפן אמיתי לא מייצר — Akamai מסמן אותה עוד לפני שהבקשה בכלל מגיעה לשרתים של Walmart.

PerimeterX/HUMAN פועל אחרי Akamai ומריץ fingerprinting ב-JavaScript (px.js) שבודק מאפייני navigator, רינדור canvas, WebGL, audio context, ומדדים ביומטריים-התנהגותיים (תנועת עכבר, מהירות גלילה, דינמיקת הקלדה). הכשל הנראה לעין הוא אתגר ה- "Press & Hold" הידוע לשמצה — כפתור שצריך להחזיק בערך 10 שניות בזמן שאותות התנהגותיים נמדדים. Oxylabs אומרים זאת בחדות: "Walmart משתמשת במודל 'Press & Hold' של CAPTCHA, שמסופק על ידי PerimeterX, וידוע שכמעט בלתי אפשרי לפתור אותו מהקוד שלך."

ההתנהגות המסוכנת באמת היא החסימה השקטה. Walmart מחזירה HTTP 200 עם גוף של CAPTCHA במקום 403. ScrapingBee מאשרים: "Walmart מחזירה קוד סטטוס 200 OK גם כאשר היא מגישה דף CAPTCHA. אי אפשר להסתמך רק על קוד הסטטוס כדי לדעת אם הבקשה הצליחה." הסקריפט שלך מנתח בשמחה את ה-HTML של ה-CAPTCHA כ"המוצר לא נמצא" וממשיך הלאה. חצי מהדאטהסט שלך זבל, ואתה אפילו לא יודע את זה.

ואז יש את בעיית הנתונים לפי חנות. המחירים והמלאי של Walmart תלויי מיקום, ונשלטים על ידי עוגיות כמו locDataV3 ו-assortmentStoreId. בלי העוגיות הנכונות, תקבל נתונים של "ברירת מחדל ארצית" שאולי נראים שלמים אבל לא תואמים למה שקונים אמיתיים רואים. עוגיות חסרות לא יוצרות דף חסימה — הן יוצרות נתונים שגויים בלי כשל נראה לעין, וזה גרוע יותר.

שלוש שיטות לחילוץ נתונים מ-Walmart (ואיך הן משתוות)

לפני שנכנסים צעד-צעד, הנה שלוש גישות החילוץ העיקריות. רוב המדריכים המתחרים מכסים רק אחת או שתיים. אני אעבור על שלושתן כדי שתוכל לבחור את מה שמתאים למצב שלך.

שיטהאמינותשלמות הנתוניםקושי מול אנטי-בוטעומס תחזוקה
HTML + BeautifulSoup⚠️ נמוכה (הסלקטורים נשברים בכל deploy)בינוניתגבוההגבוהה
JSON של __NEXT_DATA__✅ טובהגבוההבינונית-גבוההבינונית
יירוט API פנימי✅ הטובה ביותרהגבוהה ביותר (וריאנטים, מלאי, ביקורות)בינונית-גבוההנמוכה (JSON מובנה)
Thunderbit (ללא קוד)✅ טובהגבוההנמוכה (מטופל על ידי AI)אין

ניתוח HTML הוא האפשרות הגרועה ביותר עבור Walmart — האתר שולח bundles של Next.js עם שמות מחלקות CSS מגובבים שמשתנים בכל deploy. שיטת JSON של __NEXT_DATA__ היא הבחירה הפרגמטית שבה משתמש כל scraper רציני בקוד פתוח מ-2024–2026. יירוט של API פנימי הוא החזק ביותר, אבל מגיע עם הסתייגויות שרוב המדריכים מחליקים מעליהן. ו-Thunderbit הוא הבחירה הנכונה כשלא צריך בכלל צינור מותאם אישית.

נסה את Thunderbit לגריפת Walmart

הגדרת סביבת Python שלך לגריפת Walmart

זה מה שתצטרך:

  • רמת קושי: בינונית
  • זמן נדרש: כ-30 דקות להגדרה, ועוד זמן כתיבה
  • מה צריך: Python 3.10+, pip, עורך קוד, ולשימוש ב-production גם שירות proxy או API לגריפה

צור את תיקיית הפרויקט ואת סביבת העבודה הווירטואלית:

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

התקן את הספריות הנדרשות:

pip install curl_cffi parsel beautifulsoup4 lxml

curl_cffi הוא הסטנדרט של 2025 לגריפה של יעדים קשים. זו עטיפת libcurl שיכולה להתחזות לטביעות TLS מדויקות של דפדפנים. Bright Data מסבירים: "Walmart משתמשת ב-TLS fingerprinting כחלק מזיהוי הבוטים שלה, וגם הגדרת User-Agent כך שידמה דפדפן אמיתי לא תעקוף את זה." requests או httpx רגילים לא יכולים לעבור את Akamai בלי קשר לכותרות שתגדיר. curl_cffi עם impersonate="chrome124" הוא מה שעושה את ההבדל.

כדאי גם להשתמש ב-json (מובנה), csv (מובנה), time, random, ו-logging עבור דפוסי ה-production שנכסה בהמשך.

שלב אחר שלב: גריפת דפי מוצר של Walmart עם Python

שלב 1: שליפת דף המוצר של Walmart

המשימה הראשונה שלך היא לבצע בקשת HTTP שלא נחסמת מיד. הנה סט הכותרות הקנוני שמשמש את Scrapfly, Scrapingdog, Oxylabs ו-ScrapeOps ב-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" הוא זה שעושה את רוב העבודה כאן. הוא אומר ל-curl_cffi להתאים בדיוק ל-TLS ClientHello של Chrome 124, לסדר המסגרות ב-HTTP/2 ולרצף ה-pseudo-headers. בלי זה, Akamai רואה hash של JA3 ספציפי ל-Python וחוסם אותך עוד לפני שהבקשה בכלל מגיעה לשכבת האפליקציה של Walmart.

איך נראית תגובה שנחסמה: אם אתה רואה "Robot or human?" בכותרת ה-HTML של התגובה, או אם התגובה מפנה ל-walmart.com/blocked, נתפסת. הטריק הוא ש-Walmart מחזירה לעיתים קרובות קוד סטטוס 200 עם גוף CAPTCHA — לכן בדיקה של response.ok בלבד לא מספיקה.

לכל שימוש חוזר או ב-production, תצטרך פרוקסי residential. כתובות IP של data center נשרפות מיד על ידי מערכת המוניטין של Akamai. אכסה את כל אסטרטגיית הטיפול בשגיאות והפרוקסי בסעיף ה-production בהמשך.

שלב 2: ניתוח נתוני מוצר מתוך JSON של __NEXT_DATA__

Walmart.com היא אפליקציית Next.js, וה-HTML שנוצר בצד השרת מטמיע את כל payload האתחול בתוך תגית סקריפט אחת: <script id="__NEXT_DATA__" type="application/json">. זה מכרה זהב.

המדריך של Scrapfly ל-2026 מאשר: "ב-2026 Walmart משתמשת ב-Next.js עם JSON מובנה בתוך תגיות הסקריפט של __NEXT_DATA__, מה שהופך חילוץ נתונים מוסתרים לאמין יותר מאשר ניתוח מסורתי של סלקטורי CSS." כל scraper פתוח בולט ל-Walmart — של Scrapfly, של Oxylabs, ו-python-scrapy-playbook — משתמש בשיטה הזו.

כך מחלצים את זה:

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", {})

רוב המדריכים עוצרים כאן. להלן מיפוי JSON מלא של הנתיבים לשדות שבאמת מעניינים אותך — מאומת מול דפי Walmart חיים ב-2024–2026:

שדה נתוןנתיב JSON (מתחת ל-initialData)סוגהערות
שם המוצרdata > product > nameמחרוזת
מותגdata > product > brandמחרוזת
מחיר נוכחי (מספר)data > product > priceInfo > currentPrice > priceמספר עשרוניעשוי להשתנות לפי עוגיית החנות
מחיר נוכחי (מחרוזת)data > product > priceInfo > currentPrice > priceStringמחרוזתבפורמט לדוגמה "$9.99"
תיאור קצרdata > product > shortDescriptionמחרוזת HTMLיש לנתח עם BeautifulSoup כדי לקבל טקסט
תיאור ארוךdata > idml > longDescriptionמחרוזת HTMLנמצא ב-idml, לא בתוך product — זו המלכודת שמדריכים ישנים טועים בה
כל התמונותdata > product > imageInfo > allImagesמערךרשימת אובייקטים של {id, url}
דירוג ממוצעdata > product > averageRatingמספר עשרוניהמפתח הוא averageRating, לא rating הישן
מספר ביקורותdata > product > numberOfReviewsמספר שלם
וריאנטיםdata > product > variantCriteriaמערךקבוצות אפשרויות (מידה, צבע)
זמינותdata > product > availabilityStatusמחרוזתIN_STOCK, OUT_OF_STOCK, LIMITED_STOCK
מוכרdata > product > sellerDisplayNameמחרוזת
יצרןdata > product > manufacturerNameמחרוזת

הנתיב של longDescription הוא המלכודת שכולם נופלים בה. פוסט של ScrapeHero מ-2023 שם אותו ב-product.longDescription, אבל מקורות מ-2024 ומעלה מציבים אותו באופן עקבי במפתח האח idml. תמיד קרא קודם את idml.longDescription ורק אז חזור ל-product.longDescription עבור דפים ישנים יותר.

הנה תבנית חילוץ בטוחה עם שרשראות .get():

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"),
    }

למשתמשים שלא רוצים להתמודד בכלל עם ניווט בנתיבי JSON, ה-AI של Thunderbit מזהה ומבנה את השדות האלה באופן אוטומטי — בלי מיפוי ידני של נתיבים. לוחצים על "AI Suggest Fields", הוא קורא את הדף, ומקבלים טבלה. אבל אם אתה בונה צינור מותאם אישית, המפה למעלה היא נקודת הייחוס שלך.

שלב 3: יירוט נקודות הקצה הפנימיות של Walmart לקבלת נתונים עשירים יותר

אף מאמר מתחרה לא מכסה את השיטה הזו כמו שצריך. זהו מסלול החילוץ החזק ביותר — וגם המסובך ביותר.

ה-frontend של Walmart קורא ל-backend פדרטיבי של GraphQL שנבנה על Apollo Gateway. נקודות הקצה יושבות תחת www.walmart.com/orchestra/*:

  • /orchestra/pdp/graphql/... — hydration של פרטי מוצר + החלפת וריאנטים
  • /orchestra/snb/graphql/... — חלוקת pagination של search-n-browse
  • /orchestra/reviews/graphql/... — ביקורות מחולקות לעמודים

אלו מחזירות JSON נקי ומובנה עם נתונים ש-__NEXT_DATA__ לפעמים קוטע — תמחור ברמת וריאנט, ספירות מלאי בזמן אמת, paginations מלאים של ביקורות.

המלכודת שפוסטים בבלוגים נוטים לעקוף: Walmart משתמשת ב-Apollo persisted queries. גוף הבקשה שולח רק hash מסוג SHA-256 (persistedQuery.sha256Hash), לא את טקסט השאילתה. אם ה-hash לא מוכר לשרת, תקבל PersistedQueryNotFound. Walmart מחליפה את ה-hashes האלה בכל deploy. זו הסיבה שאף אחד מה-scrapers הפופולריים בקוד פתוח של Walmart לא מפרסם קוד /orchestra/ שאפשר פשוט להעתיק ולהדביק.

הגרסה הפרקטית והכנה של השיטה הזו היא תרגיל ב-DevTools:

  1. פתח דף מוצר של Walmart ב-Chrome
  2. פתח את DevTools → לשונית Network, וסנן לפי "Fetch/XHR"
  3. דפדף בדף כרגיל — לחץ על וריאנטים, גלול לביקורות, שנה מיקום חנות
  4. חפש בקשות ל-endpoints של /orchestra/* שמחזירות JSON עם נתוני מוצר
  5. קליק ימני על הבקשה → "Copy as cURL"
  6. המר את פקודת ה-cURL ל-Python באמצעות curl_cffi

כך נראית קריאת API שמשוחזרת:

import json
from curl_cffi import requests

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

# קודם, חמם את הסשן על ידי ביקור בדף המוצר
session.get("https://www.walmart.com/ip/some-product/1234567", headers=HEADERS)

# ואז שחזר את קריאת ה-API הפנימי (שהועתקה מ-DevTools)
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 = {
    # הדבק כאן את גוף הבקשה המדויק מ-DevTools
    "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()

שלב חימום הסשן קריטי. עוגיות ה-PerimeterX של Walmart (_px3, _pxhd, ACID) חייבות להיקבע על ידי שליפת ה-HTML הראשונית לפני שהבקשה ל-API תצליח. בלעדיהן תקבל 412 או 403.

מתי להשתמש בשיטה הזו: כשאתה צריך נתונים ש-__NEXT_DATA__ לא כולל — תמחור עמוק לפי וריאנט, ביקורות מחולקות לעמודים מעבר לאצווה הראשונה, או ספירות מלאי בזמן אמת. עבור רוב מקרי השימוש, __NEXT_DATA__ מספיק ופשוט הרבה יותר.

גריפת תוצאות חיפוש ומספר עמודים ב-Walmart

תוצאות חיפוש עוקבות אחרי דפוס דומה של __NEXT_DATA__, אבל עם נתיב JSON שונה:

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"]

# סינון מוצרים ממומנים
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"))

Pagination עובד על ידי העלאת הפרמטר page: &page=1, &page=2, וכו'. אבל הנה המגבלה הלא מתועדת: Walmart מגבילה את תוצאות החיפוש ל-25 עמודים בלי קשר למספר הכולל בפועל. Scrapfly מאשרים: "Walmart קובעת את מספר עמודי התוצאות המרבי שניתן לגשת אליו ל-25, בלי קשר למספר הכולל של העמודים הזמינים."

דרכי עוקף כדי לקבל כיסוי עמוק יותר:

  • היפוך סדר מיון: הרץ את אותה שאילתה עם &sort=price_low ואז עם &sort=price_high כדי לקבל כ-50 עמודי כיסוי
  • חיתוך לפי טווח מחירים: הוסף &min_price=X&max_price=Y כדי לפצל את הקטלוג לחלונות קטנים יותר
  • חיתוך לפי קטגוריה: חפש בתוך קטגוריות ספציפיות במקום ברמת כל האתר

שים לב ש-itemStacks הוא מערך. Scrapfly מקבעים [0] ב-repo שלהם, אבל דפי קטגוריה ודפדוף לפעמים מכילים כמה stacks ("Top picks," "More results"). הדפוס החזק עובר על כל ה-stacks:

for stack in search_result.get("itemStacks", []):
    for item in stack.get("items", []):
        if item.get("__typename") == "Product":
            # עיבוד הפריט
            pass

עוד נקודה ששווה לדעת: robots.txt של Walmart אוסר את /search. דפי פרטי מוצר (/ip/...) ורוב דפי הקטגוריות (/cp/...) אינם אסורים. אם חשוב לך לעמוד בכללים, התחל מדפי מוצר ומעצי קטגוריות ולא מחיפוש.

אל תיתן לחסימות שקטות להרוס את הנתונים שלך: טיפול בשגיאות ברמת Production

רוב המדריכים מתפרקים כאן. הם מראים לך איך לשלוף דף אחד, לנתח מוצר אחד, ולסיים. ב-production אתה שולף אלפי דפים, ו-Walmart מנסה באופן פעיל לעצור אותך. ההבדל בין scraper הדגמה לבין scraper שבאמת עובד הוא איך הוא מתמודד עם כשל.

לזהות חסימות שקטות לפני שהן מזהמות את הנתונים שלך

הפונקציה החשובה ביותר ב-scraper ל-Walmart היא גלאי החסימות. על סמך הסכמה בין ScrapingBee, Scrapingdog, Oxylabs, ו-Decodo, צריך ארבע בדיקות בלתי תלויות:

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

def is_walmart_blocked(response) -> bool:
    # 1. הפניה לנקודת הקצה הייעודית לחסימה
    if "/blocked" in str(response.url):
        return True
    # 2. קודי סטטוס קשיחים
    if response.status_code in (403, 412, 428, 429, 503):
        return True
    # 3. 200 OK עם גוף CAPTCHA (מקרה החסימה השקטה)
    body = response.text or ""
    if any(m.lower() in body.lower() for m in BLOCK_MARKERS):
        return True
    # 4. בדיקת אורך תגובה — PDP אמיתיים הם 300-900KB
    if len(response.content) < 50_000 and "/ip/" in str(response.url):
        return True
    return False

הבדיקה הרביעית — אורך התגובה — תופסת מקרים שבהם Walmart מחזירה דף מצומצם שלא מכיל סימני CAPTCHA ברורים, אבל גם לא מכיל את נתוני המוצר שאתה צריך.

לוגיקת retry עם Exponential Backoff ו-Jitter

כשבקשה נכשלת, אתה לא רוצה לטרוק מיד על Walmart שוב. הדפוס הסטנדרטי משתמש ב-exponential backoff עם jitter כדי לנתק את ניסיונות החזרה זה מזה:

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("Silent block detected")

            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"Attempt {attempt + 1} failed: {e}. Retrying in {wait:.1f}s")
            time.sleep(wait)

    return None

ה-jitter (random.uniform(0, 3)) הוא לא קישוט — הוא מנתק את העובדים זה מזה כך שחוות של scrapers לא תנסה שוב באותו שנייה ותפעיל את גלאי המהירות של Akamai.

הגבלת קצב

גם Thunderbit וגם Scrape.do מתכנסים ל-השהיה אקראית של 3–6 שניות לבקשה עבור Walmart: "האט את הבקשות שלך על ידי המתנה של 3–6 שניות בין טעינות דף, והגרל את ההשהיות."

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

בהיקפים גדולים, כדאי לשקול שימוש ב-aiolimiter להגבלת קצב אסינכרונית:

from aiolimiter import AsyncLimiter
limiter = AsyncLimiter(max_rate=10, time_period=60)  # 10 בקשות בדקה

ולידציית נתונים

גם כשהתגובה לא נחסמת, הנתונים שניתחו עלולים להיות שגויים (חנות לא נכונה, payload פגום). צריך לאמת לפני כתיבה לפלט:

def validate_product(product):
    """מחזיר True אם נתוני המוצר נראים לגיטימיים."""
    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

רישום מצב סשן

עקוב אחרי שיעור ההצלחה לכל סשן. כשהוא יורד מתחת ל-80% במשך 10 דקות, משהו השתנה — או שה-IP נשרף, או שהעוגיות פגו, או ש-Walmart פרסה כלל אנטי-בוט חדש.

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"שיעור ההצלחה ירד ל-{self.success_rate:.1f}% — שקול להחליף פרוקסי או להשהות")

לא זוהר. אבל זה מה ששומר על הנתונים שלך נקיים.

Python בעצמך מול Scraping API מול No-Code: איך לבחור את הדרך הנכונה לגריפת Walmart

הרבה מפתחים קופצים ישר לכתיבת scraper מותאם אישית בלי לשאול אם זו באמת הבחירה הנכונה. ScrapeOps מדרגים את Walmart 9/10 בקושי. משתמשי פורומים מתארים את זה כ"בערך 9/10" ותוהים "אם API ייעודי לגריפת web יהיה מוגזם." התשובה תלויה בנפח, בתקציב וביכולת ההנדסית.

גורםPython בעצמך (requests + proxies)Scraping API (Oxylabs, Bright Data וכו')כלי ללא קוד (Thunderbit)
זמן הגדרה לשורה ראשונהשעות15–60 דק'כ-2 דק'
זמן הגדרה ל-production40–80 שעות4–16 שעותכ-30 דק'
טיפול באנטי-בוטאתה מנהל (קשה)מטופל על ידי הספקמטופל אוטומטית
עלות בהיקף קטן (<1K דפים/חודש)נמוכה (עלות proxy כ-$4–8/GB)תכניות כניסה של $40–$49 לחודשחינם–$15 לחודש
עלות בהיקף גדול (100K+ דפים/חודש)נמוכה יותר לבקשהגבוהה יותר לבקשהמשתנה
התאמה אישיתשליטה מלאהפרמטרים של APIמוגבלת לפי UI/שדות
תחזוקה שוטפת4–8 שעות/חודשכמעט אפסאין (ה-AI מסתגל)
מתאים במיוחד למפתחים שבונים צינורות מותאמים אישיתגריפה ב-production בהיקף בינונימשתמשי עסק, חילוצים חד-פעמיים מהירים

מתי Python בעצמך הגיוני

DIY מנצח כשכבר יש לך חוזה פרוקסי, כשאתה צריך שליטה קפדנית בכותרות, יעד zip code, או קבוצות מוכרים, כשאתה מאנדקס מיליוני דפים בחודש ועלויות API לכל רשומה מצטברות, או כשאתה צריך פתרון on-prem או ערבויות תאימות. המחיר הוא זמן הנדסי אמיתי: spider של Scrapy ברמת production עם pagination, retries, rotation של פרוקסי, התחזות TLS, וסכמות לכמה סוגי דפים דורש 40–80 שעות עבודה של Python בכיר, ועוד 4–8 שעות תחזוקה בחודש כשהפינגרפרינטים של Walmart מתחלפים.

מתי Scraping API חוסך לך זמן

Scraping APIs מטפלים בשכבת האנטי-בוט כדי שאתה לא תצטרך. הבנצ'מרקים של ScrapeOps מראים שיעורי הצלחה של 99% עבור Zyte API ו-98% עבור Scrape.do ב-Walmart. תמחור ברמת כניסה נע סביב $40–$49 לחודש עבור כלים כמו ScraperAPI, Oxylabs, ו-Scrapingdog. אם אתה צוות של 2–5 מהנדסים ונפח הגריפה שלך הוא 10K–1M דפים בחודש, API הוא כמעט תמיד הבחירה הנכונה. אתה מחליף עלות לבקשה בתמורה לאפס תחזוקה.

מתי No-Code הוא הבחירה הנכונה

Thunderbit מתאים לפרופיל שונה לגמרי. אם אתה PM, אנליסט, או מפעיל e-commerce שצריך נתוני מוצרים מ-Walmart בגיליון אלקטרוני עוד היום — ולא ברבעון הבא — כלי ללא קוד הוא התשובה הכנה.

הזרימה: מתקינים את תוסף ה-Chrome של Thunderbit, נכנסים לדף מוצר או חיפוש של Walmart, לוחצים על "AI Suggest Fields", וה-AI של Thunderbit קורא את הדף ומציע עמודות (שם מוצר, מחיר, דירוג וכו'). לוחצים על "Scrape", והנתונים נטענים לטבלה. מייצאים ל-Excel, Google Sheets, Airtable, או Notion — הכול בחינם, בלי חומת תשלום.

Thunderbit מטפל באנטי-בוט בענן, כך שלא מתעסקים ב-CAPTCHA, פרוקסי, או TLS fingerprinting. ה-AI מסתגל אוטומטית לשינויים בפריסה, כך שאין תחזוקה. למשתמשים שלא רוצים בכלל להתמודד עם ניווט בנתיבי JSON, זה מסלול ההתנגדות הנמוכה ביותר.

מגבלות כנות: Thunderbit לא בנוי ל-100K+ דפים ביום. תקציבי קרדיטים ומגבלות ענן הופכים ingestion בהיקף גבוה ללא כלכלי מול APIs גולמיים. גם לא תמיד אפשר לנעוץ zip code או ASN מסוים אלא אם הכלי תומך בזה. לצינורות מתמשכים ובעלי נפח גבוה, DIY או Scraping API עדיין עדיפים.

מחיר גס: 1,000 שורות מוצר של Walmart ב-Thunderbit עולות בערך 2,000 קרדיטים (~$0.60–$1.10 בתכניות Starter/Pro). זה דומה ל-API של Walmart ב-Oxylabs וזול יותר מרוב APIs החובבניים בהיקף נמוך. בדוק את התמחור של Thunderbit לפרטים העדכניים.

גרוף נתוני מוצרי Walmart עם AI Get Started Free

ייצוא נתוני Walmart שגרפת

אחרי שיש לך את הנתונים, צריך לשים אותם במקום שימושי. שלושה פורמטים מכסים את רוב הצרכים:

CSV — הפורמט הפשוט ביותר שאנליסטים באמת פותחים:

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})

השתמש בקידוד utf-8-sig כדי לשמור על תאימות ל-Excel. סימון ה-BOM מונע מ-Excel לעוות תווים מיוחדים.

JSONL — פורמט production לצינורות גריפה:

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 עמיד לקריסה (כתיבה שנקטעה תאבד רק את השורה האחרונה), ניתן ל-streaming עם זיכרון קבוע, ושומר על נתונים מקוננים כמו וריאנטים וביקורות.

Excel — להעברה חד-פעמית לאנליסט:

from openpyxl import Workbook

def export_excel(products, filename="walmart_products.xlsx"):
    wb = Workbook(write_only=True)
    ws = wb.create_sheet("Products")
    ws.append(["Name", "Price", "Availability", "Rating", "Reviews", "Seller"])
    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 מכסה את סיפור הייצוא עבור מי שלא כותב Python: ייצוא בלחיצה אחת ל-Google Sheets, Airtable, Notion, Excel, CSV ו-JSON — הכול בחינם בתכנית הבסיסית. לניטור מתמשך, תכונת ה-scheduled scraper של Thunderbit יכולה להריץ חילוצים חוזרים אוטומטית.

אזהרה אחת לגבי תזמון: אל תשתמש ב-GitHub Actions לגריפת Walmart. רצים של GitHub Actions יושבים על טווחי IP של Azure ש-Walmart חוסמת מיד. השתמש ב-APScheduler על VPS, או ניתב את כל התעבורה דרך פרוקסי residential.

הנחיות משפטיות ואתיות לגריפת Walmart

משתמשים בפורומים מעלים את החשש הזה במפורש: "אין לי בעיה לשחק חתול ועכבר עם המפתחים, אבל אני זהיר כשזה מגיע למחלקה המשפטית שלהם."

תנאי השימוש של Walmart אוסרים במפורש שימוש ב"כל robot, spider... או כל אמצעי ידני או אוטומטי אחר כדי לאחזר, לאנדקס, 'לגרוף', 'לכרות נתונים' או לאסוף בכל דרך אחרת חומרים כלשהם" ללא "הסכמה מפורשת מראש בכתב".

robots.txt של Walmart אוסר את /search, /account, /api/, ועשרות נקודות קצה פנימיות. דפי פרטי מוצר (/ip/...) וביקורות (/reviews/product/) אינם אסורים.

התקדים hiQ נגד LinkedIn (המעגל התשיעי, 2022) קבע שגריפה של נתונים שזמינים לציבור ככל הנראה אינה מפרה את חוק CFAA הפדרלי. אבל אותו בית משפט פסק מאוחר יותר ש-hiQ הפרה את הסכם המשתמש של LinkedIn ונכנס נגדה לפסיקת הסכמה של 500,000 דולר. החלטות עדכניות יותר מ-2024 (Meta נגד Bright Data, X Corp. נגד Bright Data) צמצמו עוד יותר את CFAA ויצרו הגנות של preemption לפי זכויות יוצרים, אבל ההכרעות האלה נשענו על שפת ToU ספציפית שלא מתמפה נקי ל-Walmart.

הנחיות מעשיות: אל תעמיס על שרתים. כבד מגבלות קצב. אל תגרוף נתונים אישיים או נתוני משתמשים. השתמש בנתונים באחריות. גריפה של דפי מוצר ציבוריים של Walmart בקצב מתון לצורך מחקר אישי היא פרופיל סיכון שונה מאוד מגריפה בהיקף מסחרי בניגוד לתנאי השימוש של Walmart. אם אתה בונה מוצר על בסיס נתוני Walmart, דבר עם עורך דין ובדוק את ה- affiliate and seller APIs הרשמיים של Walmart.

הבהרה: זהו מידע חינוכי, לא ייעוץ משפטי.

סיכום ונקודות מפתח

גריפת Walmart עם Python היא אתגר קושי 9/10 בזכות שכבת ההגנה הכפולה של Akamai + PerimeterX. לא בלתי אפשרי — אבל צריך את הכלים והדפוסים הנכונים.

נקודות מפתח:

  • חילוץ JSON של __NEXT_DATA__ הוא הבחירה הפרגמטית לרוב מקרי השימוש. זה מה שכל scraper רציני בקוד פתוח ל-Walmart מ-2024–2026 משתמש בו. נתיב הבסיס הוא props.pageProps.initialData.data.product ל-PDPs ו-searchResult.itemStacks לחיפוש/דפדוף.
  • curl_cffi עם impersonate="chrome124" הוא חובה. requests או httpx רגילים לא יכולים לעבור את TLS fingerprinting של Akamai בלי קשר לכותרות.
  • חסימות שקטות הן הסכנה האמיתית. Walmart מחזירה 200 OK עם גופי CAPTCHA. בדוק את תוכן התגובה, לא רק את קודי הסטטוס.
  • Scrapers ב-production צריכים יותר מקוד של happy path. Exponential backoff עם jitter, זיהוי חסימה על ארבעה אותות, הגבלת קצב של 3–6 שניות לבקשה, ולידציית נתונים וניטור בריאות הסשן — כולם חיוניים.
  • יירוט API פנימי דרך /orchestra/* הוא חזק אבל שברירי. השתמש בו כתרגיל DevTools לצרכים נתונים מסוימים, לא כשיטת החילוץ הראשית.
  • Walmart מגבילה תוצאות חיפוש ל-25 עמודים. הרחב את הכיסוי באמצעות היפוך סדר מיון וחיתוך לפי טווח מחירים.
  • בחר את הגישה בכנות: Python בעצמך למפתחים עם צרכים מותאמים ונפח גבוה. APIs לגריפה לצוותים בינוניים בלי מהנדס גריפה. Thunderbit למשתמשי עסק שרוצים נתונים ב-Google Sheets עוד היום.

אם אתה רוצה לנסות את המסלול ללא קוד, ל-תוסף ה-Chrome של Thunderbit יש תכנית חינמית — אפשר לגרוף כמה דפי Walmart ולראות את התוצאות בעצמך. אם אתה הולך על Python, דפוסי הקוד במאמר הזה נבדקו ב-production. כך או כך, עכשיו יש לך מפה של ההגנות של Walmart ושלושה נתיבים לעבור דרכן.

לעוד על טכניקות גריפת רשת, בדוק את המדריכים שלנו על איך לגרוף web עם Python, הכלים האוטומטיים הטובים ביותר לגריפת web, ו-גריפת web בלי להיחסם. אפשר גם לצפות במדריכים ב-ערוץ YouTube של Thunderbit.

שאלות נפוצות

האם חוקי לגרוף נתוני מוצר מ-Walmart?

תנאי השימוש של Walmart אוסרים גריפה אוטומטית ללא הסכמה בכתב. פסיקת hiQ נגד LinkedIn של המעגל התשיעי (2022) קבעה שסביר להניח שחוק CFAA הפדרלי לא חל על גריפת דפים ציבוריים, אבל אותו מקרה הסתיים בפסיקת הפרת חוזה של 500,000 דולר נגד הגורף. גריפת דפי מוצר ציבוריים בקצב מתון לצורך מחקר אישי נושאת פרופיל סיכון שונה מאוד מחילוץ בקנה מידה מסחרי. התייעץ עם עורך דין אם אתה בונה עסק על נתוני Walmart.

למה ה-scraper שלי ל-Walmart ממשיך להיחסם?

הסיבות הנפוצות ביותר הן: שימוש ב-requests או httpx רגילים (שמייצרים טביעת TLS ייחודית ל-Python שאקמאי מסמן מיד), כותרות חסרות או שגויות, אין rotation של פרוקסי, קצב בקשות מהיר מ-3–6 שניות לעמוד, ועוגיות סשן חסרות (_px3, _abck, locDataV3). עבור ל-curl_cffi עם impersonate="chrome124", השתמש בפרוקסי residential, ויישם את דפוסי זיהוי החסימה וה-retry שמתוארים במאמר הזה.

אילו נתונים אפשר לגרוף מ-Walmart עם Python?

שמות מוצרים, מחירים (נוכחיים ו-rollbacks), תמונות, תיאורים קצרים וארוכים, דירוגים, מספרי ביקורות, סטטוס זמינות במלאי, שמות מוכרים, מידע על יצרן, אפשרויות וריאנטים (מידה, צבע), ומיקום בקטגוריה. באמצעות שיטת __NEXT_DATA__, כל אלה זמינים כ-JSON מובנה. יירוט API פנימי יכול בנוסף להחזיר תמחור ברמת וריאנט, ספירות מלאי בזמן אמת, ונתוני ביקורות מחולקים לעמודים.

האם צריך proxies כדי לגרוף את Walmart?

כן, לכל שימוש ב-production או לשימוש חוזר. מערכות האנטי-בוט של Walmart חוסמות בקשות רגילות בעקביות — גם עם כותרות מושלמות, IP לא-Residential יסומן על ידי מערכת המוניטין של Akamai. נדרשים פרוקסי residential או mobile. כתובות IP של data center נשרפות כמעט מיד. תקציב גס הוא כ-$3–$17 לכל 1,000 דפים, תלוי בספק ובחבילה.

אפשר לגרוף את Walmart בלי לכתוב קוד?

כן. Thunderbit הוא תוסף Chrome מבוסס AI שגורף את Walmart בשתי לחיצות: "AI Suggest Fields" לזיהוי אוטומטי של עמודות נתוני המוצר, ואז "Scrape" כדי לחלץ את הנתונים. הוא מטפל באתגרים של אנטי-בוט בענן ומייצא ישירות ל-Excel, Google Sheets, Airtable או Notion — הכול בחינם. הוא הכי מתאים לאנליסטים, PMs, ומשתמשי עסק שצריכים נתונים מהר בלי לבנות צינור מותאם אישית. עבור גריפה בהיקף גבוה או מותאם מאוד, Python או Scraping API עדיין מתאימים יותר.

נסה את Thunderbit לגריפת Walmart באמצעות AI Get Started Free

למידע נוסף

Shuai Guan
Shuai Guan
מנכ"ל Thunderbit | מומחה לאוטומציה של נתונים באמצעות AI Shuai Guan הוא המנכ"ל של Thunderbit ובוגר הפקולטה להנדסה של אוניברסיטת מישיגן. עם כמעט עשור של ניסיון בטכנולוגיה ובארכיטקטורת SaaS, הוא מתמחה בהפיכת מודלים מורכבים של AI לכלי חילוץ נתונים פרקטיים, ללא קוד. בבלוג הזה הוא משתף תובנות ישירות מהשטח, שנבחנו בפועל, על Web Scraping ואסטרטגיות אוטומציה שיעזרו לכם לבנות תהליכי עבודה חכמים יותר, מבוססי נתונים. כשאינו משפר תהליכי נתונים, הוא מביא את אותה תשומת לב לפרטים גם לתשוקה שלו לצילום.
תוכן עניינים

גרדו דף אינטרנט פשוט על ידי בקשה

תגידו מה צריך באנגלית פשוטה. או אפילו לא צריך להגיד כלום.

נסו את Thunderbit חינם
חילוץ נתונים באמצעות AI
העבירו נתונים בקלות ל-Google Sheets, Airtable או Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week