# 如何抓取 AliExpress 产品数据进行代发货研究

AliExpress 将其产品数据隐藏在一个 JavaScript 变量中，而不是在您看到的 HTML 中。获取该 JSON，您就可以在一次请求中获得价格、折扣、发货地和销售数量——以下是如何通过反封锁技术实现这一点。

AliExpress 是全球最大的市场，也是代发货研究的主要来源：价格和折扣历史、实际销售情况、发货地以及不同国家的报价变化。在 2026 年，它依赖于 JavaScript 渲染和随机化的类名，这让人们害怕启动一个完整的浏览器。通常您不需要这样做。产品数据已经在页面源代码中以 JavaScript 变量的形式存在——提取它，您就可以在一次请求中获得干净的结构化数据。本指南展示了隐藏的 JSON 方法、使 AliExpress 数据有价值的地理维度，以及保持抓取工具正常运行的代理技术。

## 数据在 window.runParams 中，而不是在 DOM 中

打开一个类别或搜索结果页面并查看源代码。所有产品预览都存储在一个名为 `window.runParams` 的 JavaScript 变量中，嵌在一个 `<script>` 标签内。这是一种常见的现代模式——服务器将数据作为 JSON 发送，前端在客户端渲染。对于抓取工具来说，这是一份礼物：您可以完全跳过脆弱的 CSS 选择器，使用正则表达式提取脚本标签，并像字典一样解析它。这种技术称为隐藏网页数据抓取，比追踪每次部署都会更改的类名要持久得多。

```python
import re, json, httpx

HEADERS = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                  "(KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
    "accept-language": "en-US,en;q=0.9",
}

PROXY = "http://USER:PASS@residentialpremium.quantumproxies.io:8080"

def get_run_params(html: str) -> dict:
    # The product data lives in window.runParams = {...};
    m = re.search(r"window\.runParams\s*=\s*(\{.+?\});", html, re.DOTALL)
    if not m:
        raise ValueError("runParams not found - page may be blocked or changed")
    return json.loads(m.group(1))

url = "https://www.aliexpress.com/category/.../catName.html"
r = httpx.get(url, headers=HEADERS, proxy=PROXY, timeout=30)
data = get_run_params(r.text)
```

## 解析研究中重要的字段

`runParams` 数据块很大，因此只提取代发货和定价研究实际使用的字段：列表标题、原价与促销价、折扣百分比、销售数量，以及——至关重要的——发货国家，这决定了交货时间和买家的信任。嵌套看起来很复杂，但它是稳定的：

```python
def parse_items(data: dict) -> list[dict]:
    items = data.get("mods", {}).get("itemList", {}).get("content", [])
    out = []
    for it in items:
        prices = it.get("prices", {})
        sale = prices.get("salePrice", {})
        orig = prices.get("originalPrice", {})
        out.append({
            "id": it.get("productId"),
            "title": it.get("title", {}).get("displayTitle"),
            "sale_price": sale.get("minPrice"),
            "orig_price": orig.get("minPrice"),
            "discount_pct": sale.get("discount"),
            "currency": sale.get("currencyCode"),
            "sold": it.get("trade", {}).get("tradeDesc"),   # e.g. "1,000+ sold"
            "store_id": it.get("store", {}).get("storeId"),
        })
    return out

for row in parse_items(data)[:5]:
    print(row["title"][:40], row["sale_price"], f"-{row['discount_pct']}%", row["sold"])
```

这一单次调用为您提供了产品的经济数据：一个显示原价 $65.85 的列表降至 $23.29 的促销价是 64% 的折扣——这种利润率信号告诉您某个商品是否值得采购。“已售”数量是您的需求代理；在一个类别中综合起来，它可以在您不需要查看评论页面的情况下排名赢家。

