Walmart thay đổi giá của một số mặt hàng nhiều lần trong một ngày. Nếu bạn từng cố theo dõi việc đó bằng cách tự động, bạn sẽ hiểu cảm giác này: script chạy được 20 phút, rồi lặng lẽ bắt đầu trả về các trang CAPTCHA được ngụy trang thành phản hồi 200 OK bình thường.
Tôi đã dành rất nhiều thời gian để tìm cách vượt qua các lớp phòng thủ chống bot của Walmart trong công việc trích xuất dữ liệu tại Thunderbit, và tôi muốn chia sẻ tất cả những gì mình học được — những phương pháp thực sự hiệu quả trong năm 2025, các lỗi âm thầm làm bẩn dữ liệu, và những đánh đổi rất thực tế giữa việc tự viết scraper, trả tiền cho một scraping API, hay chỉ dùng một công cụ no-code. Hướng dẫn này bao gồm ba phương pháp trích xuất (phân tích HTML, JSON __NEXT_DATA__, và chặn API nội bộ), cách xử lý lỗi đủ chuẩn production mà hầu hết bài hướng dẫn bỏ qua hoàn toàn, và một khung ra quyết định thẳng thắn để chọn cách tiếp cận phù hợp. Dù bạn đang viết Python hay chỉ muốn có một bảng tính đầy giá cả trước giờ trưa, bài này đều có thứ dành cho bạn.
Vì sao nên thu thập dữ liệu Walmart bằng Python?
Walmart là nhà bán lẻ lớn nhất thế giới theo doanh thu — 680,985 tỷ USD trong năm tài chính 2025, và đã giữ vị trí số 1 trên Fortune Global 500 suốt 12 năm liên tiếp. Trang web này có khoảng 420 triệu danh mục đang hoạt động, trong khi CFO của Walmart từng nhắc đến “nửa tỷ SKU” trên marketplace. Khoảng 95% các danh mục đó đến từ người bán bên thứ ba, nên catalog luôn biến động — người bán thay đổi liên tục, biến thể sản phẩm đổi, và tồn kho cũng đảo theo từng ngày.

Chính sự biến động đó làm cho việc scrape trở nên quan trọng. Một báo cáo hàng quý không thể nắm bắt điều mà một lần thu thập dữ liệu mỗi đêm có thể làm được. Dưới đây là những trường hợp sử dụng phổ biến nhất mà tôi thường thấy:
| Trường hợp sử dụng | Ai cần | Họ trích xuất gì |
|---|---|---|
| Theo dõi giá đối thủ | Vận hành e-commerce, công cụ repricing | Giá, khuyến mãi, tuân thủ MAP |
| Làm giàu catalog sản phẩm | Nhóm bán hàng & merchandising | Mô tả, hình ảnh, thông số, biến thể |
| Theo dõi tình trạng tồn kho | Chuỗi cung ứng, dropshipper | Tình trạng hàng, thông tin người bán |
| Nghiên cứu thị trường & phân tích xu hướng | Marketing, quản lý sản phẩm | Xếp hạng, đánh giá, danh mục |
| Tạo lead | Nhóm bán hàng | Tên người bán, số lượng sản phẩm, danh mục |
Riêng thị trường phần mềm theo dõi giá đối thủ đã đạt 1,92 tỷ USD trong năm 2025 và được dự báo sẽ lên 5,09 tỷ USD vào năm 2033. Hành vi người tiêu dùng thúc đẩy chi tiêu này: 94% khách hàng so sánh giá khi mua sắm online, và 83% mua sắm so sánh trên nhiều website khác nhau.
Python là ngôn ngữ mặc định cho công việc này. Báo cáo Hạ tầng 2026 của Apify cho thấy Python chiếm 71,7% tổng hoạt động web scraping, và thư viện cốt lõi (requests) có khoảng 30 triệu lượt tải mỗi tuần. Nếu bạn scrape ở bất kỳ quy mô nào, gần như chắc chắn bạn đang làm bằng Python.
Vì sao Walmart là một trong những trang khó scrape nhất
Walmart khó scrape một cách đặc biệt vì nó chạy hai sản phẩm chống bot thương mại theo chuỗi: Akamai Bot Manager ở lớp edge WAF và TLS fingerprinting, rồi đến PerimeterX (đã đổi thương hiệu thành HUMAN Security) ở lớp thử thách JavaScript hành vi. Scrape.do mô tả tổ hợp này là “hiếm gặp và cực kỳ khó vượt qua.”

