# AliExpress Scraper: Products, Prices, Variants & Search (`dheerajitbhu/aliexpress-scraper`) Actor

Scrape AliExpress search results and product details: prices, discounts, sold counts, ratings, every variant (SKU) with price and stock, store and shipping info. Pinned ship-to country. $2.50 per 1,000 products.

- **URL**: https://apify.com/dheerajitbhu/aliexpress-scraper.md
- **Developed by:** [dheeraj kumar](https://apify.com/dheerajitbhu) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 products

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## AliExpress Scraper: Products, Prices, Variants & Search

Scrape **AliExpress** search results and product pages to JSON, CSV or Excel. You get prices, discounts, sold counts and ratings, plus, with details on, **every variant (SKU) with its price and stock**, item properties, all images, review count, **store info** and **shipping cost and delivery estimate**.

The ship-to country and currency are pinned, so you get consistent prices for the market you care about (US by default). No login needed.

**$2.50 per 1,000 products**, the same price for a search row or a full detail row. Leading AliExpress actors charge $5–9 per 1,000.

> 中文简介：速卖通（AliExpress）商品与搜索采集：价格、折扣、销量、评分；可选商品详情，包括全部 SKU 的价格与库存、属性、图片、评论数、店铺信息、运费与预计送达时间。可指定收货国家和币种。每 1000 个商品 2.5 美元。

### What you can scrape

| Mode | Input | Output |
|---|---|---|
| `search` | keywords, sort (best match, orders, price), up to 60 products per page | one row per product: price, original price, discount, sold, rating, Choice flag, ad flag, delivery tag |
| `search` + `fetchDetails` | the same | the search fields **plus** variants, properties, images, reviews count, store, shipping |
| `product` | product links or ids | full detail rows |

### Pricing (pay per event)

| Event | Price |
|---|---|
| Run start | $0.001 |
| Product row (search or detail) | **$0.0025** |

Error rows are free. `maxChargeUsd` (default $5) stops the run cleanly before it goes over.

### Input examples

```json
{ "mode": "search", "searchQueries": ["bluetooth earbuds"], "maxResults": 120, "sort": "orders" }
```

```json
{ "mode": "search", "searchQueries": ["phone case"], "maxResults": 20, "fetchDetails": true, "shipTo": "DE", "currency": "EUR" }
```

```json
{ "mode": "product", "productUrls": ["https://www.aliexpress.com/item/1005006609906038.html", "1005009893532334"] }
```

### Output example (real detail row, 2026-10-18, lists shortened)

```json
{
  "type": "product", "detail": "full", "detailStatus": "full", "productId": "1005009893532334", "usLocalId": "3256811467917760",
  "url": "https://www.aliexpress.com/item/1005009893532334.html",
  "title": "SK Small Headphones Wireless Bluetooth Headset Sport Sleeping Invisible Comfortable To Wear Bass Earbuds Earphone For All Phones",
  "imageUrl": "https://ae-pic-a1.aliexpress-media.com/kf/Sebab286d68ac4d6183c1a1a8cce21316s.jpg",
  "salePrice": 7.71, "salePriceMax": 7.71, "originalPrice": 33.83, "currency": "USD", "discountPct": 81,
  "rating": 4.8, "reviewsCount": 33, "soldText": "293 sold", "soldCount": 293, "isAd": false, "isChoice": false,
  "tags": ["New shoppers save $24.76", "Free shipping"],
  "variantCount": 3,
  "variants": [{ "skuId": "12000050501217752", "attributes": "Color: Black; Ships From: United States", "salePrice": 7.71, "originalPrice": 33.83, "stock": 1000879, "available": true }],
  "properties": [{ "name": "Material", "value": "Plastic" }],
  "store": { "name": "INSONIXN Audiovisual Store", "storeId": 1104069061, "sellerId": 6000542421, "positiveFeedbackPct": 90.7, "sold180Days": "1,000+", "openedYear": 2, "country": "China", "topRated": false },
  "shipping": { "fee": 0, "feeText": "Free", "company": "USPS Priority Mail", "shipFrom": "United States", "deliveryDaysMin": 4, "deliveryDaysMax": 11, "estimate": "Oct. 22 - Oct. 29" },
  "categoryPath": "44/100000306/63705", "shipTo": "US", "searchQuery": "bluetooth earbuds", "page": 1, "position": 2
}
```

A search row (without `fetchDetails`) has the same identity, price, rating and sold fields, plus `delivery` and `listedAt`.

### `detailStatus`

Every product row carries `detailStatus`, either `"full"` (the per-product page + detail API both came back
clean — variants, store, shipping, etc. are all present) or `"search_only"` (the row only has what the search
results page itself returned). This is the same information `detail` has always carried (`"full"` / `"search"`);
`detailStatus` is the more explicit name and the one to check in code going forward — both fields stay in sync.

With `fetchDetails` off, every row is `search_only` by design — that's just what you asked for. With
`fetchDetails` on, a row still comes back `search_only` when AliExpress blocked every attempt at that one
product's detail page (sliders, rate limits); `detailError` on the row then holds the reason code (e.g.
`"slider"`, `"punish"`, `"network"`). The row isn't dropped or retried forever — you still get the search-level
price/rating/etc. for it, same price, and the run keeps going instead of stalling on one stubborn product.

### Compact output for AI agents

