# AliExpress Product Scraper (`mrdoe/aliexpress-product-scraper`) Actor

Extract product data from AliExpress.com anonymously — no login needed. Search by keyword for price, sold count and store info, or pull full product details including specs, images and store profile by product ID. Batch multiple queries or IDs in one run. First 10 rows of every run are free.

- **URL**: https://apify.com/mrdoe/aliexpress-product-scraper.md
- **Developed by:** [MrDoe](https://apify.com/mrdoe) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

![AliExpress Product Scraper hero](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/aliexpress-product-scraper--hero.png)

### What does AliExpress Product Scraper do?

**AliExpress Product Scraper** extracts product data from [AliExpress.com](https://www.aliexpress.com) - keyword search results and full product detail pages - **anonymously, no login, no AliExpress account, no API key**. Two operations live in one actor: search for products by keyword, or look up full detail for one or many product IDs.

### Why use this Actor?

- **Price tracking** - schedule `productDetails` on a cron and diff consecutive runs to catch price drops.
- **Market research / assortment mapping** - `search` gives you ranked results for any keyword, with price, sold count, and store info.
- **Batch, one start fee** - pass a list of keywords or product IDs and one run covers all of them.

### How to use it

![How AliExpress Product Scraper works](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/aliexpress-product-scraper--how-it-works.png)

1. Pick an **Operation**: Product Search or Product Details.
2. Fill the matching field:
   - **Search** → `query` (e.g. `coffee maker`) or `queries` for a batch.
   - **Product Details** → `productId` (e.g. `1005005452938708`) or a full item URL, or `productIds` for a batch.
3. Optionally set `maxItems` to cap total rows.
4. Click **Start**.

There is no page cap on `search` by default - it follows a query through to AliExpress's own reported result count. Batch a lot of keywords and this can produce a very large run; use `maxItems` to bound it.

Batch fields (`queries`/`productIds`) win over their singular counterparts when filled; duplicates and blanks are dropped automatically.

### Input

![AliExpress Product Scraper input options](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/aliexpress-product-scraper--input.png)

| Field                      | Type              | Description                                                                                                                                                                                                                                                                                                      |
| -------------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `operation`                | string (required) | One of: `search`, `productDetails`.                                                                                                                                                                                                                                                                              |
| `query` / `queries`        | string / array    | Search keyword(s). Required by `search`.                                                                                                                                                                                                                                                                         |
| `productId` / `productIds` | string / array    | A numeric AliExpress product ID (e.g. `1005005452938708`) or a full item URL. Used by `productDetails`.                                                                                                                                                                                                          |
| `maxItems`                 | integer           | Caps total rows returned across the run. First 10 rows are free. Leave blank for no cap.                                                                                                                                                                                                                         |
| `proxyConfiguration`       | object            | Optional - leave blank to let the Actor pick a sensible per-operation default. See [Why a real browser only for productDetails?](#why-a-real-browser-only-for-productdetails) and [Why does search use a US proxy but productDetails doesn't?](#why-does-search-use-a-us-proxy-but-productdetails-doesnt) below. |

### Why a real browser only for productDetails?

Live-verified (2026-08-25): a plain, cookie-less HTTP request to an AliExpress search page (`/w/wholesale-{query}.html`) returns the full result set server-side-rendered into an embedded JSON blob (`window._dida_config_._init_data_`) - **no bot protection was encountered at all**, so `search` runs on a lightweight `CheerioCrawler`. Product detail pages are different: the page ships with an empty `window.runParams = {}` and an explicit `window._d_c_.isCSR = true` flag - AliExpress renders the actual product data entirely client-side after load. So `productDetails` drives a real headless browser instead, purely to let that client-side render complete.

### Why does search use a US proxy but productDetails doesn't?

AliExpress geo-detects the requesting IP and returns pricing in the local currency - a non-US IP in testing got Nepali Rupee (NPR) pricing on the exact same product a US visitor sees in USD. For `search`, a US-pinned residential proxy fixes this with no downside, so it's the default.

For `productDetails`, root-caused 2026-08-25: pinning to a US proxy instead reliably redirects the browser from `aliexpress.com` to a *different* domain, `aliexpress.us` (with a re-mapped product ID), which carries its own obfuscated JS bot-challenge that never resolved in testing - on top of that page's already-slow client-side render under residential-proxy latency. Without a US pin, the browser reliably stays on `aliexpress.com` and the page renders (just in whatever currency the exit node's actual country implies, surfaced honestly via the `currency` field). So this Actor's default proxy config is US-pinned for `search` only; `productDetails` gets a country-unpinned residential proxy unless you override `proxyConfiguration` yourself.

### Output

![AliExpress Product Scraper dataset output](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/aliexpress-product-scraper--output.png)

![AliExpress Product Scraper data fields](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/aliexpress-product-scraper--fields.png)

One flat row per item. Search rows carry search-result fields; product-detail rows carry the full page. Every row has `_operation` and `status` (`success` or `error`) so you can split/filter a mixed export.

Search row example:

```json
{
    "_operation": "search",
    "productId": "1005005452938708",
    "title": "Welhome / WPM Electric coffee bean grinder Coffee machine WPM coffee machine cafeteras electricas Niche Zero WPM espresso",
    "price": 89.99,
    "listPrice": 199.99,
    "currency": "USD",
    "soldCount": 8,
    "image": "https://ae-pic-a1.aliexpress-media.com/kf/Sa334b8a3b1964e3db600830d59a180e6q.jpg",
    "productUrl": "https://www.aliexpress.com/item/1005005452938708.html",
    "query": "coffee maker",
    "status": "success"
}
```

Product detail row example:

```json
{
    "_operation": "productDetails",
    "productId": "1005005452938708",
    "title": "Welhome / WPM Electric coffee bean grinder Coffee machine WPM coffee machine cafeteras electricas Niche Zero WPM espresso",
    "price": 89.99,
    "currency": "USD",
    "storeName": "Coffee machine Store",
    "storeUrl": "https://www.aliexpress.com/store/1102188075",
    "soldCount": 8,
    "image": "https://ae-pic-a1.aliexpress-media.com/kf/Sa334b8a3b1964e3db600830d59a180e6q.jpg",
    "images": ["..."],
    "specs": { "Power Source": "Electric", "Model Number": "Niche Zero" },
    "productUrl": "https://www.aliexpress.com/item/1005005452938708.html",
    "status": "success"
}
```

### Pricing

This Actor uses pay-per-event pricing - one small run-start charge, then a per-row charge for each search result or product-detail lookup. See the **Pricing** tab for current rates. Failed lookups land as `status: "error"` rows and are never charged. There is no page cap - `search` runs to AliExpress's own reported result count for each keyword unless you set `maxItems`.

### Limitations

- **No review scraping.** AliExpress fetches reviews via a separately signed API (`mtop.aliexpress.review.pc.list`) - live-verified 2026-08-25: from a non-US proxy the reviews section renders "Due to our system upgrades, this content is currently unavailable in your region" for an anonymous visitor (not a bot-block, the site's own message), and from a US-pinned proxy the whole page instead lands on the bot-walled `aliexpress.us` gateway (see above) before reviews would even be reachable. No anonymous, reliable path to review content was found in this session, so there's no companion review Actor for AliExpress.
- Only the numbers/text AliExpress shows to an anonymous, logged-out visitor are available.
- No item-level star rating is available - the search cards and product page checked in live verification only expose a "sold count" and store-level "Positive Feedback %", not a per-item 1-5 star rating; `rating` is not part of this Actor's output for that reason (rather than emitting an always-null field).
- The product image gallery (`images`) can come back sparse - only the class-name prefix used for gallery thumbnails was verified live, and AliExpress's PDP layout varies somewhat by category.
- AliExpress's embedded JSON key names and CSS class-name prefixes can drift over time; a redesign may need an update.
- `productDetails` is meaningfully slower and less reliable than `search`: its client-side render can take well over 20s under a residential proxy's added latency, and this Actor retries (up to 10 times, with a fresh proxy session each time) rather than failing fast - a single call can take a few minutes in the worst case, though it self-heals. See [Why does search use a US proxy but productDetails doesn't?](#why-does-search-use-a-us-proxy-but-productdetails-doesnt) for the root cause.

### FAQ

**Does AliExpress have a public API?** The AliExpress Open Platform API exists but requires an approved dropshipping/affiliate partner account, not general scraping. This Actor gets you search and product data anonymously, no approval process.

**Do I need an AliExpress account or API key?** No - it runs entirely against AliExpress's public, logged-out web pages.

**Why did I get non-USD pricing?** For `search`, make sure `proxyConfiguration` is left blank (or explicitly US-pinned) - see [Why does search use a US proxy but productDetails doesn't?](#why-does-search-use-a-us-proxy-but-productdetails-doesnt) above. For `productDetails`, non-USD pricing is the expected tradeoff of the default (unpinned) proxy - pin `proxyConfiguration` to US yourself if you'd rather accept the slower, less reliable render in exchange for USD pricing.

### Disclaimer

This Actor is an independent tool, not affiliated with or endorsed by Alibaba Group / AliExpress. It only accesses data AliExpress serves publicly to anonymous visitors. Use it in compliance with AliExpress's Terms of Use and applicable law in your jurisdiction. Found a bug or have a feature request? Use the Issues tab on this Actor's page.

# Actor input Schema

## `operation` (type: `string`):

Which AliExpress data to scrape. One operation per run.

## `query` (type: `string`):

Keyword to search AliExpress, e.g. "coffee maker". Used by the search operation. Defaults to a demo query if left blank.

## `queries` (type: `array`):

Many keywords in one run. Wins over "query" when filled. Duplicates and blanks are dropped.

## `productId` (type: `string`):

A numeric AliExpress product ID (e.g. "1005005452938708") or a full item URL. Used by the productDetails operation. Defaults to a demo product if left blank.

## `productIds` (type: `array`):

Many product IDs or item URLs in one run. Wins over "productId" when filled.

## `maxItems` (type: `integer`):

Caps total rows returned across the whole run (applies to search; productDetails always returns one row per product ID). The first 10 rows of any run are free. Leave blank for no cap - the search operation then follows AliExpress's own reported result count for the query.

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

Leave blank to let the Actor pick automatically: a US-pinned residential proxy for search (keeps pricing in USD - AliExpress geo-detects the IP and returns local-currency pricing otherwise), or a country-unpinned residential proxy for productDetails (root-caused 2026-08-25: pinning that operation to US instead reliably redirects it to aliexpress.us, a separate regional gateway with its own unsolved bot-challenge, on top of that page's already-slow client-side render - see the README's Limitations section). Only set this yourself to override that per-operation default.

## Actor input object example

```json
{
  "operation": "search",
  "query": "coffee maker",
  "productId": "1005005452938708"
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# 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 = {
    "query": "coffee maker",
    "productId": "1005005452938708"
};

// Run the Actor and wait for it to finish
const run = await client.actor("mrdoe/aliexpress-product-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 = {
    "query": "coffee maker",
    "productId": "1005005452938708",
}

# Run the Actor and wait for it to finish
run = client.actor("mrdoe/aliexpress-product-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 '{
  "query": "coffee maker",
  "productId": "1005005452938708"
}' |
apify call mrdoe/aliexpress-product-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mrdoe/aliexpress-product-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/mrgRDkjzn2K4f2gEm/builds/HQKk0jmRrtbNuec0W/openapi.json
