Wie man Walmart mit Python ausliest, ohne blockiert zu werden

Zuletzt aktualisiert am April 15, 2026

Walmart는 일부 상품의 가격을 바꿉니다. 이걸 프로그램으로 따라가 보려 한 적이 있다면, 아마 이런 문제를 겪어봤을 거예요. 스크립트는 20분 동안 멀쩡하게 돌아가다가, 갑자기 아무 말 없이 CAPTCHA 페이지를 받아 오는데, 그 응답이 겉보기엔 일반적인 200-OK처럼 보이는 겁니다.

저는 에서 데이터 추출 작업을 하면서 Walmart의 안티봇 방어를 뚫는 데 꽤 많은 시간을 쏟았고, 그 과정에서 배운 걸 전부 정리해 보려 합니다. 2025년에 실제로 통하는 방법들, 조용히 데이터를 망가뜨리는 실패 유형들, 그리고 직접 만든 스크래퍼와 Scraping API, 노코드 툴 사이의 현실적인 선택 기준까지 다룹니다. 이 가이드는 세 가지 추출 방식(HTML 파싱, __NEXT_DATA__ JSON, 내부 API 가로채기), 대부분의 튜토리얼이 빼먹는 운영 수준의 오류 처리, 그리고 적절한 접근법을 고르는 명확한 의사결정 모델까지 포함합니다. Python을 쓰든, 아니면 점심시간 전까지 가격표가 담긴 표만 필요하든, 여기서 필요한 답을 찾을 수 있을 거예요.

Warum Walmart mit Python auslesen?

Walmart는 매출 기준 세계 최대 소매업체로, 에 달했고, 를 지키고 있습니다. 이 사이트에는 약 이 있고, Walmart CFO는 마켓플레이스에서 라고 언급했습니다. 이 중 약 가 올린 상품이라 카탈로그가 엄청나게 역동적입니다. 판매자는 바뀌고, 옵션은 수정되고, 재고는 매일 출렁입니다.

walmart_stats_670d06c6bd.png

바로 그래서 스크래핑이 중요합니다. 분기 보고서는 야간 크롤링이 잡아내는 변화를 따라가지 못합니다. 대표적인 활용 사례는 다음과 같습니다:

활용 사례필요한 사람추출하는 데이터
경쟁사 가격 모니터링이커머스 팀, 리프라이싱 도구가격, 프로모션, MAP 준수 여부
상품 카탈로그 보강세일즈 & 머천다이징설명, 이미지, 사양, 옵션
재고 여부 추적공급망, 드롭쉬퍼재고 상태, 판매자 정보
시장 조사 & 트렌드 분석마케팅, 제품 관리자리뷰, 평점, 카테고리 구성
리드 생성영업팀판매자명, 상품 수, 카테고리

경쟁 가격 모니터링 소프트웨어 시장만 봐도 에 이르렀고, 2033년에는 50.9억 달러까지 성장할 전망입니다. 소비자 행동도 이 수요를 밀어 올립니다. 하고, 83%는 여러 웹사이트를 오가며 확인합니다.

Python은 이 분야의 표준 언어입니다. Apify의 2026 Infrastructure Report에 따르면 으로 이뤄지고, 핵심 라이브러리인 requests됩니다. 어느 정도 규모로 스크래핑을 한다면, 거의 확실히 Python을 쓰고 있을 겁니다.

Warum Walmart zu den schwierigsten Webseiten für Scraping gehört

Walmart가 특히 어려운 이유는, 상용 안티봇 시스템 두 개가 연달아 작동하기 때문입니다. 먼저 가 엣지 WAF와 TLS 지문 검사 계층 역할을 하고, 그다음 가 행동 기반 JavaScript 챌린지를 걸어옵니다. Scrape.do는 이 조합을 “드물고, 우회하기 극도로 어렵다”고 표현합니다.

walmart_antibot_3d67d0119c.png

으로 평가했고, Akamai만 따로 놓고 봐도 9/10입니다. 제 경험으로도 그 평가는 꽤 정확합니다.

핵심은 이렇습니다:

