# Made-in-China Product Scraper (`axiomworks/made-in-china-products-scraper`) Actor

Turn Made-in-China product searches into structured rows with product titles and IDs, price and MOQ text, supplier names and links, membership, location, and available ratings and images. It reads search cards only, and deduplicates repeated product IDs.

- **URL**: https://apify.com/axiomworks/made-in-china-products-scraper.md
- **Developed by:** [Axiom Works](https://apify.com/axiomworks) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.48 / 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?

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

**Returns:** one row per product with title, productId, price, moq, supplier, location, membership, and imageUrl.
**Input:** `{"searchTerms":["LED light"],"maxItems":30}`
**Best for:** supplier discovery, product catalog research, and comparing minimum order quantities.

```json
{"productId":"rahpWFfYaMcu","title":"150W Dimmable LED UFO Warehouse High Bay Light Fixture","price":"US\u002414.50-17.50","moq":"100 Pieces","supplier":"Ningbo ALVA Electric Appliance Co., Ltd.","location":"Zhejiang, China","membership":"Diamond Member"}
```

### What does Made in China Product Scraper do?

Made in China Product Scraper collects product cards from public Made-in-China.com search result pages. Give it one or more product keywords, or a search result URL, and it returns structured product and supplier information. Each row represents one product listing found on a search page. A stable product identifier lets you combine runs and remove repeats from later analysis.

The Actor searches the site's hot product result pages. It reads the title, product link, displayed price, minimum order quantity, supplier link, badges, location, business type, rating when shown, and the main image link. It can parse numeric price bounds and minimum order values from the displayed text. The original price and minimum order text remain in the output so you can check those parsed values.

This Made-in-China scraper is useful when you need a repeatable export from a product search. For example, you can compare suppliers for a product category, create a research list with public supplier links, or watch how the visible result set changes over time. It is a search result collector, so details that appear only on a separate product page are outside the output. Search result order can change, and ads can repeat a listing; the Actor keeps each product ID once per run.

No login is needed. The Actor reads public pages and does not submit inquiries or contact suppliers. It is an independent tool and is not affiliated with Made-in-China.com. Product and supplier information comes from the site's current search cards, so treat it as a starting point for research and verify any purchasing decision with the supplier.

### What data can you get?

The dataset has one row per unique product ID. Fields can be null when a search card does not show that value. The `sourceUrl` field identifies the search result page used to create the row. The `productUrl` and `supplierUrl` fields are links shown on that page; collecting a row does not mean those linked pages were opened.

| Field | Meaning |
| --- | --- |
| `id` | Stable identifier for the product, equal to `productId`. |
| `productId` | Identifier found in the product link. |
| `title` | Product title as displayed in the search card. |
| `productUrl` | Public product page linked by the title. |
| `price` | Original displayed price text. |
| `priceMin` | First numeric amount parsed from the displayed price. |
| `priceMax` | Second numeric amount, or the sole amount if only one appears. |
| `currency` | `USD` when the displayed price begins with the `US$` marker; otherwise null. |
| `moq` | Displayed minimum order quantity text. |
| `moqValue` | Numeric quantity parsed from `moq`, such as `100` from `100 Pieces`. |
| `supplier` | Name of the supplier shown on the card. |
| `supplierUrl` | Public supplier page linked by the card. |
| `membership` | Visible supplier membership label, when present. |
| `auditedSupplier` | Whether the card shows an audited supplier badge. |
| `businessType` | Business type displayed for the supplier, when present. |
| `location` | Supplier location displayed on the card. |
| `rating` | Numeric rating when a rating appears on the card. |
| `imageUrl` | Main image URL from the product card. |
| `imageUrls` | All gallery image links shown on the card (array). |
| `moqUnit` | Unit of the minimum order, such as `Pieces` or `Meters`. |
| `sampleAvailable` | Whether the card's listing data flags sample orders. |
| `rushOrderAvailable` | Whether the card's listing data flags rush orders. |
| `rank` | Position of the row among accepted cards for its search target, from 1. |
| `sourceUrl` | Search result page where the row was found. |

The source site can omit a field from some cards. A missing `rating` does not imply a low rating; it means no rating was read from that card. Similarly, `auditedSupplier` reflects the badge in the result card, while membership and business type are text shown in the card. Numeric fields are simple parsing of visible text, not a currency conversion or a quote from the supplier.

The Actor deduplicates rows by product ID across search terms and pages. The run stops at `maxItems`, the page limit, or a page with no product cards.

### How to use

Open the Actor input form and enter a keyword in **Search terms**. A common first run is `LED light` with the prefilled result limit. Run the Actor, then open the dataset to inspect or download the rows. Each result includes its product and supplier links, so you can move from a row to the relevant public page if you need to verify the details.

To search several topics in one run, enter multiple terms in the list. The Actor processes them in order and combines unique products until `maxItems` is reached. If you set `maxItems` smaller than the number of products on the first page, the dataset contains only that requested number. If you want to collect a specific public search page, put its URL in `startUrls`. You can use URLs and keywords together; URL searches run first.

The search pages are paginated. Page one uses the keyword path, and later pages use a numeric suffix in the same path. `maxPagesPerQuery` controls how many pages the Actor may fetch for each keyword or start URL. A page without product cards ends that target. The Actor makes requests sequentially with at least one second between search page requests and backs off when the site blocks or rate limits a request.

The default proxy setting uses Apify Proxy. A blocked datacenter request can be retried through a fresh residential session when that option is available in your account. If the site remains unavailable, the run reports a clear failure or finishes with the results already collected. A search that has no products finishes with an empty dataset and a warning. Avoid using unrelated URLs: `startUrls` accepts only public Made-in-China hot product search pages.

### Input

| Field | Required | Default | Use |
| --- | --- | --- | --- |
| `searchTerms` | Yes in the form | None for API calls | Product keywords, such as `LED light`; supply this or `startUrls`. |
| `startUrls` | No | Empty list | Public hot product search result URLs. |
| `maxItems` | No | `50` | Maximum number of unique product rows across the run. |
| `maxPagesPerQuery` | No | `10` | Maximum pages to fetch per keyword or URL. |
| `minPrice` | No | None | Keep products whose displayed price range reaches at least this US$ amount. |
| `maxPrice` | No | None | Keep products whose lowest displayed price is at most this US$ amount. |
| `maxMoq` | No | None | Keep products whose parsed MOQ number is at most this value. |
| `auditedOnly` | No | `false` | Keep only products from suppliers with the Audited Supplier badge. |
| `proxyConfiguration` | No | Apify Proxy | Proxy settings for public search page requests. |

The Console form prepopulates a sample search, a result limit, and a page limit. `maxItems` accepts a whole number from 1 through 10000. `maxPagesPerQuery` accepts a whole number from 1 through 100. The optional filters run on each card before it counts toward `maxItems`, so a strict filter may need a higher page limit.

```json
{
  "searchTerms": ["LED light", "electric bicycle"],
  "startUrls": [],
  "maxItems": 40,
  "maxPagesPerQuery": 5,
  "proxyConfiguration": {"useApifyProxy": true}
}
```

Each start URL must point to a Made-in-China hot product search HTML page; invalid targets are rejected before any data is collected. Empty and duplicate terms are removed.

### Output

This row shows the structure of a product card from the initial source probe; values change as listings change. New rows also carry `imageUrls`, `moqUnit`, `sampleAvailable`, `rushOrderAvailable` and `rank`.

```json
{
  "id": "rahpWFfYaMcu",
  "productId": "rahpWFfYaMcu",
  "title": "150W Dimmable LED UFO Warehouse High Bay Light Fixture",
  "price": "US\u002414.50-17.50",
  "priceMin": 14.5,
  "priceMax": 17.5,
  "currency": "USD",
  "moq": "100 Pieces",
  "moqValue": 100,
  "supplier": "Ningbo ALVA Electric Appliance Co., Ltd.",
  "supplierUrl": "https://alvaled.en.made-in-china.com",
  "membership": "Diamond Member",
  "auditedSupplier": true,
  "businessType": "Trading Company",
  "location": "Zhejiang, China",
  "rating": null,
  "imageUrl": "https://image.made-in-china.com/43f34j00hEqcKfQCJoVr/150W-Dimmable-LED-UFO-Warehouse-High-Bay-Light-Fixture.webp",
  "productUrl": "https://alvaled.en.made-in-china.com/product/rahpWFfYaMcu/China-150W-Dimmable-LED-UFO-Warehouse-High-Bay-Light-Fixture.html",
  "sourceUrl": "https://www.made-in-china.com/products-search/hot-china-products/LED_Light.html"
}
```

The raw text fields help you interpret parsed numbers. For a single amount, `priceMin` and `priceMax` contain the same numeric value. For a range, they contain the first and second values respectively. `moqValue` removes separators from the number while `moq` keeps the site's original unit text. Verify current terms with the supplier before buying.

### How much does it cost?

The Actor is charged per result row saved to the dataset. The input limit controls how many result rows it can return, and only rows actually pushed are charged. Check the Actor's Pricing tab for the current event rate and any account-specific information. Empty searches do not create result rows. A repeated product ID within one run is skipped and does not become another result row.

A small trial with a narrow keyword and a low `maxItems` value is a practical way to inspect the data shape. When you know the output suits your task, increase the result and page limits. The Actor stops collecting as soon as it reaches the result limit or the run's applicable spending limit. The price of products shown in search results is source data and has no connection to the Actor's billing.

### Use with AI agents (MCP)

You can make the Actor available as a tool through Apify MCP. Configure an MCP server with this URL, using the Store path for the Actor:

```text
https://mcp.apify.com/?tools=axiomworks/made-in-china-products-scraper
```

An agent can call the tool with `searchTerms`, `maxItems`, and `maxPagesPerQuery`, then read the dataset rows. Field names such as `supplier`, `moq`, `priceMin`, and `location` make it possible to ask the agent to group or compare the results. The agent should report what the dataset shows and keep source URLs available for verification.

Example prompts include: “Find up to 20 LED light listings and group their suppliers by location.” Another is: “Collect public electric bicycle products and show the minimum order quantity alongside each supplier.” You can also ask: “Compare the visible price ranges for yoga mat products and include the product URLs.” These prompts use fields present in the output, without implying that the Actor can contact suppliers, verify stock, or negotiate an order.

For repeated research, save the returned product IDs and compare them with a later run. If an agent combines this dataset with another source, make clear which claims came from these search cards and which came from elsewhere.

### Integrations and API

Use the Apify API to start a run and fetch its default dataset. The examples below show the input shape and dataset access pattern. Replace the token placeholder with your own Apify API token in your client environment. Keep tokens out of shared scripts and source control.

Python example:

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("axiomworks/made-in-china-products-scraper").call(
    run_input={"searchTerms": ["LED light"], "maxItems": 20}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["productId"], item["supplier"], item["moq"])
```

JavaScript example:

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('axiomworks/made-in-china-products-scraper').call({
  searchTerms: ['LED light'], maxItems: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const item of items) {
  process.stdout.write(`${item.productId} ${item.supplier} ${item.moq}\n`);
}
```

cURL example:

```bash
curl -X POST 'https://api.apify.com/v2/acts/axiomworks~made-in-china-products-scraper/runs' \
  -H 'Authorization: Bearer YOUR_APIFY_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"searchTerms":["LED light"],"maxItems":20}'
```

After the run finishes, use the run's default dataset ID to retrieve items. A dataset can be exported in formats supported by Apify. If you use the Actor in a scheduled workflow, keep the input limits and downstream storage capacity in mind. A row's `sourceUrl` is the page where the card was collected; use it when auditing a change or investigating a missing value.

### FAQ

**Can I search more than one keyword?** Yes. Put several strings in `searchTerms`. The Actor processes them sequentially and stops at the overall `maxItems` limit. Duplicates are removed by product ID, even when terms overlap.

**Can I start from a search URL?** Yes. Use `startUrls` with a public Made-in-China hot product search result page. The URL is validated before a request is made. You can combine URLs with search terms in one run.

**Why are some fields null?** Search cards do not always show every value. Rating and business type may be absent, and some cards may show a price or minimum order quantity differently. Null means the value was not extracted from that card.

**What if a search has no results?** The Actor finishes with an empty dataset and a warning when the page is reachable but has no product cards. An unreachable or blocked page produces a clear error if no results were collected.

**Does it fetch every product page?** No. It extracts the public search cards, including links to product and supplier pages. Those URLs are output fields; they are not extra pages fetched by this Actor.

**How does pagination work?** The Actor follows numbered search page paths for each target. It stops at `maxPagesPerQuery`, `maxItems`, or the first page without product cards. Site changes may affect which results appear on a page.

**What does the audited flag mean?** It records whether an audited supplier badge appears on the result card. It is a visible badge indicator, not an independent audit performed by this Actor.

### Is it legal to scrape Made-in-China?

This Actor reads publicly accessible search result pages without a login. The legality of a particular use depends on your location, the data involved, and what you do with it. Review applicable law and the site's current terms before using the output at scale. Respect privacy and intellectual property rights when storing, sharing, or republishing data. This Actor is independent of Made-in-China.com and does not claim site endorsement.

The Actor uses modest sequential request rates and backs off from blocks. It does not solve CAPTCHAs, enter private areas, or submit inquiries. If access is blocked, try again later or reduce the scope of your run. Keep source URLs with any derived analysis so another person can verify the public listing that produced a row.

### Feedback

If a field stops appearing or a search returns unexpected results, report the keyword or public search URL, the run ID, and which fields were missing. Search page HTML can change, and a concrete example helps reproduce a selector problem. Do not include account credentials, API tokens, or private supplier messages in feedback.

# Actor input Schema

## `searchTerms` (type: `array`):

Product keywords to search on Made-in-China.com, e.g. \["LED light", "yoga mat"]. Any language works; English gives the most results. One run = one search per keyword, all sharing the maxItems budget. A keyword with no matches returns 0 rows and a status message; change the wording.

## `startUrls` (type: `array`):

Optional. Full made-in-china.com search result URLs, e.g. https://www.made-in-china.com/products-search/hot-china-products/solar_panel.html. Each is paged like a keyword and runs before searchTerms. Product or supplier page URLs are not supported and return 0 rows.

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

Maximum product rows for the whole run (shared across all keywords and URLs), 1-10000, default 50. Filters are applied first, so only matching rows count. About 30 rows per page.

## `maxPagesPerQuery` (type: `integer`):

Maximum search pages to fetch per keyword or URL, 1-100, default 10 (about 30 products per page). Lower it to finish faster.

## `minPrice` (type: `number`):

Optional. Keep only products whose displayed price range reaches at least this US$ amount, e.g. 1.5. Leave empty for no lower bound.

## `maxPrice` (type: `number`):

Optional. Keep only products whose lowest displayed price is at most this US$ amount, e.g. 20. Leave empty for no upper bound.

## `maxMoq` (type: `integer`):

Optional. Keep only products whose minimum order quantity number is at most this value, e.g. 100. Products without a parsable MOQ are skipped when set.

## `auditedOnly` (type: `boolean`):

If true, keep only products from suppliers shown with the Audited Supplier badge. Default false.

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

Apify Proxy settings for search requests. Datacenter proxy is the default; blocked requests retry through a fresh residential session when available.

## Actor input object example

```json
{
  "searchTerms": [
    "LED light"
  ],
  "startUrls": [],
  "maxItems": 30,
  "maxPagesPerQuery": 10,
  "auditedOnly": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Dataset with one item per result, in the order found.

# 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 = {
    "searchTerms": [
        "LED light"
    ],
    "startUrls": [],
    "maxItems": 30,
    "maxPagesPerQuery": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axiomworks/made-in-china-products-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 = {
    "searchTerms": ["LED light"],
    "startUrls": [],
    "maxItems": 30,
    "maxPagesPerQuery": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("axiomworks/made-in-china-products-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 '{
  "searchTerms": [
    "LED light"
  ],
  "startUrls": [],
  "maxItems": 30,
  "maxPagesPerQuery": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call axiomworks/made-in-china-products-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,axiomworks/made-in-china-products-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/gd0HaXEQft6oE07WV/builds/ZDHizRyVHoMKg66t8/openapi.json