ScrapeOps chấm Walmart 9/10 về độ khó scraping, riêng Akamai cũng ở mức 9/10. Theo trải nghiệm của tôi, con số đó khá sát thực tế.
Đây là những gì bạn thực sự phải đối mặt:
Akamai Bot Manager kiểm tra TLS fingerprint của bạn (JA3/JA4 hash), thứ tự frame HTTP/2, thứ tự và cách viết hoa của header, cùng các cookie phiên (_abck, ak_bmsc). Một lệnh gọi Python requests thông thường sẽ phát ra TLS fingerprint mà không trình duyệt thật nào tạo ra — Akamai sẽ gắn cờ trước khi request của bạn chạm tới máy chủ của Walmart.
PerimeterX/HUMAN chạy sau Akamai, thực thi fingerprinting JavaScript (px.js) để kiểm tra các thuộc tính navigator, rendering canvas, WebGL, audio context, và sinh trắc học hành vi (di chuyển chuột, tốc độ cuộn, động lực gõ phím). Dấu hiệu lỗi nhìn thấy được là thử thách khét tiếng “Press & Hold” — một nút bạn phải giữ khoảng 10 giây trong khi tín hiệu hành vi được lấy mẫu. Oxylabs nói thẳng: “Walmart sử dụng mô hình CAPTCHA ‘Press & Hold’ do PerimeterX cung cấp, vốn gần như không thể giải bằng mã của bạn.”
Hành vi thật sự nguy hiểm là chặn âm thầm. Walmart trả về HTTP 200 nhưng nội dung là CAPTCHA thay vì 403. ScrapingBee xác nhận: “Walmart trả về mã trạng thái 200 OK ngay cả khi phục vụ trang CAPTCHA. Bạn không thể chỉ dựa vào mã trạng thái để biết request của mình có thành công hay không.” Script của bạn sẽ vui vẻ phân tích HTML CAPTCHA như thể là “không tìm thấy sản phẩm” rồi đi tiếp. Nửa bộ dữ liệu của bạn sẽ thành rác, mà bạn còn không biết.
Rồi còn vấn đề dữ liệu phụ thuộc cửa hàng. Giá và tồn kho của Walmart phụ thuộc vị trí, được điều khiển bởi các cookie như locDataV3 và assortmentStoreId. Nếu không có cookie phù hợp, bạn sẽ nhận được dữ liệu “mặc định toàn quốc” — nhìn thì có vẻ đầy đủ nhưng lại không khớp với những gì khách hàng thực sự thấy. Thiếu cookie không tạo ra trang chặn; nó tạo ra dữ liệu sai mà không có lỗi rõ ràng, và đó còn tệ hơn.
Ba cách trích xuất dữ liệu từ Walmart (và so sánh chúng như thế nào)
Trước khi đi vào từng bước, đây là ba cách trích xuất chính. Hầu hết bài hướng dẫn đối thủ chỉ nói đến một hoặc hai cách. Tôi sẽ đi qua cả ba để bạn có thể chọn cách phù hợp nhất với hoàn cảnh của mình.
| Phương pháp | Độ tin cậy | Mức độ đầy đủ của dữ liệu | Độ khó chống bot | Gánh nặng bảo trì |
|---|---|---|---|---|
| HTML + BeautifulSoup | ⚠️ Thấp (selector hỏng theo mỗi lần triển khai) | Trung bình | Cao | Cao |
JSON __NEXT_DATA__ | ✅ Tốt | Cao | Trung bình-cao | Trung bình |
| Chặn API nội bộ | ✅ Tốt nhất | Cao nhất (biến thể, tồn kho, đánh giá) | Trung bình-cao | Thấp (JSON có cấu trúc) |
| Thunderbit (no-code) | ✅ Tốt | Cao | Thấp (AI xử lý) | Không có |
Phân tích HTML là lựa chọn tệ nhất cho Walmart — website này dùng các bundle Next.js với tên class CSS được hash và thay đổi sau mỗi lần deploy. Phương pháp JSON __NEXT_DATA__ là lựa chọn thực dụng mà mọi Walmart scraper mã nguồn mở nghiêm túc trong giai đoạn 2024–2026 đều dùng. Chặn API nội bộ là cách mạnh nhất nhưng đi kèm nhiều lưu ý mà đa số bài hướng dẫn lướt qua. Và Thunderbit là lựa chọn đúng khi bạn không cần một pipeline tùy chỉnh.
Dùng thử Thunderbit để scrape Walmart
Chuẩn bị môi trường Python để scrape Walmart
Bạn cần những gì sau đây:
- Mức độ khó: Trung cấp
- Thời gian cần: Khoảng 30 phút để cài đặt, cộng thêm thời gian viết code
- Bạn sẽ cần: Python 3.10+, pip, một trình soạn thảo code, và (cho môi trường production) một dịch vụ proxy hoặc scraping API
Tạo thư mục dự án và môi trường ảo:
mkdir walmart-scraper && cd walmart-scraper
python -m venv venv
source venv/bin/activate # Trên Windows: venv\Scripts\activate
Cài các thư viện cần thiết:
pip install curl_cffi parsel beautifulsoup4 lxml
curl_cffi là tiêu chuẩn năm 2025 cho việc scrape các mục tiêu khó. Đây là binding cho libcurl có thể giả lập chính xác TLS fingerprint của trình duyệt. Bright Data giải thích: “Walmart dùng TLS fingerprinting như một phần của cơ chế phát hiện bot, và ngay cả việc đặt User-Agent để giả lập trình duyệt thật cũng không đủ để vượt qua.” requests hay httpx thông thường đều không thể qua Akamai, bất kể bạn đặt header gì. curl_cffi với impersonate="chrome124" mới tạo nên khác biệt.
Bạn cũng nên dùng json (có sẵn), csv (có sẵn), time, random, và logging cho các mẫu production mà chúng ta sẽ bàn ở phần sau.
Từng bước: Scrape trang sản phẩm Walmart bằng Python
Bước 1: Gửi request tới trang sản phẩm Walmart
Việc đầu tiên là tạo một request HTTP không bị chặn ngay lập tức. Đây là bộ header tiêu chuẩn được dùng trên Scrapfly, Scrapingdog, Oxylabs và ScrapeOps trong giai đoạn 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)
Tham số impersonate="chrome124" đang gánh phần việc nặng ở đây. Nó bảo curl_cffi khớp chính xác TLS ClientHello, thứ tự frame HTTP/2 và chuỗi pseudo-header của Chrome 124. Nếu không có nó, Akamai sẽ thấy một JA3 hash đặc trưng của Python và chặn bạn trước khi request chạm đến lớp ứng dụng của Walmart.
Phản hồi bị chặn trông như thế nào: Nếu bạn thấy "Robot or human?" trong tiêu đề HTML phản hồi, hoặc nếu phản hồi chuyển hướng tới walmart.com/blocked, nghĩa là bạn đã bị bắt. Điểm khó ở đây là Walmart thường trả về mã trạng thái 200 nhưng nội dung là CAPTCHA — vì vậy kiểm tra response.ok thôi là chưa đủ.
Với bất kỳ trường hợp dùng production hoặc lặp lại nhiều lần, bạn sẽ cần proxy residential. IP datacenter bị Akamai đốt rất nhanh qua hệ thống đánh giá uy tín IP. Tôi sẽ nói kỹ hơn về chiến lược xử lý lỗi và proxy ở phần production bên dưới.
Bước 2: Phân tích dữ liệu sản phẩm từ JSON __NEXT_DATA__
Walmart.com là một ứng dụng Next.js, và HTML được server render nhúng toàn bộ dữ liệu hydration trong một thẻ script duy nhất: <script id="__NEXT_DATA__" type="application/json">. Đây chính là mỏ vàng.
Hướng dẫn 2026 của Scrapfly xác nhận: “Năm 2026, Walmart dùng Next.js với JSON có cấu trúc trong thẻ script __NEXT_DATA__, khiến việc trích xuất dữ liệu ẩn đáng tin cậy hơn so với phân tích CSS selector truyền thống.” Mọi Walmart scraper mã nguồn mở nổi bật — của Scrapfly, của Oxylabs, của python-scrapy-playbook — đều dùng cách này.
Cách trích xuất như sau:
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", {})
Phần lớn bài hướng dẫn dừng ở đây. Dưới đây là bản đồ đường dẫn JSON đầy đủ cho các trường dữ liệu thực sự quan trọng — đã được kiểm chứng trên các trang Walmart thực tế trong giai đoạn 2024–2026:
| Trường dữ liệu | Đường dẫn JSON (bên dưới initialData) | Kiểu | Ghi chú |
|---|---|---|---|
| Tên sản phẩm | data > product > name | Chuỗi | — |
| Thương hiệu | data > product > brand | Chuỗi | — |
| Giá hiện tại (số) | data > product > priceInfo > currentPrice > price | Số thực | Có thể khác theo cookie cửa hàng |
| Giá hiện tại (chuỗi) | data > product > priceInfo > currentPrice > priceString | Chuỗi | Định dạng ví dụ "$9.99" |
| Mô tả ngắn | data > product > shortDescription | Chuỗi HTML | Dùng BeautifulSoup để lấy text |
| Mô tả dài | data > idml > longDescription | Chuỗi HTML | Nằm ở idml, KHÔNG phải trong product — đây là bẫy mà các bài cũ hay sai |
| Tất cả ảnh | data > product > imageInfo > allImages | Mảng | Danh sách object {id, url} |
| Đánh giá trung bình | data > product > averageRating | Số thực | Khóa là averageRating, không phải rating kiểu cũ |
| Số lượt đánh giá | data > product > numberOfReviews | Số nguyên | — |
| Biến thể | data > product > variantCriteria | Mảng | Các nhóm tùy chọn (size, color) |
| Tình trạng còn hàng | data > product > availabilityStatus | Chuỗi | IN_STOCK, OUT_OF_STOCK, LIMITED_STOCK |
| Người bán | data > product > sellerDisplayName | Chuỗi | — |
| Nhà sản xuất | data > product > manufacturerName | Chuỗi | — |
Đường dẫn longDescription là cái bẫy hay khiến người ta dính. Một bài viết của ScrapeHero năm 2023 đặt nó ở product.longDescription, nhưng các nguồn từ năm 2024 trở đi nhất quán đặt nó trên key anh em idml. Hãy luôn đọc idml.longDescription trước, rồi mới fallback sang product.longDescription cho các trang cũ.
Dưới đây là mẫu trích xuất an toàn dùng chuỗi .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"),
}
Với những ai không muốn phải tự lần đường dẫn JSON, AI của Thunderbit sẽ tự động nhận diện và cấu trúc các trường này — không cần map đường dẫn thủ công. Bạn chỉ cần bấm “AI Suggest Fields”, nó đọc trang và trả về một bảng. Nhưng nếu bạn đang xây pipeline riêng, bản đồ phía trên là tài liệu tham chiếu của bạn.
Bước 3: Chặn các endpoint API nội bộ của Walmart để lấy dữ liệu giàu hơn
Không có bài đối thủ nào giải thích đúng cách này. Đây là đường trích xuất mạnh nhất — và cũng phức tạp nhất.
Frontend của Walmart gọi một backend GraphQL liên kết dựa trên Apollo Gateway. Các endpoint nằm dưới www.walmart.com/orchestra/*:
/orchestra/pdp/graphql/...— dữ liệu làm nóng trang sản phẩm + chuyển biến thể/orchestra/snb/graphql/...— phân trang search-n-browse/orchestra/reviews/graphql/...— đánh giá có phân trang
Những endpoint này trả về JSON sạch và có cấu trúc với dữ liệu mà __NEXT_DATA__ đôi khi cắt bớt — giá theo từng biến thể, số lượng tồn kho theo thời gian thực, phân trang đánh giá đầy đủ.
Điểm mà các bài blog thường nói vòng vo: Walmart dùng Apollo persisted queries. Body request chỉ gửi một hash SHA-256 (persistedQuery.sha256Hash), không gửi text query. Nếu server không biết hash đó, bạn sẽ nhận PersistedQueryNotFound. Walmart thay đổi các hash này mỗi khi deploy. Đó là lý do vì sao không có scraper Walmart mã nguồn mở nổi bật nào công khai đoạn code /orchestra/ có thể copy-paste thẳng.
Cách làm thực tế, trung thực là một bài tập với DevTools:
- Mở trang sản phẩm Walmart trong Chrome
- Mở DevTools → tab Network, lọc theo “Fetch/XHR”
- Duyệt trang như bình thường — bấm biến thể, cuộn xuống đánh giá, đổi vị trí cửa hàng
- Quan sát các request tới endpoint
/orchestra/*trả về JSON có dữ liệu sản phẩm - Chuột phải vào request → “Copy as cURL”
- Chuyển lệnh cURL sang Python bằng
curl_cffi
Đây là ví dụ một lần gọi API được phát lại:
import json
from curl_cffi import requests
session = requests.Session(impersonate="chrome124")
# Trước hết, làm nóng phiên bằng cách truy cập trang sản phẩm
session.get("https://www.walmart.com/ip/some-product/1234567", headers=HEADERS)
# Sau đó phát lại lệnh gọi API nội bộ (đã copy từ 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 = {
# Dán đúng body request từ DevTools vào đây
"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()
Bước làm nóng phiên là cực kỳ quan trọng. Cookie PerimeterX của Walmart (_px3, _pxhd, ACID) phải được thiết lập qua lần fetch HTML ban đầu thì request API mới thành công. Không có chúng, bạn sẽ nhận 412 hoặc 403.
Khi nào nên dùng cách này: Khi bạn cần dữ liệu mà __NEXT_DATA__ không có — giá biến thể sâu hơn, đánh giá có phân trang vượt quá batch đầu tiên, hoặc số lượng tồn kho theo thời gian thực. Với đa số trường hợp, __NEXT_DATA__ đã đủ và đơn giản hơn nhiều.
Scrape kết quả tìm kiếm Walmart và nhiều trang
Kết quả tìm kiếm cũng đi theo mẫu __NEXT_DATA__ tương tự, nhưng với một đường dẫn JSON khác:
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"]
# Loại bỏ sản phẩm được tài trợ
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"))
Phân trang hoạt động bằng cách tăng tham số page: &page=1, &page=2, v.v. Nhưng có một giới hạn không được ghi tài liệu: Walmart giới hạn kết quả tìm kiếm ở 25 trang, bất kể tổng số kết quả là bao nhiêu. Scrapfly xác nhận: “Walmart đặt số trang kết quả có thể truy cập tối đa là 25, dù tổng số trang thực tế là bao nhiêu.”
Cách lách để lấy phủ rộng hơn:
- Đảo thứ tự sắp xếp: Chạy cùng truy vấn với
&sort=price_lowrồi&sort=price_highđể lấy khoảng 50 trang phủ - Chia theo khoảng giá: Thêm
&min_price=X&max_price=Yđể tách catalog thành các cửa sổ nhỏ hơn - Chia theo danh mục: Tìm trong từng danh mục cụ thể thay vì quét toàn site
Lưu ý rằng itemStacks là một mảng. Scrapfly hardcode [0] trong repo của họ, nhưng các trang category và browse đôi khi chứa nhiều stack (“Top picks,” “More results”). Cách làm bền vững là duyệt qua tất cả các stack:
for stack in search_result.get("itemStacks", []):
for item in stack.get("items", []):
if item.get("__typename") == "Product":
# xử lý item
pass
Cũng đáng chú ý: robots.txt của Walmart không cho phép /search. Các trang chi tiết sản phẩm (/ip/...) và hầu hết trang danh mục (/cp/...) thì không bị chặn. Nếu bạn lo về tuân thủ, hãy bắt đầu từ trang sản phẩm và cây danh mục thay vì search.
Đừng để các block âm thầm phá hỏng dữ liệu của bạn: xử lý lỗi đủ chuẩn production
Phần lớn hướng dẫn thường vỡ trận ở đây. Họ chỉ cho bạn cách fetch một trang, phân tích một sản phẩm, rồi coi như xong. Trong production, bạn sẽ fetch hàng nghìn trang, và Walmart đang chủ động tìm cách ngăn bạn. Sự khác biệt giữa một scraper demo và một scraper thực sự chạy được nằm ở cách nó xử lý lỗi.
Phát hiện block âm thầm trước khi dữ liệu bị hỏng
Hàm quan trọng nhất trong một Walmart scraper là bộ phát hiện block. Dựa trên sự đồng thuận của các nhà cung cấp như ScrapingBee, Scrapingdog, Oxylabs, và Decodo, bạn cần bốn kiểm tra độc lập:
BLOCK_MARKERS = (
"Robot or human",
"Press & Hold",
"Press & Hold",
"px-captcha",
"perimeterx",
)
def is_walmart_blocked(response) -> bool:
# 1. Chuyển hướng đến endpoint block riêng
if "/blocked" in str(response.url):
return True
# 2. Mã trạng thái cứng
if response.status_code in (403, 412, 428, 429, 503):
return True
# 3. 200 OK nhưng body là CAPTCHA (trường hợp chặn âm thầm)
body = response.text or ""
if any(m.lower() in body.lower() for m in BLOCK_MARKERS):
return True
# 4. Kiểm tra độ dài phản hồi — trang PDP thật thường 300-900 KB
if len(response.content) < 50_000 and "/ip/" in str(response.url):
return True
return False
Kiểm tra thứ tư — độ dài phản hồi — sẽ bắt các trường hợp Walmart trả về một trang rút gọn không có marker CAPTCHA rõ ràng nhưng cũng không chứa dữ liệu sản phẩm bạn cần.
Logic thử lại với backoff hàm mũ và jitter
Khi một request thất bại, bạn không muốn dồn dập bắn tiếp ngay vào Walmart. Mô hình tiêu chuẩn là backoff hàm mũ kèm jitter để làm lệch nhịp retry:
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"Bị giới hạn: {response.status_code}")
if is_walmart_blocked(response):
raise Exception("Phát hiện block âm thầm")
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"Lần thử {attempt + 1} thất bại: {e}. Thử lại sau {wait:.1f}s")
time.sleep(wait)
return None
Phần jitter (random.uniform(0, 3)) không phải để cho đẹp — nó giúp các worker không retry cùng một thời điểm, tránh cả đội scraper cùng dồn vào một giây và kích hoạt bộ phát hiện velocity của Akamai.
Giới hạn tốc độ
Cả Thunderbit lẫn Scrape.do đều hội tụ vào một quy tắc: chờ ngẫu nhiên 3–6 giây cho mỗi request khi scrape Walmart: “hãy giới hạn tốc độ request bằng cách chờ 3–6 giây giữa các lần tải trang và ngẫu nhiên hóa độ trễ.”
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
Ở quy mô lớn, hãy cân nhắc dùng aiolimiter để giới hạn tốc độ trong async:
from aiolimiter import AsyncLimiter
limiter = AsyncLimiter(max_rate=10, time_period=60) # 10 request mỗi phút
Xác thực dữ liệu
Ngay cả khi phản hồi không bị chặn, dữ liệu đã parse vẫn có thể sai (nhầm cửa hàng, payload bị suy giảm). Hãy xác thực trước khi ghi ra output:
def validate_product(product):
"""Trả về True nếu dữ liệu sản phẩm có vẻ hợp lệ."""
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
Ghi log phiên
Theo dõi tỷ lệ thành công theo từng phiên. Khi nó tụt dưới 80% trong 10 phút, có nghĩa là đã có gì đó thay đổi — hoặc IP của bạn đã bị đốt, cookie hết hạn, hoặc Walmart vừa triển khai một quy tắc chống bot mới.
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"Tỷ lệ thành công giảm còn {self.success_rate:.1f}% — hãy cân nhắc xoay proxy hoặc tạm dừng")
Không hào nhoáng. Nhưng đó là thứ giữ cho dữ liệu của bạn sạch.
Python tự làm vs. Scraping API vs. No-code: chọn cách nào để scrape Walmart?
Rất nhiều lập trình viên nhảy ngay vào viết scraper riêng mà không tự hỏi liệu đó có phải là lựa chọn đúng hay không. ScrapeOps chấm Walmart 9/10 về độ khó. Người dùng trên forum mô tả nó là “gần như 9/10” và tự hỏi “liệu một scraping API chuyên dụng có bị quá tay không.” Câu trả lời phụ thuộc vào khối lượng, ngân sách và năng lực kỹ thuật.
| Yếu tố | Python tự làm (requests + proxy) | Scraping API (Oxylabs, Bright Data, v.v.) | Công cụ no-code (Thunderbit) |
|---|---|---|---|
| Thời gian từ lúc bắt đầu đến dòng dữ liệu đầu tiên | Vài giờ | 15–60 phút | Khoảng 2 phút |
| Thời gian để lên production | 40–80 giờ | 4–16 giờ | Khoảng 30 phút |
| Xử lý chống bot | Tự quản lý (khó) | Nhà cung cấp xử lý | Tự động xử lý |
| Chi phí ở quy mô nhỏ (<1K trang/tháng) | Thấp (proxy khoảng 4–8 USD/GB) | Gói khởi điểm 40–49 USD/tháng | Miễn phí–15 USD/tháng |
| Chi phí ở quy mô lớn (100K+ trang/tháng) | Thấp hơn trên mỗi request | Cao hơn trên mỗi request | Tùy biến |
| Mức độ tùy chỉnh | Kiểm soát hoàn toàn | Tham số API | Hạn chế theo giao diện/trường |
| Bảo trì định kỳ | 4–8 giờ/tháng | Gần như không | Không có (AI thích ứng) |
| Phù hợp nhất cho | Lập trình viên xây pipeline tùy chỉnh | Scraping production quy mô trung bình | Người dùng business, trích xuất nhanh một lần |
Khi nào Python tự làm là hợp lý
DIY thắng khi bạn đã có sẵn hợp đồng proxy, cần kiểm soát chặt header, nhắm theo zipcode hoặc nhóm người bán, đang index hàng triệu trang mỗi tháng nên phí API trên từng bản ghi trở nên cộng dồn lớn, hoặc bạn cần đảm bảo on-prem/compliance. Đổi lại là thời gian kỹ thuật thực sự: một Scrapy spider đủ chuẩn production với phân trang, retry, xoay proxy, giả lập TLS, và nhiều schema cho nhiều loại trang sẽ mất 40–80 giờ làm việc của một Python senior, cộng thêm 4–8 giờ mỗi tháng để bảo trì khi Walmart đổi fingerprint.
Khi nào scraping API giúp bạn tiết kiệm thời gian
Scraping API xử lý lớp chống bot để bạn không phải làm. Các benchmark của ScrapeOps cho thấy tỷ lệ thành công 99% cho Zyte API và 98% cho Scrape.do trên Walmart. Giá gói khởi điểm rơi vào khoảng 40–49 USD/tháng cho các công cụ như ScraperAPI, Oxylabs, và Scrapingdog. Nếu bạn là một đội 2–5 kỹ sư và khối lượng scrape nằm trong khoảng 10K–1M trang mỗi tháng, API gần như luôn là lựa chọn đúng. Bạn đổi chi phí trên mỗi request lấy việc không phải bảo trì gì cả.
Khi no-code là lựa chọn đúng
Thunderbit phù hợp với một kiểu người dùng hoàn toàn khác. Nếu bạn là PM, analyst, hay người vận hành e-commerce cần dữ liệu sản phẩm Walmart trong một bảng tính ngay chiều nay — chứ không phải sprint sau — thì công cụ no-code mới là câu trả lời thẳng thắn.
Quy trình làm việc: cài Thunderbit Chrome Extension, mở trang sản phẩm hoặc trang tìm kiếm của Walmart, bấm “AI Suggest Fields”, và AI của Thunderbit sẽ đọc trang rồi gợi ý các cột (tên sản phẩm, giá, đánh giá, v.v.). Bấm “Scrape” là dữ liệu sẽ được đổ vào bảng. Xuất sang Excel, Google Sheets, Airtable, hoặc Notion — đều miễn phí, không có paywall.
Thunderbit xử lý anti-bot trên cloud, nên bạn không phải đụng tới CAPTCHA, proxy hay TLS fingerprinting. AI cũng tự thích ứng với thay đổi giao diện, nên không cần bảo trì. Với người không muốn đụng vào việc lần theo đường dẫn JSON, đây là con đường ít trở ngại nhất.
Hạn chế thẳng thắn: Thunderbit không được xây cho 100K+ trang mỗi ngày. Ngân sách credit và giới hạn cloud khiến việc ingest khối lượng lớn trở nên không kinh tế so với API thô. Bạn cũng không thể cố định một zipcode hay ASN cụ thể trừ khi công cụ hỗ trợ. Với pipeline dài hạn, khối lượng lớn, DIY hoặc scraping API vẫn là hướng đi phù hợp hơn.
Ước tính chi phí nhanh: 1.000 dòng sản phẩm Walmart trên Thunderbit tốn khoảng 2.000 credits (tầm 0,60–1,10 USD trên gói Starter/Pro). Mức này tương đương API Walmart của Oxylabs và rẻ hơn hầu hết scraping API ở tầng hobby khi khối lượng thấp. Kiểm tra giá Thunderbit để xem thông tin mới nhất.
Thu thập dữ liệu sản phẩm Walmart bằng AI Get Started Free
Xuất dữ liệu Walmart đã scrape
Khi đã có dữ liệu, bạn cần đưa nó vào nơi hữu ích. Ba định dạng sau đáp ứng hầu hết nhu cầu:
CSV — định dạng phổ thông nhất mà nhà phân tích thực sự mở được:
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})
Dùng mã hóa utf-8-sig để tương thích với Excel. Ký hiệu BOM giúp Excel không làm méo các ký tự đặc biệt.
JSONL — định dạng production cho pipeline scraping:
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 an toàn khi bị crash (một lần ghi bị ngắt chỉ mất dòng cuối), có thể stream với bộ nhớ cố định, và giữ nguyên dữ liệu lồng nhau như biến thể và đánh giá.
Excel — cho các lần bàn giao nhanh cho analyst:
from openpyxl import Workbook
def export_excel(products, filename="walmart_products.xlsx"):
wb = Workbook(write_only=True)
ws = wb.create_sheet("Products")
ws.append(["Tên", "Giá", "Tình trạng", "Đánh giá", "Lượt đánh giá", "Người bán"])
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 giải quyết luôn câu chuyện xuất dữ liệu cho người không biết Python: một cú nhấp để xuất sang Google Sheets, Airtable, Notion, Excel, CSV và JSON — tất cả đều miễn phí ở gói cơ bản. Với nhu cầu theo dõi định kỳ, tính năng scheduled scraper của Thunderbit có thể tự động chạy trích xuất lặp lại.
Một lưu ý về lịch chạy: đừng dùng GitHub Actions cho scraping Walmart. Máy chạy GitHub Actions nằm trên dải IP Azure mà hệ thống chống bot của Walmart chặn ngay lập tức. Hãy dùng APScheduler trên VPS, hoặc chuyển toàn bộ traffic qua proxy residential.
Nguyên tắc pháp lý và đạo đức khi scrape Walmart
Người dùng trên forum nói rất thẳng về nỗi lo này: “Tôi không ngại chơi trò mèo vờn chuột với các kỹ sư, nhưng hơi sợ đùa với đội pháp lý của họ.”
Điều khoản sử dụng của Walmart nêu rõ việc dùng “bất kỳ robot, spider… hay thiết bị thủ công hoặc tự động nào khác để truy xuất, lập chỉ mục, ‘scrape,’ ‘data mine’ hoặc thu thập bất kỳ Materials nào” mà không có “sự chấp thuận bằng văn bản trước” là bị cấm.
robots.txt của Walmart không cho phép /search, /account, /api/, và hàng chục endpoint nội bộ khác. Các trang chi tiết sản phẩm (/ip/...) và đánh giá (/reviews/product/) thì không bị disallow.
Tiền lệ hiQ v. LinkedIn (Tòa phúc thẩm Khu 9, 2022) cho thấy việc scrape dữ liệu công khai nhiều khả năng không vi phạm CFAA của liên bang. Nhưng chính vụ này sau đó lại kết thúc bằng việc hiQ bị xác định vi phạm User Agreement của LinkedIn và phải chịu phán quyết đồng thuận 500.000 USD. Các phán quyết gần hơn trong năm 2024 (Meta v. Bright Data, X Corp. v. Bright Data) tiếp tục thu hẹp phạm vi CFAA và tạo ra các lập luận phản biện về tiền nhiệm bản quyền, nhưng các phán quyết đó phụ thuộc vào ngôn ngữ ToU cụ thể, điều không khớp một cách trơn tru với Walmart.
Nguyên tắc thực tế: Đừng làm quá tải máy chủ. Tôn trọng rate limit. Đừng scrape dữ liệu cá nhân hay dữ liệu người dùng. Hãy dùng dữ liệu một cách có trách nhiệm. Việc scrape các trang sản phẩm công khai của Walmart với tốc độ vừa phải cho nghiên cứu cá nhân có mức rủi ro rất khác so với scrape ở quy mô thương mại và đi ngược Điều khoản của Walmart. Nếu bạn đang xây sản phẩm dựa trên dữ liệu Walmart, hãy nói chuyện với luật sư và tìm hiểu các affiliate và seller API chính thức của Walmart.
Lưu ý: Đây là thông tin mang tính giáo dục, không phải tư vấn pháp lý.
Kết luận và điểm chính cần nhớ
Scrape Walmart bằng Python là một thử thách độ khó 9/10 vì Walmart dùng cả Akamai lẫn PerimeterX trong lớp chống bot kép. Không phải là không thể — nhưng bạn cần đúng công cụ và đúng mẫu triển khai.
Những điểm chính:
- Trích xuất JSON
__NEXT_DATA__là lựa chọn thực dụng nhất cho hầu hết trường hợp. Đây là cách mà mọi Walmart scraper mã nguồn mở nghiêm túc trong giai đoạn 2024–2026 đều dùng. Đường dẫn cơ bản làprops.pageProps.initialData.data.productcho PDP vàsearchResult.itemStackscho search/browse. curl_cffivớiimpersonate="chrome124"là bắt buộc.requestshayhttpxthông thường không thể vượt qua TLS fingerprinting của Akamai dù bạn có set header gì.- Block âm thầm mới là mối nguy thật sự. Walmart trả về 200 OK với body CAPTCHA. Hãy kiểm tra nội dung phản hồi, không chỉ mã trạng thái.
- Scraper production cần nhiều hơn code cho đường đi thuận lợi. Backoff hàm mũ kèm jitter, phát hiện block qua bốn tín hiệu, giới hạn tốc độ 3–6 giây mỗi request, xác thực dữ liệu, và giám sát sức khỏe phiên đều là bắt buộc.
- Chặn API nội bộ qua
/orchestra/*rất mạnh nhưng dễ gãy. Hãy dùng nó như một bài tập DevTools cho nhu cầu dữ liệu cụ thể, không phải phương pháp trích xuất chính. - Walmart giới hạn kết quả tìm kiếm ở 25 trang. Hãy mở rộng bằng cách đảo thứ tự sắp xếp và chia theo khoảng giá.
- Chọn cách tiếp cận một cách trung thực: Python tự làm cho lập trình viên có nhu cầu tùy chỉnh và khối lượng lớn. Scraping API cho các đội quy mô trung bình không có kỹ sư scraping. Thunderbit cho người dùng business muốn có dữ liệu trong Google Sheets ngay chiều nay.
Nếu bạn muốn thử hướng no-code, Thunderbit Chrome Extension có gói miễn phí — bạn có thể scrape vài trang Walmart và tự xem kết quả. Nếu bạn đi theo hướng Python, các mẫu code trong bài này đã được kiểm chứng trong production. Dù chọn cách nào, giờ bạn đã có bản đồ phòng thủ của Walmart và ba con đường để đi qua nó.
Để tìm hiểu thêm về kỹ thuật web scraping, hãy xem các hướng dẫn của chúng tôi về cách web scrape bằng Python, các công cụ web scraping tự động tốt nhất, và web scraping mà không bị chặn. Bạn cũng có thể xem các video hướng dẫn trên Thunderbit YouTube Channel.
Câu hỏi thường gặp
Có hợp pháp khi scrape dữ liệu sản phẩm Walmart không?
Điều khoản sử dụng của Walmart cấm scraping tự động nếu không có chấp thuận bằng văn bản. Phán quyết hiQ v. LinkedIn của Tòa Khu 9 (2022) cho thấy CFAA của liên bang nhiều khả năng không áp dụng cho việc scrape các trang công khai, nhưng chính vụ đó vẫn kết thúc bằng phán quyết vi phạm hợp đồng trị giá 500.000 USD chống lại bên scrape. Việc scrape các trang sản phẩm công khai ở tốc độ vừa phải cho nghiên cứu cá nhân có mức rủi ro rất khác so với trích xuất ở quy mô thương mại. Hãy hỏi luật sư nếu bạn đang xây dựng doanh nghiệp dựa trên dữ liệu Walmart.
Vì sao scraper Walmart của tôi cứ bị chặn?
Các nguyên nhân phổ biến nhất là: dùng requests hoặc httpx thuần (chúng phát ra TLS fingerprint đặc trưng của Python mà Akamai nhận ra ngay), header thiếu hoặc sai, không xoay proxy, tốc độ request nhanh hơn 3–6 giây mỗi trang, và thiếu cookie phiên (_px3, _abck, locDataV3). Hãy chuyển sang curl_cffi với impersonate="chrome124", dùng proxy residential, và triển khai các mẫu phát hiện block và retry được mô tả trong bài này.
Tôi có thể scrape dữ liệu gì từ Walmart bằng Python?
Tên sản phẩm, giá (hiện tại và rollback), hình ảnh, mô tả ngắn và dài, đánh giá, số lượt đánh giá, tình trạng tồn kho, tên người bán, thông tin nhà sản xuất, các tùy chọn biến thể (size, color), và vị trí danh mục. Khi dùng phương pháp __NEXT_DATA__, tất cả những dữ liệu này đều có sẵn dưới dạng JSON có cấu trúc. Chặn API nội bộ còn có thể trả về giá theo biến thể, số lượng tồn kho theo thời gian thực và dữ liệu đánh giá có phân trang.
Tôi có cần proxy để scrape Walmart không?
Có, cho bất kỳ trường hợp production hoặc dùng lặp lại nào. Hệ thống chống bot của Walmart chặn request thuần rất nhất quán — ngay cả khi header hoàn hảo, IP không phải residential vẫn sẽ bị hệ thống đánh giá uy tín IP của Akamai gắn cờ. Proxy residential hoặc mobile là bắt buộc. IP datacenter gần như bị đốt ngay lập tức. Hãy dự trù khoảng 3–17 USD cho mỗi 1.000 trang, tùy nhà cung cấp proxy và gói dịch vụ.
Tôi có thể scrape Walmart mà không cần viết code không?
Có. Thunderbit là một tiện ích Chrome dùng AI có thể scrape Walmart trong hai cú nhấp: “AI Suggest Fields” để tự nhận diện các cột dữ liệu sản phẩm, rồi “Scrape” để trích xuất dữ liệu. Công cụ này xử lý các thử thách chống bot trên cloud và xuất thẳng sang Excel, Google Sheets, Airtable hoặc Notion — tất cả đều miễn phí. Nó phù hợp nhất cho analyst, PM và người dùng business cần dữ liệu nhanh mà không muốn xây pipeline riêng. Với scraping khối lượng lớn hoặc tùy biến cao, Python hoặc scraping API vẫn phù hợp hơn.
Dùng thử Thunderbit cho AI Walmart scraping Get Started Free
Tìm hiểu thêm
- Thu thập dữ liệu Walmart bằng Python trong năm 2025: Hướng dẫn thực tế
- Cách web scraping mà không bị chặn trong Python
- Web scraping bằng Python: tránh bị chặn với chiến lược proxy thông minh
- Cách viết một web scraper bằng Python: từ đầu đến cuối
- Cách scrape dữ liệu bằng Python: hướng dẫn cho người mới bắt đầu