Akamai Bot Manager는 TLS 지문(JA3/JA4 해시), HTTP/2 프레임 순서, 헤더의 순서와 대소문자, 그리고 세션 쿠키(_abck, ak_bmsc)를 검사합니다. 일반적인 Python requests는 실제 브라우저가 만들지 않는 TLS 지문을 보내기 때문에, 요청이 Walmart 서버에 닿기도 전에 Akamai가 알아챕니다.

PerimeterX/HUMAN은 Akamai 뒤에서 다시 한번 JavaScript 지문 채집(px.js)을 실행해 Navigator 속성, Canvas 렌더링, WebGL, Audio Context, 그리고 마우스 이동·스크롤 속도·키 입력 패턴 같은 행동 생체 신호를 분석합니다. 이 과정은 악명 높은 로 드러납니다. 버튼을 약 10초간 누르고 있어야 하며, 그동안 행동 신호가 측정됩니다. Oxylabs는 이를 아주 직설적으로 설명합니다. “Walmart는 PerimeterX의 'Press & Hold' CAPTCHA 모델을 사용하며, 코드만으로는 사실상 풀 수 없다.”

가장 위험한 부분은 조용한 차단입니다. Walmart는 403 대신 종종 HTTP 200과 CAPTCHA 내용을 돌려줍니다. 했습니다. “Walmart는 CAPTCHA 페이지를 내보내도 200-OK 상태코드를 반환합니다. 따라서 상태코드만으로 요청 성공 여부를 판단할 수 없습니다.” 그러면 스크립트는 CAPTCHA HTML을 그냥 “상품을 찾을 수 없음” 정도로 파싱해 버리고 계속 돌아갑니다. 결국 데이터셋 절반이 쓰레기가 되는데도 모릅니다.

또 하나는 지역 의존 데이터 문제입니다. Walmart의 가격과 재고는 위치에 따라 달라지고, locDataV3, assortmentStoreId 같은 쿠키로 제어됩니다. 올바른 쿠키가 없으면 “전국 표준 데이터”처럼 보이는 값을 받게 되는데, 겉보기엔 멀쩡하지만 실제 고객 화면과는 다를 수 있습니다. 쿠키가 없다고 차단 페이지가 뜨는 게 아니라, 틀린 데이터를 아무 경고 없이 주는 것이라 더 위험합니다.

Drei Methoden, um Daten von Walmart zu extrahieren (und wie sie sich unterscheiden)

실무로 들어가기 전에, 먼저 세 가지 핵심 추출 방식을 보겠습니다. 경쟁 글 대부분은 하나나 둘만 다루지만, 여기서는 실제 선택에 도움이 되도록 셋 다 설명합니다.

방법신뢰도데이터 완성도안티봇 난이도유지보수 부담
HTML + BeautifulSoup⚠️ 낮음(배포 때마다 셀렉터가 깨짐)중간높음높음
__NEXT_DATA__ JSON✅ 좋음높음중간~높음중간
내부 API 엔드포인트 가로채기✅ 가장 좋음가장 높음(옵션, 재고, 리뷰 포함)중간~높음낮음(구조화된 JSON)
Thunderbit (노코드)✅ 좋음높음낮음(AI가 처리)없음

Walmart에서는 HTML 파싱이 가장 별로입니다. 사이트는 해시된 CSS 클래스명을 쓰는 Next.js 번들을 사용하며, 이 클래스는 배포할 때마다 바뀝니다. __NEXT_DATA__ JSON 방식은 2024~2026 사이의 진지한 오픈소스 Walmart 스크래퍼들이 거의 공통으로 쓰는 실용적인 선택입니다. 내부 API를 가로채는 방식은 가장 강력하지만, 대부분의 튜토리얼이 숨기는 함정이 있습니다. Thunderbit은 아예 자체 파이프라인을 만들 필요가 없을 때 적합합니다.

Python-Umgebung für das Walmart-Scraping einrichten

필요한 것은 다음과 같습니다:

  • 난이도: 중간
  • 소요 시간: 초기 설정 약 30분, 그 뒤 개발 시간 추가
  • 필수: Python 3.10+, pip, 코드 에디터, 그리고 실전 운영용으로는 프록시 서비스나 Scraping API

