# Lazada Product Search Scraper: 6 Countries, USD & English (`maksim_lazouski/lazada-product-search-scraper`) Actor

Scrape Lazada search and category pages in Singapore, Malaysia, Thailand, the Philippines, Indonesia and Vietnam without login or your own proxy. Price, discount, rating, units sold, seller, prices in USD, optional English titles, and watch lists for price changes. Pay per result.

- **URL**: https://apify.com/maksim_lazouski/lazada-product-search-scraper.md
- **Developed by:** [Maksim Lazouski](https://apify.com/maksim_lazouski) (community)
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.05 / 1,000 product rows

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?

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

### What does Lazada Product Search Scraper do?

Lazada Product Search Scraper reads **search results and category pages** from [Lazada](https://www.lazada.com), the largest online marketplace of Southeast Asia, in **six countries**: Singapore, Malaysia, Thailand, the Philippines, Indonesia and Vietnam. Give it **keywords** or **links of search and category pages** and it returns one clean row per product: price and original price, discount, rating, number of reviews, units sold, seller, where it ships from, stock and picture.

- **No Lazada account, no cookies, no proxy of your own.** Type a keyword, pick a country, press Start. Each search is read from an address in its own country.
- **Search like on the site.** Paste the link of a search or category page with its filters, or use the country, order and price fields.
- **Prices in local money and US dollars**, at the European Central Bank's rate of the day.
- **English titles** as an add-on for Thai, Vietnamese, Indonesian and Malay listings; titles already in English are left alone and not charged.
- **Watch lists** for runs on a schedule: get only new products, price changes and products that went out of stock since the last run.
- **You pay per row** that was read and stored, plus $0.005 when a run starts.

![Example output of Lazada Product Search Scraper: titles in Thai and English, prices, discounts, USD, rating and units sold](https://api.apify.com/v2/key-value-stores/TV7hYdY6BhVu4w53W/records/lazada-output.png)

It runs on the Apify platform, so you also get scheduling, an API, webhooks, integrations, and export of the results to JSON, CSV, Excel or HTML.

### What data can you extract from Lazada?

| Group | Fields |
|---|---|
| Product | id, SKU id, link, title, brand, category ids, picture, sponsored or not |
| Price | price, price before discount, discount in %, the money (SGD, MYR, THB, PHP, IDR, VND), the price as the page shows it, both prices in USD |
| Popularity | rating, number of reviews, units sold as a number and as the page shows it |
| Seller | seller id and name, where the product ships from |
| Stock | in stock or not |
| Search | the search it came from, its place in the results, the country |
| Add-on | `title_en`: the title in English |

### How to scrape Lazada

1. Open the actor and go to the **Input** tab.
2. Type a **search**: a keyword such as `phone case`, `เคสโทรศัพท์` or `ốp lưng`, or paste the link of a Lazada search or category page. One search per line.
3. Pick the **country** for keywords, and the order and price range if you want them. A pasted link keeps its own country and filters.
4. Choose how many **products per search** to return (40 a page, up to 2,000).
5. Turn on **English titles** if you need them.
6. Press **Start**, then open the **Output** tab or export the dataset.

#### Ready-made tasks

Start from a task that is already set up, then change the keyword and the country to your market:

- [Compare phone case prices on Lazada Singapore](https://apify.com/maksim_lazouski/lazada-product-search-scraper/examples/lazada-singapore-phone-case-prices)
- [Lazada Thailand Bluetooth earphones in English](https://apify.com/maksim_lazouski/lazada-product-search-scraper/examples/lazada-thailand-bluetooth-earphones-in-english)
- [Cheapest air fryers on Lazada Malaysia](https://apify.com/maksim_lazouski/lazada-product-search-scraper/examples/lazada-malaysia-air-fryer-prices)
- [Power bank prices and sales on Lazada Philippines](https://apify.com/maksim_lazouski/lazada-product-search-scraper/examples/lazada-philippines-power-bank-prices)
- [Skincare products and prices on Lazada Indonesia](https://apify.com/maksim_lazouski/lazada-product-search-scraper/examples/lazada-indonesia-skincare-products)
- [Lazada Vietnam Bluetooth earphones in English](https://apify.com/maksim_lazouski/lazada-product-search-scraper/examples/lazada-vietnam-bluetooth-earphones-in-english)
- [Get Lazada price changes for a search](https://apify.com/maksim_lazouski/lazada-product-search-scraper/examples/watch-lazada-price-changes)

#### Watch a search for changes

Put a name in **Watch list name** and run the actor on a schedule, for example every day. The first run returns everything, marked `"change": "new"`. Every later run with the same name returns only:

- what is new: a product that came into your search;
- what changed since the last run: price, price before discount, title or stock (`"change": "changed"`, with `changed_fields` and the old values in `previous`);
- what is gone: a product that left a search that was read to its end (`"change": "removed"`). Rows for what is gone are free.

Rows that did not change are not stored and not charged, so a daily check of a market costs only what changed. The **Changes** view of the output shows these rows. A search cut by **Products per search** says nothing about what went beyond the cut. The actor keeps the watch list in a key-value store of your account named `watch-lazada-...`; use one name per list, and one run of it at a time.

```json
{
    "searches": ["https://www.lazada.com.my/catalog/?q=air+fryer&sort=priceasc"],
    "maxItemsPerSearch": 200,
    "watchName": "air fryers MY"
}
```

### How much does it cost to scrape Lazada?

You pay for the rows the actor stores. The price per 1,000 rows depends on your Apify plan:

| What | Free | Starter | Scale | Business |
|---|---|---|---|---|
| A product row | $1.50 | $1.35 | $1.20 | $1.05 |
| English title (add-on, per row that gets one) | $1.00 | $0.90 | $0.80 | $0.70 |

A run also costs $0.005 to start, on every plan. Apify counts the start once per GB of the run's memory: one start at the default 1 GB, four ($0.02) at 4 GB.

The examples below are at the Free plan price, rows only; add $0.005 per run.

- A search of 120 products costs $0.18; with English titles for a Thai search, $0.30.
- 10,000 products cost $15.

You do not pay for searches the actor could not read, for rows of what is gone, or for unchanged rows of a watch list. Apify's free plan comes with $5 of usage a month, which is enough for about 3,300 products.

### Input

| Field | What it does |
|---|---|
| `searches` | Keywords or links of Lazada search, category or brand pages, one per line. |
| `country` | For keywords: `sg` (default), `my`, `th`, `ph`, `id` or `vn`. |
| `sort` | For keywords: `relevance` (default), `price_low`, `price_high`. |
| `priceMin`, `priceMax` | For keywords: a price range in the country's money. |
| `maxItemsPerSearch` | How many products of each search to return: up to 2,000, 120 by default. |
| `translateTitles` | Adds `title_en` to products whose title is not in English. |
| `maxItems` | Stop after this many rows. |
| `maxConcurrency` | How many searches are read at the same time. 5 by default. |
| `watchName` | A watch list's name: each run stores only what is new, changed or gone since the last run with the same name. |

One keyword in three countries, cheapest first:

```json
{
    "searches": [
        "https://www.lazada.sg/catalog/?q=power+bank&sort=priceasc",
        "https://www.lazada.com.my/catalog/?q=power+bank&sort=priceasc",
        "https://www.lazada.co.th/catalog/?q=power+bank&sort=priceasc"
    ],
    "maxItemsPerSearch": 80,
    "translateTitles": true
}
```

### Output

Every row is one product of one search.

```json
{
    "type": "listing",
    "source_query": "phone case",
    "position": 2,
    "country": "sg",
    "item_id": "2374234860",
    "sku_id": "22564517942",
    "url": "https://www.lazada.sg/products/pdp-i2374234860.html",
    "title": "Shieldmonster iPhone Case 18 Pro Max/18 Pro/17 Pro Max/17 Pro/17 ... Clear TPU cover",
    "price": 8.99,
    "original_price": 18.99,
    "discount_percent": 53,
    "currency": "SGD",
    "price_text": "$8.99",
    "price_usd": 6.93,
    "original_price_usd": 14.65,
    "rating": 4.86,
    "reviews": 1367,
    "sold": 6100,
    "sold_text": "6.1K sold",
    "in_stock": true,
    "seller_id": "1149612009",
    "seller_name": "ShieldMonster",
    "location": "Singapore",
    "brand": "Shieldmonster",
    "category_ids": [42062201, 9536, 10002873],
    "image": "https://sg-live-01.slatic.net/p/2c326ecb033f58ab28950f62068732f6.png",
    "sponsored": false,
    "usd_rate": 0.7712,
    "usd_rate_date": "2026-11-03"
}
```

### Limits you should know

- **Search and category pages only.** The actor returns what Lazada shows in its lists of products; it does not open product pages, so there is no full description, variant list or review text.
- **Up to 2,000 products per search** (50 pages of 40), in the order Lazada shows them. How many results a search has is in the run's `SUMMARY` (`search_results_found`).
- **Units sold come rounded** as Lazada shows them: "6.1K sold" is returned as 6100, with the page's own text beside it.
- **No USD for Vietnam:** the ECB publishes no rate for the dong, so rows from Vietnam keep VND only.
- **English titles are machine translation.** Brand and model names may come out odd; the original title is always there.
- **Sponsored products** are in the results where Lazada puts them, marked `"sponsored": true`.

### FAQ

#### Do I need a Lazada account, cookies or a proxy?

No. The actor reads what Lazada shows to a visitor who is not logged in, and brings its own connections in each country.

#### What happens when a search could not be read?

A search that breaks off is read on from the page where it stopped, up to three times in a row. What still fails is listed in the `FAILED` record of the run's key-value store, with the reason; the rows already stored are kept. If Lazada starts showing its check, or the connection is lost, the run does not press on: it waits and tries again with one visitor at a time. If that does not help within a few minutes, the run stops and keeps what it stored; it is marked as failed only when it stored nothing. Start it again with **Resurrect** and it goes on from where it stopped. A row is never stored twice.

#### Can I run it on a schedule or call it from my code?

Yes. Use Apify's schedules with a watch list to follow prices and new products in a market, and the Apify API or its clients for Python and JavaScript to start runs and read results. The `maxItems` field and the run's spending limit keep a run within a budget.

#### Is it legal to scrape Lazada?

The actor reads only what Lazada shows publicly, without logging in: product listings of shops. You are responsible for how you use the data and for following the rules that apply to you; if you are not sure, ask a lawyer.

#### Something is wrong or a field is missing

Open an issue on the actor's **Issues** tab with the search or the link.

Lazada is a trademark of its owner. This actor is not affiliated with or endorsed by Lazada or Alibaba Group.

# Actor input Schema

## `searches` (type: `array`):

One search per line: a keyword (phone case, เคสโทรศัพท์, ốp lưng), or the link of a Lazada search, category or brand page with its filters, such as https://www.lazada.sg/catalog/?q=phone+case\&rating=4. A link keeps its own country and filters; the options below apply to keywords.

## `country` (type: `string`):

For keywords: which Lazada to search.

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

For keywords.

## `priceMin` (type: `integer`):

For keywords, in the local money of the country (SGD, MYR, THB, PHP, IDR, VND). Leave empty for no lower bound.

## `priceMax` (type: `integer`):

For keywords, in the local money of the country. Leave empty for no upper bound.

## `maxItemsPerSearch` (type: `integer`):

How many products of each search to return, in the order Lazada shows them (40 a page). 2,000 is the most; empty means 120.

## `translateTitles` (type: `boolean`):

Adds title_en, the title in English (machine translation), to products whose title is in Thai, Vietnamese, Indonesian, Malay or another language. Titles already in English get none and are not charged. Charged per row that gets one; see the pricing.

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

The run stops once it has stored this many rows. Leave empty for no limit.

## `maxConcurrency` (type: `integer`):

How many searches are read at the same time, each from its own address in its country. More is faster; the default suits most jobs.

## `watchName` (type: `string`):

For runs on a schedule. Give the same name every time: each run then stores only what is new or changed since the last run with that name (a new product, a new price, out of stock), marked in the field change. A product that is gone from a search read to its end is stored once as removed, free. Rows that did not change are not stored and not charged. Leave empty to get every row.

## Actor input object example

```json
{
  "searches": [
    "phone case"
  ],
  "country": "sg",
  "sort": "relevance",
  "maxItemsPerSearch": 40,
  "translateTitles": false,
  "maxConcurrency": 5
}
```

# Actor output Schema

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

One row per product of every search, in the order Lazada shows them.

## `summary` (type: `string`):

How many products were stored, how many results each search has, how many searches failed, and why the run stopped if it did.

## `failed` (type: `string`):

The searches that could not be read, each with the reason. An empty list when everything was read.

# 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 = {
    "searches": [
        "phone case"
    ],
    "maxItemsPerSearch": 40
};

// Run the Actor and wait for it to finish
const run = await client.actor("maksim_lazouski/lazada-product-search-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 = {
    "searches": ["phone case"],
    "maxItemsPerSearch": 40,
}

# Run the Actor and wait for it to finish
run = client.actor("maksim_lazouski/lazada-product-search-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 '{
  "searches": [
    "phone case"
  ],
  "maxItemsPerSearch": 40
}' |
apify call maksim_lazouski/lazada-product-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maksim_lazouski/lazada-product-search-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/Kkp3iLkQBPpvWD5nF/builds/uqNlQUuBZ56cxFX4Y/openapi.json