![Python 代码抓取一个 AliExpress 页面，用正则表达式在原始 HTML 中找到 window.runParams，用 json.loads 加载，然后遍历 mods.itemList.content；卡片展示了解析出的商品字段：标题、售价、折扣百分比和销量，整个过程无需无头浏览器。](https://res.cloudinary.com/dmqliab0t/image/upload/f_auto,q_auto,w_1200/v1785335163/blog/generated/qp-b9-026-diag1.png)
*列表数据被服务器渲染到一个 JavaScript 变量中——无需无头浏览器即可读取。*

## 搜索分页而不对网站造成负担

搜索页面使用已知长度的分页，因此高效的惯用方法是：抓取第一页，从响应中读取总页数，然后在限制下并发获取其余部分。不要一次性请求所有页面——AliExpress 会积极限制速率，并开始返回 403。保持适度的并发，并在每个请求时轮换出口 IP：

```python
import asyncio, httpx

ROTATING = "http://USER:PASS@residentialpremium.quantumproxies.io:8080"

async def fetch_page(client, query, page):
    url = f"https://www.aliexpress.com/w/wholesale-{query}.html?page={page}"
    for attempt in range(3):
        r = await client.get(url, headers=HEADERS, timeout=30)
        if r.status_code == 200:
            return parse_items(get_run_params(r.text))
        if r.status_code == 403:                 # blocked: back off, rotate exit
            await asyncio.sleep(2 ** attempt)
    return []

async def scrape_search(query, max_pages=5):
    async with httpx.AsyncClient(proxy=ROTATING) as client:
        sem = asyncio.Semaphore(3)               # gentle concurrency
        async def guarded(p):
            async with sem:
                return await fetch_page(client, query, p)
        pages = await asyncio.gather(*[guarded(p) for p in range(1, max_pages + 1)])
        return [row for page in pages for row in page]

results = asyncio.run(scrape_search("wireless earbuds"))
print(len(results), "products")
```

在这里，旋转网关很重要：一个 IP 连续请求页面是最快被封锁的方式，而在 [住宅池](https://quantumproxies.io/residential-proxies) 中进行每次请求的轮换可以分散负载，使没有单个出口看起来异常。对 403 进行指数退避，让被封锁的 IP 有时间轮换出去。

[在 90M+ 住宅 IP 上抓取 AliExpress](https://quantumproxies.io/residential-proxies)

## 地理是重点

AliExpress 根据访问者的位置个性化价格、货币、促销和发货仓库——同一产品可以向美国 IP 显示美国本地卡，提供更快的运输，而向欧洲 IP 显示不同的价格和来源。对于代发货研究来说，这种地理维度就是数据：您想知道目标市场的客户实际看到的是什么。因此，故意设置出口国家。通过每个您销售的市场的 IP 路由，并记录差异；在一个地区便宜且本地发货的产品在另一个地区却慢且昂贵，这是一种非常不同的选择。我们关于 [代发货研究代理](https://quantumproxies.io/blog/proxies-for-dropshipping-research) 的指南深入探讨了如何将这些矩阵转化为采购决策。

```python
# One product, three markets - compare price and ship-from per geo
MARKETS = {
    "us": "http://USER-country-us:PASS@residentialpremium.quantumproxies.io:8080",
    "de": "http://USER-country-de:PASS@residentialpremium.quantumproxies.io:8080",
    "br": "http://USER-country-br:PASS@residentialpremium.quantumproxies.io:8080",
}
for market, proxy in MARKETS.items():
    r = httpx.get(product_url, headers=HEADERS, proxy=proxy, timeout=30)
    d = get_run_params(r.text)
    # read price + shipFrom from the product detail runParams for this geo
    print(market, "->", extract_price_and_origin(d))
```

## 评论和库存在单独的请求中

列表为您提供价格和需求，但两个高价值字段在它们自己的请求后面。客户评论不在产品页面的 `runParams` 中——它们从一个专用的反馈端点加载，分页，因此要收集评分和评论文本，您需要跟随每个产品的调用，而不是解析主页面。库存信号类似：列表上的“已售”数量是一个累计需求代理，而每个变体（颜色、尺寸、发货仓库）的精确可用性来自产品详细信息负载中的 SKU 数据。对于代发货研究来说，这很重要，因为一个产品在价格和销售上看起来像是赢家，而您想销售的特定变体在为您的市场服务的仓库中缺货。

将这两个视为第二次处理：首先抓取列表，根据折扣和已售数量对候选者进行排名，然后仅用评论页面和每个变体的库存丰富您的候选名单。这使请求量——以及您的封锁风险——与您对每个产品的重视程度成比例，而不是对每个列表进行大量请求以获取您不会使用的数据。

## 何时跳过 DIY 抓取工具

隐藏的 JSON 方法是持久的，但 AliExpress 确实会更改负载形状，将评论置于单独的端点后，并在大量请求下升级封锁。如果您不想维护正则表达式和重试逻辑，[Scraper API](https://quantumproxies.io/scraper-api) 接受一个 URL 并返回解析后的 JSON——它处理渲染、轮换和反封锁层，您可以通过单个参数进行地理定位。一旦您计划定期收集跨市场的数千种产品，这是务实的选择。有关直接从客户端负载读取数据的一般模式，请参阅我们关于 [抓取工具返回空页面的原因](https://quantumproxies.io/blog/scraper-returns-empty-page-javascript) 的说明。

![AliExpress 抓取的三个障碍及各自的解决方法：翻几页后出现 403 错误，通过每个请求轮换住宅 IP 解决；价格因国家而异，通过在每个市场使用当地出口解决；runParams 缺失，这本身就是拦截。卡片展示了文中代码里对应的设置。](https://res.cloudinary.com/dmqliab0t/image/upload/f_auto,q_auto,w_1200/v1785335163/blog/generated/qp-b9-026-diag2.png)
*三个障碍，三个解决方案——大多数 AliExpress 抓取工具故障是 IP 质量或地理问题。*

## 常见问题

### 可以抓取 AliExpress 产品数据吗？

可以。公开可见的列表数据——标题、价格、折扣、已售数量、图片和发货地——在类别、搜索和产品页面的 `window.runParams` JavaScript 变量中提供。您可以使用正则表达式提取它，并将其解析为 JSON，而无需为列表使用无头浏览器。请遵守 AliExpress 的条款和速率限制。

### AliExpress 有公共 API 吗？

AliExpress 提供联盟和开放平台 API，但它们需要批准，覆盖范围有限，并与一个项目绑定。对于跨类别和市场的广泛研究，抓取公共页面可以为您提供更多字段和完整的地理控制，这就是为什么大多数代发货研究人员提取页面上的 JSON。

### 为什么抓取 AliExpress 时会出现 403 错误？

403 表示 AliExpress 标记了请求——通常是因为来自一个 IP 的请求过多、数据中心范围或头部设置过少。每次请求轮换住宅 IP，对 403 进行指数退避，发送真实的 User-Agent 和接受语言，并保持低并发。如果 HTML 中缺少 runParams，那是封锁，而不是布局更改。

### 如何获取特定国家的 AliExpress 价格？

通过目标国家的出口 IP 路由请求。AliExpress 读取位置以设置货币、价格、促销和发货仓库，因此美国 IP 和德国 IP 对同一产品看到的数据不同。根据市场对代理进行地理定位，并记录每个版本以建立按地理位置划分的价格矩阵。

获胜的方法是无聊且持久的：读取页面已经提供的 JSON，礼貌地分页，轮换干净的住宅 IP，并对每个您关心的市场进行地理定位。这样做，AliExpress 就成为价格、需求信号和运输经济的可靠来源，而不是 403 的墙。

[从 Scraper API 获取解析后的 AliExpress 数据](https://quantumproxies.io/scraper-api)