프로젝트 폴더와 가상환경을 만듭니다:

1mkdir walmart-scraper && cd walmart-scraper
2python -m venv venv
3source venv/bin/activate  # Windows에서는: venv\Scripts\activate

필요한 라이브러리를 설치합니다:

1pip install curl_cffi parsel beautifulsoup4 lxml

curl_cffi는 2025년에 어려운 대상에 붙일 표준 도구입니다. libcurl 래퍼로서 실제 브라우저의 TLS 지문을 매우 정밀하게 흉내 낼 수 있습니다. . “Walmart는 봇 탐지의 일부로 TLS 지문을 사용하며, User-Agent만 바꿔서는 이를 우회할 수 없다.” 일반적인 requestshttpx는 헤더를 아무리 바꿔도 Akamai를 통과하지 못합니다. 반면 curl_cffiimpersonate="chrome124"를 주면 상황이 달라집니다.

추가로 json(내장), csv(내장), time, random, logging도 함께 쓰게 될 겁니다. 아래 운영 패턴에서 필요합니다.

Schritt für Schritt: Walmart-Produktseiten mit Python auslesen

Schritt 1: Die Walmart-Produktseite abrufen

첫 단계는 곧바로 막히지 않는 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가 종종 200 상태코드와 CAPTCHA 내용을 함께 준다는 점이라, response.ok만 확인하면 안 됩니다.

실전이나 반복 작업을 하려면 Residential Proxy가 필요합니다. 데이터센터 IP는 Akamai의 IP 평판 시스템에서 바로 소모됩니다. 오류 처리와 프록시 운용은 아래 운영 파트에서 자세히 다룹니다.

Schritt 2: Produktdaten aus __NEXT_DATA__-JSON parsen

Walmart.com은 Next.js 기반이고, 서버 렌더링된 HTML 안에 전체 hydration payload를 단일 script 태그로 넣습니다. 바로 <script id="__NEXT_DATA__" type="application/json"> 입니다. 여기야말로 핵심 데이터가 들어 있는 자리입니다.

합니다. “2026년 Walmart는 __NEXT_DATA__ script 태그에 구조화된 JSON을 넣는 Next.js를 사용하므로, 숨은 데이터를 뽑는 데 CSS 셀렉터 파싱보다 더 안정적이다.” 2024~2026년의 주요 오픈소스 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 > name문자열
브랜드data > product > brand문자열
현재 가격(숫자)data > product > priceInfo > currentPrice > pricefloat스토어 쿠키에 따라 달라질 수 있음
현재 가격(텍스트)data > product > priceInfo > currentPrice > priceString문자열예: "$9.99"
짧은 설명data > product > shortDescriptionHTML 문자열텍스트가 필요하면 BeautifulSoup로 파싱
긴 설명data > idml > longDescriptionHTML 문자열product가 아니라 idml에 있음 — 오래된 튜토리얼이 자주 틀리는 부분
모든 이미지data > product > imageInfo > allImages배열{id, url} 객체 목록
평균 평점data > product > averageRatingfloat키 이름은 rating이 아니라 averageRating
리뷰 수data > product > numberOfReviews정수
옵션data > product > variantCriteria배열사이즈, 색상 같은 옵션 그룹
재고 상태data > product > availabilityStatus문자열IN_STOCK, OUT_OF_STOCK, LIMITED_STOCK
판매자data > product > sellerDisplayName문자열
제조사data > product > manufacturerName문자열

longDescription는 많이들 빠지는 함정입니다. 2023년 ScrapeHero 글은 아직 product.longDescription 아래에 있다고 했지만, 2024년 이후 소스들은 일관되게 인접한 idml 키에 넣고 있습니다. 그래서 항상 먼저 idml.longDescription을 읽고, 아주 오래된 페이지에 한해서만 product.longDescription으로 fallback 하세요.

