如何抓取沃尔玛产品数据:JSON、地理价格、阻拦

沃尔玛没有公开API,每个页面都个性化,并通过按住不放的验证码来阻止抓取。但其Next.js JSON为您提供了干净的结构化数据——如果您的IP能通过门禁。以下是完整的方法。

沃尔玛是全球最大的零售商,这使得其定价成为实时经济信号——而没有公开的沃尔玛API来读取它。所以人们进行抓取。好消息是:沃尔玛是一个Next.js网站,每个产品页面都带有一个完整、干净的数据JSON blob。坏消息是:数据中心IP在看到该JSON之前会遇到按住不放的验证码。本指南涵盖了可靠的方法——读取hydration JSON而不是样式化的HTML,使用正确的IP通过HUMAN的机器人防御,并提取店级地理定价。

停止解析标签。读取__NEXT_DATA__ JSON

大多数教程教您找到h1作为标题和span作为价格。这在沃尔玛重新排列其类名之前有效,而这经常发生。持久的方法是:沃尔玛从一个带有id="__NEXT_DATA__"的脚本标签中渲染React,其中包含整个产品模型的JSON。抓取一次,每个字段都是结构化的:

import requests, json
from bs4 import BeautifulSoup

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                  "(KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36",
    "Accept-Language": "en-US,en;q=0.9",
}
proxies = {"http": "http://USER:PASS@gate.quantumproxies.io:8000",
           "https": "http://USER:PASS@gate.quantumproxies.io:8000"}

url = "https://www.walmart.com/ip/1756765288"
r = requests.get(url, headers=headers, proxies=proxies, timeout=20)

soup = BeautifulSoup(r.text, "html.parser")
blob = soup.find("script", id="__NEXT_DATA__")
data = json.loads(blob.string)
product = data["props"]["pageProps"]["initialData"]["data"]["product"]
print(product["name"], product["priceInfo"]["currentPrice"]["price"])

确切的键路径会随着时间变化,所以打印顶级键一次并从那里导航。但原则是:JSON是事实来源,它在一个地方包括价格、可用性、卖家、变体和评级——没有每个字段的选择器会被破坏。

门禁:“机器人还是人类?”

从一个裸露的数据中心IP运行请求,您不会得到产品JSON——您会得到一个页面,上面写着“机器人还是人类?激活并按住按钮以确认您是人类。”这就是HUMAN(前身为PerimeterX),沃尔玛运行的机器人防御层。它将IP信誉、TLS指纹和头信息结合在一起,当得分较低时,它会提供按住不放的挑战。

您不解决那个验证码;您避免触发它。最大的杠杆是IP。一个住宅代理表现为一个真正的沃尔玛购物者的连接,这保持得分足够高以提供真实页面。数据中心范围被预先评分为可疑,并在请求一次时被挡住。我们对HUMAN如何检测自动化的分解涵盖了还有什么影响得分。

抓取沃尔玛产品数据的管道:通过住宅出口到__NEXT_DATA__ JSON和结构化行的产品URL
通过住宅出口路由,然后读取hydration JSON——路径中没有脆弱的HTML选择器。

地理定价:一个产品,多种价格

沃尔玛的价格和库存是店铺特定的。相同的商品根据购物位置显示不同的价格和可用性,因此没有设置位置的抓取器正在读取一个任意的店铺。通过ZIP设置位置以控制您定价的店铺——沃尔玛将其保存在位置cookie中,因此在每次请求时发送它:

# pin the store location by US ZIP before reading price/stock
cookies = {"assortmentStoreId": "3081", "locationData": '{"postalCode":"10001"}'}

r = requests.get(url, headers=headers, cookies=cookies,
                 proxies=proxies, timeout=20)
# now priceInfo + availabilityStatus reflect that store

要在市场间比较产品,循环您的ZIP列表并将每个与该地区的住宅出口配对——一个纽约购物者读取纽约市店铺价格比声称一个位置但在其他地方退出的请求更连贯。这种地理一致性正是竞争对手价格监控赖以生存的。

搜索页面和分页

对于目录工作,抓取搜索结果,而不仅仅是产品页面。需要知道两件事:沃尔玛根据用户个性化搜索排序,因此不要期望在多次运行中有稳定的排名,结果跨越多个页面,您通过page参数分页。相同的__NEXT_DATA__模式适用——搜索JSON携带完整的商品列表及其价格和ID,因此除非您想要变体级别的详细信息,否则很少需要触碰产品页面:

def search(query, pages=5):
    items = []
    for page in range(1, pages + 1):
        url = f"https://www.walmart.com/search?q={query}&page={page}"
        html = requests.get(url, headers=headers, cookies=cookies,
                            proxies=proxies, timeout=20).text
        blob = BeautifulSoup(html, "html.parser").find("script", id="__NEXT_DATA__")
        data = json.loads(blob.string)
        stacks = data["props"]["pageProps"]["initialData"]["searchResult"]["itemStacks"]
        for stack in stacks:
            items += stack["items"]
    return items

何时停止手动操作

原始请求加上住宅IP可以让您在沃尔玛上走很远。停止回报的点是规模:每个请求旋转出口,重试仍然遇到墙的请求,并在数千个ZIP中保持店铺cookie逻辑一致是一个真正的维护负担。一个Scraper API携带浏览器指纹,旋转住宅IP并可以返回解析的JSON,将其压缩为一个调用——您发送一个沃尔玛URL并获得产品模型,阻拦处理。如果您的页面返回为验证码壳而不是数据,那就是经典的空页面症状,这是一个渲染和IP问题,而不是解析器错误。

沃尔玛HUMAN按住不放验证码阻止数据中心IP,而住宅IP通过以获取干净的产品JSON
您不解决按住不放的门禁——您保持您的信任分数足够高以至于它从未出现。

获取可到达沃尔玛的住宅IP

常见问题解答

沃尔玛有产品数据API吗?

没有用于任意产品和价格数据的开放公共API,这就是为什么抓取是常见的途径。沃尔玛的联盟和市场卖家API存在但受到限制且范围有限。对于广泛的产品、价格和可用性收集,通过住宅IP读取页面的__NEXT_DATA__ JSON是实用的方法。

如何在不被阻止的情况下抓取沃尔玛价格?

通过住宅代理路由请求,使HUMAN的机器人防御评分您为真实购物者,发送一致的浏览器User-Agent和Accept-Language,并读取hydration JSON而不是大量选择器请求。通过ZIP cookie固定店铺并保持出口区域与其一致。该组合避免了大多数请求中的按住不放验证码。

为什么沃尔玛对同一产品显示不同价格?

沃尔玛的价格和库存是店铺级别的。您看到的价格取决于会话设置的位置,因此两个不同ZIP位置的请求合法地返回不同的价格。为了收集可比数据,明确固定ZIP并将您的代理出口与该地区匹配,而不是让沃尔玛从IP中猜测。

__NEXT_DATA__ JSON比解析HTML好吗?

是的,为了持久性。沃尔玛的可见类名经常变化,破坏CSS选择器抓取器,但Next.js hydration JSON是产品的稳定结构模型,价格、变体、卖家和可用性都在一个对象中。解析JSON一次,您就避免了一堆脆弱的每字段选择器。

沃尔玛并不难因为数据隐藏——它就在页面JSON中。难的是门禁检查谁在敲门。读取__NEXT_DATA__而不是标签,通过ZIP设置店铺,并用住宅IP敲门,您就能在规模上获得干净、可比的产品数据。对于更广泛的大型零售商价格工作,相同的策略可扩展到Best Buy和Target

通过一个API调用抓取沃尔玛