Set **Output format** to `compact` and the run still pushes the same rows to the dataset
at the same price — nothing about billing changes. It additionally writes `OUTPUT_COMPACT`
to the run's key-value store: a lossless columnar JSON encoding of the same rows (one
column-name header plus one array per row, instead of repeating every key name on every
row), which is cheaper to hand to an LLM than the plain dataset JSON.

Measured on a real 130-row export of this actor's product rows (see
`benchmarks/compact-output/` in this repo for methodology and all 5 actors' numbers):

| Tokenizer | Pretty JSON | Minified JSON | Compact | vs Pretty | vs Minified |
|---|---:|---:|---:|---:|---:|
| cl100k_base (GPT-4/3.5) | 42,238 | 32,158 | 23,707 | 43.9% smaller | 26.3% smaller |
| o200k_base (GPT-4o) | 42,425 | 32,461 | 24,154 | 43.1% smaller | 25.6% smaller |

Decoding it back to the normal row objects is five lines of Python:

```python
def decode_columnar(payload):
    cols, marker = payload["columns"], payload["missing"]
    return [{c: v for c, v in zip(cols, row) if v != marker}
            for row in payload["rows"]]
```

### Good to know

- **US listings.** With ship-to US, AliExpress shows aliexpress.us local listings. We return the global `productId`, which works on www.aliexpress.com, and the local id as `usLocalId`.
- **Sponsored results** are flagged `isAd: true`. Use `excludeAds` to skip them.
- **Anti-bot.** AliExpress sometimes shows a slider check. The actor starts a fresh session (new cookies and a new proxy IP), alternates to a mobile client fingerprint if the desktop one keeps getting sliders, and switches to residential proxies (country-matched to `shipTo`) if that keeps failing. If every request is blocked, the run **fails** instead of ending green with 0 rows.
- **Full details are slower than search**, but detail fetches for a page of products run in parallel (`detailConcurrency`, default 4, each with its own proxy session) instead of one at a time — a blocked session doesn't stall the others.
- Reviews text isn't included in v1.

### Reliability

A self-test runs every day (search, sorting, product detail API) to catch layout changes early.

**Keywords:** AliExpress scraper, AliExpress API, AliExpress product data, AliExpress price tracker, AliExpress variants SKU, dropshipping product research, 速卖通采集.

# Actor input Schema

## `mode` (type: `string`):

What to scrape. No login needed.

## `searchQueries` (type: `array`):

Used in 'search' mode. If left empty, the run uses 'phone case' as a sample keyword.

## `maxResults` (type: `integer`):

AliExpress shows 60 products per search page.

## `sort` (type: `string`):

Search result order.

## `fetchDetails` (type: `boolean`):

Also open each product for all variants (SKUs) with prices and stock, properties, all images, review count, store and shipping info. Same price per product, but slower (2 extra requests per product).

## `excludeAds` (type: `boolean`):

Skip products marked as ads in the search results (they're flagged isAd otherwise).

## `productUrls` (type: `array`):

Used in 'product' mode. Example: https://www.aliexpress.com/item/1005006609906038.html or 1005006609906038.

## `shipTo` (type: `string`):

Two-letter country code. Prices, shipping and delivery estimates are for this country (pinned, independent of the proxy location).

## `currency` (type: `string`):

Three-letter currency code, e.g. USD, EUR, GBP.

## `maxVariants` (type: `integer`):

Caps the variants list in detailed rows (variantCount always shows the full number).

## `outputFormat` (type: `string`):

Dataset rows are always pushed and charged the same either way. 'compact' additionally writes OUTPUT_COMPACT to the run's key-value store: a lossless columnar JSON encoding of the same rows that is far cheaper to feed to an LLM and decodes back to the exact same rows.

## `maxChargeUsd` (type: `number`):

Hard spending cap. The run stops cleanly before going over it; rows already delivered are kept.

## `proxyConfiguration` (type: `object`):

Default: Apify datacenter proxy. When AliExpress shows an anti-bot check, the run starts a fresh session; if that keeps failing it switches once to the RESIDENTIAL group automatically. Pick RESIDENTIAL to use it from the start.

## `requestIntervalSecs` (type: `number`):

Polite pacing between requests.

## `detailConcurrency` (type: `integer`):

With 'Fetch full product details' on (or in 'product' mode), how many products to fetch at once. Each worker gets its own proxy session, so one blocked session doesn't stall the others. Higher is faster but hits AliExpress harder; 1 disables parallel fetching.

## Actor input object example

```json
{
  "mode": "search",
  "searchQueries": [
    "phone case"
  ],
  "maxResults": 60,
  "sort": "best_match",
  "fetchDetails": false,
  "excludeAds": false,
  "shipTo": "US",
  "currency": "USD",
  "maxVariants": 100,
  "outputFormat": "standard",
  "maxChargeUsd": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "requestIntervalSecs": 1.5,
  "detailConcurrency": 4
}
```

# Actor output Schema

## `results` (type: `string`):

Product rows (detail: search or full).

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQueries": [
        "phone case"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dheerajitbhu/aliexpress-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchQueries": ["phone case"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("dheerajitbhu/aliexpress-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "phone case"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call dheerajitbhu/aliexpress-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dheerajitbhu/aliexpress-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/RVS5zpM7vefjzSB0q/builds/im8s2SIAjqMhoZopY/openapi.json