안전한 추출 패턴은 .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 Suggest Fields”만 누르면 페이지를 분석해 바로 표로 만들어 줍니다. 하지만 직접 파이프라인을 짠다면, 위 맵이 기준점이 됩니다.

Schritt 3: Walmarts interne API-Endpunkte für umfangreichere Daten abfangen

경쟁 글들 중 이 방법을 제대로 설명하는 경우는 거의 없습니다. 사실 가장 강력한 방식이지만, 동시에 가장 까다롭습니다.

Walmart 프론트엔드는 를 사용합니다. 엔드포인트는 www.walmart.com/orchestra/* 아래에 있습니다:

  • /orchestra/pdp/graphql/... — 상품 상세 hydration + 옵션 변경
  • /orchestra/snb/graphql/... — Search-N-Browse 페이지네이션
  • /orchestra/reviews/graphql/... — 페이지네이션된 리뷰

이 API들은 __NEXT_DATA__에 일부만 들어 있는 데이터보다 더 구조화된 JSON을 줍니다. 예를 들어 옵션별 가격, 실시간 재고, 여러 페이지에 걸친 전체 리뷰 같은 것들입니다.

블로그 글들이 자주 빼먹는 핵심: Walmart는 를 씁니다. 요청 본문에는 실제 쿼리 텍스트가 아니라 SHA-256 해시(persistedQuery.sha256Hash)만 들어갑니다. 서버가 이 해시를 모르면 PersistedQueryNotFound가 뜹니다. Walmart는 배포할 때 이 해시를 바꾸기도 합니다. 그래서 대형 오픈소스 Walmart 스크래퍼들도 /orchestra/용 단순 복붙 예제를 잘 공개하지 않습니다.

현실적인 방법은 DevTools를 쓰는 겁니다:

  1. Chrome에서 Walmart 상품 페이지를 엽니다
  2. DevTools → Network 탭을 열고 “Fetch/XHR”로 필터링합니다
  3. 페이지에서 평소처럼 움직입니다 — 옵션 클릭, 리뷰 스크롤, 스토어 위치 변경
  4. /orchestra/*로 가는 요청 중 상품 데이터를 돌려주는 것을 찾습니다
  5. 요청을 우클릭한 뒤 “Copy as cURL”을 선택합니다
  6. 그 cURL을 curl_cffi로 Python에 옮깁니다

예를 들면 이런 식입니다:

1import json
2from curl_cffi import requests
3session = requests.Session(impersonate="chrome124")
4# 먼저 상품 페이지 HTML로 세션을 예열합니다
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": "your-copied-correlation-id",
14}
15payload = {
16    # DevTools에서 복사한 정확한 요청 본문을 넣습니다
17    "variables": {"productId": "1234567"},
18    "extensions": {
19        "persistedQuery": {
20            "version": 1,
21            "sha256Hash": "the-hash-you-copied"
22        }
23    }
24}
25api_response = session.post(api_url, headers=api_headers, json=payload)
26api_data = api_response.json()

세션을 먼저 예열하는 단계가 아주 중요합니다. Walmart의 PerimeterX 쿠키(_px3, _pxhd, ACID)는 첫 HTML 요청을 통해 설정되어야 API 호출이 동작합니다. 그게 없으면 412나 403을 받게 됩니다.

이 방법이 적합한 경우: __NEXT_DATA__에 없는 데이터가 필요할 때, 예를 들어 더 깊은 옵션별 가격, 페이지를 넘긴 리뷰, 또는 실시간 재고를 봐야 할 때입니다. 대부분의 경우는 __NEXT_DATA__만으로 충분하고 훨씬 간단합니다.

Walmart-Suchergebnisse und mehrere Seiten auslesen

검색 결과도 같은 __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            # 항목 처리
5            pass

또 하나, Walmart의 robots.txt합니다. 반면 상품 상세 페이지(/ip/...)와 대부분의 카테고리 페이지(/cp/...)는 금지되어 있지 않습니다. 컴플라이언스가 중요하다면 검색 페이지보다 상품 페이지와 카테고리 구조부터 시작하는 게 좋습니다.

Lassen Sie stille Blocks nicht Ihre Daten ruinieren: Produktionsreife Fehlerbehandlung

대부분의 튜토리얼은 여기서 무너집니다. 페이지 한 장 가져오고, 상품 하나 파싱하고, 끝내 버리거든요. 하지만 운영 환경에서는 수천 페이지를 긁어야 하고, Walmart는 적극적으로 막아섭니다. 데모 스크래퍼와 제대로 동작하는 스크래퍼의 차이는 오류 처리에 있습니다.

Stille Blocks erkennen, bevor sie Ihre Daten verfälschen

Walmart 스크래퍼에서 가장 중요한 함수는 차단 감지기입니다. , , , 의 공통된 권고를 보면, 독립적인 네 가지 검사가 필요합니다:

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

네 번째 검사인 응답 길이는, Walmart가 겉으론 CAPTCHA 표식이 없지만 필요한 상품 데이터도 없는 축소 페이지를 던질 때 잡아냅니다.

Retry-Logik mit exponentiellem Backoff und Jitter

요청이 실패했다고 바로 다음 요청으로 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("조용한 차단 감지")
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 + 1} 실패: {e}. {wait:.1f}초 후 재시도")
20            time.sleep(wait)
21    return None

지터(random.uniform(0, 3))는 단순한 장식이 아닙니다. 워커들을 서로 엇갈리게 만들어서, 전체 스크래퍼 군집이 같은 초에 다시 요청을 보내며 Akamai의 속도 탐지에 걸리는 일을 막아 줍니다.

Rate Limiting

모두 Walmart에 대해 요청 간 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)  # 분당 10회 요청

데이터 검증

응답이 차단되지 않았더라도, 추출한 데이터가 틀릴 수 있습니다(잘못된 스토어, 축소된 payload). 출력에 쓰기 전에 검증하세요:

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

Session-Logging

세션별 성공률을 추적하세요. 10분 동안 80% 아래로 떨어지면 뭔가 바뀐 겁니다. IP가 소모됐거나, 쿠키가 만료됐거나, 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"성공률이 {self.success_rate:.1f}%로 떨어졌습니다 — 프록시를 바꾸거나 잠시 멈추세요")

화려하진 않지만, 이런 장치가 있어야 데이터가 깨끗하게 유지됩니다.

DIY-Python vs. Scraping-API vs. No-Code: Der richtige Weg für Walmart

많은 개발자들이 먼저 직접 스크래퍼를 만들지만, 그게 정말 맞는 선택인지 확인하지는 않습니다. 으로 봅니다. 포럼 사용자들도 “사실상 9/10”이라고 부르며, 전용 Web Scraping API가 과한지 고민합니다. 답은 볼륨, 예산, 엔지니어링 역량에 달려 있습니다.

요소DIY-Python (requests + 프록시)Scraping API (Oxylabs, Bright Data 등)노코드 툴(Thunderbit)
첫 결과까지 걸리는 시간몇 시간15~60분약 2분
운영 가능한 수준까지40~80시간4~16시간약 30분
안티봇 처리직접 해결해야 함(어려움)제공업체가 처리자동 처리
소규모 비용(<월 1K 페이지)낮음(프록시 약 4~8달러/GB)시작 요금 40~49달러/월무료~15달러/월
대규모 비용(월 10만+ 페이지)요청당 비용이 더 낮음요청당 비용이 더 높음변동
커스터마이징완전 통제API 파라미터UI/필드에 제한됨
유지보수월 4~8시간거의 없음없음(AI가 적응)
적합한 대상자체 파이프라인을 가진 개발자중간 규모 운영비즈니스 사용자, 빠른 1회성 추출

Wann sich DIY-Python lohnt

이미 프록시 계약이 있고, 헤더·우편번호 타기팅·판매자 그룹을 세밀하게 통제해야 하며, 월 수백만 페이지를 인덱싱해야 하고 API 수수료가 쌓이면 부담이 될 때 DIY가 맞습니다. 또 사내 설치나 컴플라이언스 제약이 있을 때도 그렇습니다. 대신 진짜 엔지니어링 비용이 듭니다. 페이지네이션, 재시도, 프록시 로테이션, TLS 임퍼소네이션, 여러 페이지 유형의 스키마를 갖춘 운영 수준의 Scrapy 스파이더는 이 들고, Walmart의 지문 체계가 바뀔 때마다 매달 4~8시간의 유지보수도 필요합니다.

Wann eine Scraping-API Zeit spart

Scraping API는 안티봇 계층을 대신 처리합니다. 에 따르면 Walmart에서 , **Scrape.do는 98%**의 성공률을 보였습니다. , , 같은 도구의 시작 가격은 월 40~49달러 수준입니다. 2~5명 규모의 팀이고 월 1만~100만 페이지를 긁는다면, API가 거의 항상 맞는 선택입니다. 요청당 비용을 내는 대신 유지보수를 거의 없애는 셈이죠.

Wann No-Code die richtige Wahl ist

은 전혀 다른 사용자군을 위한 도구입니다. PM, 애널리스트, 이커머스 운영 담당자처럼 “다음 스프린트”가 아니라 “오늘 안에” Walmart 상품 데이터를 표로 보고 싶다면, 노코드가 가장 솔직한 답입니다.

방법은 간단합니다. 을 설치하고, Walmart 상품 페이지나 검색 페이지를 연 뒤, “AI Suggest Fields”를 누르세요. 그러면 Thunderbit의 AI가 페이지를 읽고 상품명, 가격, 평점 같은 열을 제안합니다. 이어서 “Scrape”를 누르면 데이터가 표로 들어갑니다. Excel, Google Sheets, Airtable, Notion으로 내보내기도 무료입니다.

Thunderbit은 클라우드에서 안티봇 처리를 해 주므로, CAPTCHA, 프록시, TLS 지문 때문에 골치 아플 일이 없습니다. AI가 레이아웃 변경에도 자동 적응하니 유지보수 부담도 거의 없습니다. JSON 경로를 다루고 싶지 않은 사람에게 가장 잘 맞습니다.

솔직한 한계도 있습니다. Thunderbit은 하루 10만+ 페이지급 고속 수집용으로 설계된 도구는 아닙니다. 크레딧 예산과 클라우드 제한 때문에 고속 대량 수집은 원시 API보다 경제성이 떨어질 수 있습니다. 특정 우편번호나 ASN을 정교하게 지정해야 할 때도 툴이 지원하지 않으면 어렵습니다. 계속 돌아가는 고볼륨 파이프라인에는 여전히 DIY나 Scraping API가 더 낫습니다.

대략적인 가격 감각: Walmart 상품 1,000행은 Thunderbit에서 약 2,000 크레딧(Starter/Pro 기준 대략 0.60~1.10달러) 정도입니다. 이 정도면 Oxylabs의 Walmart API와 비슷한 수준이고, 소규모에서는 대부분의 취미용 Scraping API보다 저렴합니다. 에서 확인할 수 있습니다.

Ihre extrahierten Walmart-Daten exportieren

데이터를 뽑아냈다면, 이제 쓸 수 있는 포맷으로 내보내야 합니다. 대부분의 경우 다음 세 가지면 충분합니다:

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

utf-8-sig를 쓰면 Excel이 파일을 제대로 읽습니다. BOM이 들어가야 특수문자가 깨지지 않습니다.

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

합니다. 쓰다가 중단돼도 마지막 줄만 잃을 뿐이고, 메모리도 일정하게 쓰면서 스트리밍할 수 있으며, 옵션과 리뷰처럼 중첩된 데이터도 그대로 보존합니다.

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의 Scheduled Scraper 기능으로 정기 추출도 자동화할 수 있습니다.

스케줄링에 대한 주의점 하나: . GitHub Actions 러너는 Azure IP 대역을 쓰기 때문에 Walmart의 안티봇 시스템에 바로 막힙니다. VPS에서 APScheduler를 쓰거나, 트래픽 전체를 Residential Proxy로 우회하세요.

Rechtliche und ethische Leitlinien für das Scraping von Walmart

포럼에서는 이런 걱정을 아주 솔직하게 말합니다. “개발자랑 술래잡기 하는 건 괜찮지만, 법무팀은 건드리고 싶지 않다.”

Walmart의 이용약관 “로봇, 스파이더, 기타 수동 또는 자동 수단”을 써서, “사전 서면 동의” 없이 자료를 가져오거나 인덱싱하거나 “scrape”, “data mine”하거나 수집하는 행위를 금지합니다.

Walmart의 robots.txt합니다: /search, /account, /api/ 및 수많은 내부 엔드포인트가 차단됩니다. 반면 상품 상세 페이지(/ip/...)와 리뷰(/reviews/product/)는 막혀 있지 않습니다.

hiQ 대 LinkedIn 판례(9th Circuit, )는 공개 데이터 스크래핑이 연방 CFAA를 위반하지 않을 가능성이 높다고 봤습니다. 하지만 같은 법원은 이후 고 판단했고, 을 내렸습니다. 2024년의 더 최근 판결들(, )은 CFAA 적용 범위를 더 좁히고 저작권 선점(preemption) 논리를 강화했지만, 이 판결들은 매우 구체적인 ToU 문구에 달려 있었고 Walmart에 그대로 적용되지는 않습니다.

실무 지침: 서버를 과부하시키지 마세요. Rate limit을 지키세요. 개인정보나 사용자 데이터를 긁지 마세요. 데이터를 책임 있게 쓰세요. 공개된 Walmart 상품 페이지를 적당한 속도로 연구 목적으로 스크래핑하는 것과, Walmart 약관을 정면으로 거스르는 상업적 수집은 전혀 다른 위험 프로필입니다. Walmart 데이터를 기반으로 제품을 만들 계획이라면 법률 자문을 받고, Walmart의 공식 를 확인하세요.

참고: 이 글은 교육 목적일 뿐이며, 법률 자문이 아닙니다.

Fazit und wichtigste Erkenntnisse

Walmart를 Python으로 스크래핑하는 일은 Akamai와 PerimeterX의 이중 방어층 때문에 에 가깝습니다. 불가능한 건 아니지만, 올바른 도구와 패턴이 필요합니다.

핵심 정리:

  • __NEXT_DATA__ JSON 추출은 대부분의 경우 가장 실용적인 선택입니다. 2024~2026년 진지한 오픈소스 Walmart 스크래퍼들이 이 방법을 씁니다. PDP의 기본 경로는 props.pageProps.initialData.data.product, 검색/브라우즈는 searchResult.itemStacks입니다.
  • curl_cffiimpersonate="chrome124"는 필수입니다. 일반 requestshttpx는 헤더를 바꿔도 Akamai의 TLS 지문 검사를 통과하지 못합니다.
  • 조용한 차단이 진짜 위험입니다. Walmart는 CAPTCHA 내용과 함께 200 OK를 줄 수 있습니다. 상태 코드만 보지 말고 응답 내용을 검사하세요.
  • 운영용 스크래퍼에는 Happy Path 코드만으로는 부족합니다. 지터가 포함된 지수 백오프, 네 가지 신호로 하는 차단 탐지, 요청당 3~6초 레이트 리미팅, 데이터 검증, 세션 상태 모니터링이 필요합니다.
  • 내부 /orchestra/* API 가로채기는 강력하지만 깨지기 쉽습니다. 주요 추출 방식이 아니라, 구체적인 데이터가 필요할 때 DevTools로 활용하는 보조 수단으로 쓰세요.
  • Walmart는 검색 결과를 25페이지로 제한합니다. 더 넓게 보려면 정렬 순서를 바꾸거나 가격 범위를 잘라서 나눠야 합니다.
  • 접근법은 솔직하게 고르세요: 맞춤 요건과 대용량 처리가 필요한 개발자라면 DIY Python. 전담 스크래핑 엔지니어 없이 중간 규모로 운영하는 팀이라면 Scraping API. 오늘 바로 Google Sheets에서 데이터를 보고 싶은 비즈니스 사용자라면 .

노코드 방식을 시험해 보고 싶다면, 에는 무료 플랜이 있어 Walmart 페이지 몇 개를 직접 스크래핑해 볼 수 있습니다. Python을 쓴다면 이 글의 코드 패턴은 실전 검증을 거쳤습니다. 어느 쪽이든 이제 Walmart의 방어 체계를 이해했고, 그 안을 통과하는 세 가지 길도 알게 된 셈입니다.

더 많은 Web Scraping 기술이 궁금하다면 , , 가이드를 참고하세요. 에서도 튜토리얼을 볼 수 있습니다.

FAQs

Walmart의 이용약관은 서면 동의 없는 자동 스크래핑을 금지합니다. 9th Circuit의 hiQ 대 LinkedIn (2022) 판결은 공개 페이지 스크래핑이 연방 CFAA를 위반하지 않을 가능성이 높다고 봤지만, 같은 사건은 스크래퍼 측에 로 끝났습니다. 공개 상품 페이지를 적당한 범위에서 개인 연구용으로 스크래핑하는 것과, 상업적으로 데이터를 수집하는 건 법적으로 전혀 다른 문제입니다. Walmart 데이터 위에 비즈니스를 올릴 생각이라면 법률 자문을 받으세요.

Warum wird mein Walmart-Scraper ständig blockiert?

가장 흔한 원인은 다음과 같습니다: 일반 requestshttpx 사용(Python 특유의 TLS 지문을 Akamai가 바로 감지), 잘못되거나 부족한 헤더, 프록시 로테이션 없음, 페이지당 3~6초 미만의 과도한 요청 속도, 그리고 세션 쿠키(_px3, _abck, locDataV3) 누락. impersonate="chrome124"가 설정된 curl_cffi로 바꾸고, Residential Proxy를 쓰고, 이 글에서 설명한 차단 탐지 및 재시도 패턴을 구현하세요.

Welche Daten kann ich mit Python von Walmart auslesen?

상품명, 가격(현재가와 할인 가격), 이미지, 짧고 긴 설명, 평점, 리뷰 수, 재고 상태, 판매자명, 제조사 정보, 옵션(사이즈, 색상), 카테고리 매핑까지 가능합니다. __NEXT_DATA__ 방식을 쓰면 이런 데이터가 모두 구조화된 JSON으로 들어 있습니다. 내부 API를 가로채면 옵션별 가격, 실시간 재고, 페이지네이션된 리뷰까지 추가로 얻을 수 있습니다.

Brauche ich Proxys, um Walmart zu scrapen?

네, 운영용이나 반복 작업이라면 필요합니다. — 헤더가 완벽해도 비-residential IP는 Akamai의 IP 평판 시스템에 걸립니다. Residential 또는 Mobile Proxy가 필요합니다. 데이터센터 IP는 거의 즉시 소모됩니다. 프록시 공급자와 요금제에 따라 1,000페이지당 대략 3~17달러를 예상하면 됩니다.

Kann ich Walmart ohne Code scrapen?

네. 은 AI 기반 Chrome 확장 프로그램으로, 두 번의 클릭만으로 Walmart를 읽습니다. 먼저 “AI Suggest Fields”로 상품 열을 자동 인식하고, 다음에 “Scrape”로 데이터를 추출합니다. 안티봇 이슈는 클라우드에서 처리되고, Excel, Google Sheets, Airtable, Notion으로 바로 내보낼 수 있으며, 모두 무료입니다. 분석가, PM, 비즈니스 사용자처럼 빠르게 데이터를 확보해야 하는 사람에게 특히 적합합니다. 다만 대용량이거나 매우 맞춤화된 스크래핑에는 여전히 Python이나 Scraping API가 더 낫습니다.

AI 기반 Walmart 스크래핑을 위해 Thunderbit 체험하기

Mehr erfahren

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.
Inhaltsverzeichnis

Teste Thunderbit

Leads und andere Daten in nur 2 Klicks scrapen. Unterstützt durch KI.

Thunderbit holen Es ist kostenlos
Daten mit KI extrahieren
Daten einfach zu Google Sheets, Airtable oder Notion übertragen
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week