# Made-in-China Scraper — Products, Suppliers, Prices & MOQ (`tortuga/made-in-china-scraper`) Actor

Scrape Made-in-China.com search results and product pages: title, FOB price range, MOQ, supplier name, location, member level, audit badge, images and product URL. Any keyword or category URL.

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

## Pricing

from $3.00 / 1,000 product scrapeds

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

## Made-in-China Scraper

Scrape Made-in-China.com wholesale listings from any keyword search, keyword landing page or category: product title, FOB price range, minimum order quantity (MOQ), key specifications, images, Secured Trading / sample / video badges and the supplier's name, province, Diamond or Gold membership, audited status, business type and rating. Turn on **Include product details** to also get price tiers by quantity, all product attributes (HS code, model, packaging, production capacity, lead time), variants, payment terms, nearest port, description, video and the audited supplier profile (year established, employees, plant area, registered capital, incoterms, main products, certifications, OEM/ODM service, review score).

Built for reliability: plain HTTP with browser TLS fingerprinting, no headless browser, no login. Made-in-China.com renders its listing cards and product pages server-side, so the scraper reads them directly and falls back to the schema.org JSON-LD the site embeds. You pay only for the products you get.

See also the companion actor for Alibaba.com: [Alibaba Product Scraper](https://apify.com/tortuga/alibaba-scraper), with the same input and output shape.

### What data does Made-in-China Scraper extract?

Every product from a search, landing or category page:

| Field | Description |
|---|---|
| `productId` | Made-in-China product ID (the code in the product URL) |
| `title` | Product title |
| `url` | Product page URL on the supplier's showroom |
| `priceMin`, `priceMax` | Lowest and highest FOB unit price shown (equal when there is a single price, `null` when the price is "Negotiable") |
| `currency` | ISO currency code of the prices (USD) |
| `priceUnit` | Unit the price applies to: Piece, Set, Pair, … |
| `priceText` | Price as displayed, e.g. `US$8.54-9.84` or `Negotiable` |
| `moq`, `moqUnit`, `moqText` | Minimum order quantity as a number, its unit and the text (`10 Pieces`) |
| `attributes` | Key specifications shown on the search card as a `{name: value}` dictionary (type, material, usage, …) |
| `description` | Description snippet shown on category cards |
| `imageUrl`, `images` | Full-size main image and gallery image URLs |
| `badges` | Card labels: `Diamond Member`, `Audited Supplier`, `Secured Trading`, `Sample Available`, `Rush Order`, `360° Virtual Tour`, `Video` |
| `hasSecuredTrading` | Can be ordered through the platform's Secured Trading Service (payment protection) |
| `sampleAvailable` | Supplier sells samples of this product |
| `hasVideo` | Listing has a product video |
| `isSponsored` | Paid "top ranking" placement in the results |
| `category` | Site category of the product (landing and category pages; filled from the breadcrumb with details) |
| `inquiryUrl` | Link to the "Send Inquiry" form for this product |
| `supplier.name`, `supplier.id`, `supplier.url`, `supplier.logo` | Supplier company name, ID, showroom URL and logo |
| `supplier.location`, `supplier.country` | Province (and city with details) and country, e.g. `Guangdong`, `China` |
| `supplier.memberLevel` | `Diamond`, `Gold`, … paid membership tier (verified business licence) |
| `supplier.isAuditedSupplier` | Audited on site by an independent inspection agency (SGS, BV, TÜV) |
| `supplier.businessType` | `Manufacturer/Factory`, `Trading Company` or both |
| `supplier.rating` | Supplier review score (0-5) when shown |
| `supplier.capabilityStars` | Supplier Capability Index (1-5 stars) on search cards |
| `supplier.certifications` | Management system certificates shown on the card (ISO 9001, ISO 14001, …) |
| `supplier.verifiedLabels` | Verified strength labels (`Customization from Samples`, `Fast Delivery`, `Low MOQ`, …) |
| `position`, `page`, `searchTerm`, `sourceUrl`, `scrapedAt` | Rank on its page, page number, which search term / start URL produced the item and the run timestamp |
| `changeType`, `previousValues` | Only with **Only new or changed items** on: `new` or `changed`, and for changed products the old values of the fields that changed |

With **Include product details** on, each item also gets:

| Field | Description |
|---|---|
| `priceTiers` | Price ladder by quantity: `[{minQty, maxQty, price, priceText, unit}]` (`maxQty` is `null` for the open-ended top tier; empty when the page shows a single range) |
| `attributes` | All product attributes as a `{name: value}` dictionary (model number, material, origin, trademark, HS code, package size, …) |
| `variants` | Product specification options, e.g. `[{"name": "color", "values": ["purple", "black"]}]` |
| `hsCode`, `productionCapacity` | Customs code and production capacity as stated by the supplier |
| `leadTime`, `leadTimeText` | Production lead time by quantity: `[{minQty, maxQty, days}]` plus the raw text |
| `packaging` | `transportPackage`, `specification`, `packageSize`, `packageGrossWeightKg` |
| `paymentTerms`, `incoterms`, `port` | Accepted payment terms (`T/T`, `L/C`, `PayPal`, …), trade terms (`FOB`, `CIF`, …) and the port of loading |
| `description` | Product description text |
| `videoUrl` | Product video (MP4) when the listing has one |
| `category`, `categoryPath` | Site category breadcrumb |
| `certifications` | Product certifications (CE, RoHS, ISO, …) |
| `isCustomizable`, `samplePrice`, `supportsRushOrder` | Customization offered, sample price in USD, rush orders accepted |
| `supplier.memberSince`, `supplier.yearsAsMember` | Year the membership started and years as a paid member |
| `supplier.auditedBy`, `supplier.auditReportId` | Audit agency (SGS, BV, TÜV) and report ID of audited suppliers |
| `supplier.rating`, `supplier.reviewCount` | Review score and number of reviews |
| `supplier.businessType`, `supplier.yearEstablished`, `supplier.employees`, `supplier.plantArea`, `supplier.registeredCapital` | Audited company facts |
| `supplier.address`, `supplier.nearestPort`, `supplier.mainMarkets`, `supplier.exportYears` | Business address, ports, markets served |
| `supplier.mainProducts`, `supplier.productionLines`, `supplier.oemService`, `supplier.odmService`, `supplier.ownBrand`, `supplier.customizationOptions` | Production and customization capabilities |
| `supplier.paymentTerms`, `supplier.incoterms`, `supplier.averageLeadTime`, `supplier.minimumOrder`, `supplier.repeatBuyersRate` | Trade terms of the supplier |
| `supplier.certifications`, `supplier.managementCertifications`, `supplier.intro`, `supplier.profile` | Certificates, the "Company Profile" text and the complete audited profile table as `{label: value}` (production machines, QA staff, R\&D engineers, …) |
| `isAvailable`, `detailError` | `false` + `"product paused"` when the supplier took the product offline since the search index was built (listing data is kept, no detail charge) |

Contact persons are not included: search and product pages do not show them (the product page loads the inquiry recipient separately, and the supplier's contact page would cost one extra request per supplier). `inquiryUrl` and `supplier.url` are the ways to contact a supplier on the site.

### How to use Made-in-China Scraper

1. Enter one or more **Search terms** (e.g. `bluetooth speaker`, `stainless steel water bottle`), or paste **Start URLs**: keyword search pages (`https://www.made-in-china.com/multi-search/led+strip/F1/1.html`), keyword landing pages (`https://www.made-in-china.com/products-search/hot-china-products/Bluetooth_Speaker.html`), category pages (`https://www.made-in-china.com/Computer-Products-Catalog/Portable-Speaker.html`) or single product pages.
2. Set **Max items** and **Max pages per search** to cap the run (and the cost). Pages hold 30 products each.
3. Optionally narrow search terms with the **Search filters** (audited suppliers only, Secured Trading only, business type, max MOQ, price range) and switch on **Include product details**.
4. Click **Start**. Results appear in the **Dataset** tab; export as JSON, CSV or Excel, or read them through the API.

### Input example

```json
{
  "searchTerms": ["bluetooth speaker", "portable power station"],
  "startUrls": [{ "url": "https://www.made-in-china.com/Computer-Products-Catalog/Portable-Speaker.html" }],
  "maxItems": 200,
  "maxPagesPerSearch": 5,
  "auditedSuppliersOnly": true,
  "maxMoq": 500,
  "includeDetails": true
}
```

### Output example

```json
{
  "productId": "NTHYLSRxRzpn",
  "title": "Fun Cartoon Kuromi Bluetooth Speaker for Trendy Music Enjoyment",
  "url": "https://speaker-fan.en.made-in-china.com/product/NTHYLSRxRzpn/China-Fun-Cartoon-Kuromi-Bluetooth-Speaker-for-Trendy-Music-Enjoyment.html",
  "priceMin": 8.54,
  "priceMax": 9.84,
  "currency": "USD",
  "priceUnit": "Pieces",
  "priceText": "US$8.54-9.84",
  "moq": 10,
  "moqUnit": "Pieces",
  "attributes": { "Amplification Type": "Active", "Speaker Material": "Plastic", "Model NO.": "CT4", "HS Code": "8518210000", "Transport Package": "Original" },
  "badges": ["Diamond Member", "Audited Supplier", "Secured Trading", "Sample Available", "Video"],
  "hasSecuredTrading": true,
  "sampleAvailable": true,
  "isSponsored": true,
  "imageUrl": "https://image.made-in-china.com/2f0j00NJfoOnhRSPpy/Fun-Cartoon-Kuromi-Bluetooth-Speaker-for-Trendy-Music-Enjoyment.webp",
  "priceTiers": [
    { "minQty": 10, "maxQty": 999, "price": 9.84, "priceText": "US$9.84", "unit": "Pieces" },
    { "minQty": 1000, "maxQty": 9999, "price": 9.14, "priceText": "US$9.14", "unit": "Pieces" },
    { "minQty": 10000, "maxQty": null, "price": 8.54, "priceText": "US$8.54", "unit": "Pieces" }
  ],
  "variants": [{ "name": "color", "values": ["purple"] }, { "name": "size", "values": ["13", "11", "12"] }],
  "hsCode": "8518210000",
  "packaging": { "transportPackage": "Original", "specification": "25*15*10", "packageSize": "30.00cm * 10.00cm * 5.00cm", "packageGrossWeightKg": 5.0 },
  "paymentTerms": ["LC", "T/T", "D/P", "PayPal", "Western Union"],
  "incoterms": ["FOB", "CIF", "CFR", "EXW"],
  "port": "Shenzhen Port, Guangzhou Port",
  "category": "PA Speaker",
  "samplePrice": 20.0,
  "supplier": {
    "name": "Shenzhen Kudiyou Electronic Technology Co., Ltd.",
    "url": "https://speaker-fan.en.made-in-china.com",
    "location": "Shenzhen, Guangdong",
    "country": "China",
    "memberLevel": "Diamond",
    "memberSince": 2025,
    "yearsAsMember": 2,
    "isAuditedSupplier": true,
    "auditedBy": "BV",
    "businessType": "Manufacturer/Factory",
    "yearEstablished": "2021-05-28",
    "employees": "50",
    "plantArea": "4600 square meters",
    "nearestPort": "Shenzhen Port, Guangzhou Port",
    "mainProducts": ["Speaker", "Fan"],
    "oemService": "Yes",
    "rating": 5.0,
    "reviewCount": 56
  }
}
```

### How much does it cost?

Pay per result: a small price per product from a search, landing or category page, plus a small extra per product when **Include product details** is on (one extra page fetch each). No subscription; Apify's free plan is enough to try it. Scraping 1,000 products with full details costs a few dollars.

### How do I scrape all products in a Made-in-China category?

Use the category URL as a start URL, e.g. `https://www.made-in-china.com/Computer-Products-Catalog/Portable-Speaker.html` (the breadcrumb of any product page links to its categories). Raise **Max items** and **Max pages per search**; the scraper follows the category's own pagination until it runs out. A category with 19,000 products has about 640 pages of 30.

### Can I get Made-in-China price tiers, MOQ and payment terms per product?

Yes. Every result carries the FOB price range and MOQ shown on the search card. With **Include product details** the scraper opens the product page and returns the quantity price ladder (`priceTiers`), lead time, packaging size and weight, HS code, the supplier's payment terms, incoterms and port of loading, which is what you need for landed-cost comparisons. Some suppliers list their price as "Negotiable": those products come back with `priceText: "Negotiable"` and `priceMin: null`.

### Can I filter by audited suppliers, manufacturers, MOQ or price?

Yes, for search terms and keyword search URLs. The **Search filters** map to the site's own filter bar: audited suppliers only, Secured Trading products only, manufacturer / trading company, maximum MOQ and a price range in USD. Category and landing pages do not support these filters on the site, so they are ignored there.

### Does it work without login or a browser?

Yes. All data comes from public pages Made-in-China.com serves to anonymous visitors. No account, cookies or headless browser are needed, which keeps runs fast and cheap. Prices are FOB prices in USD as shown on the site. The site offers no sort order for product search; results come in the site's relevance order, with the paid "top ranking" placements first (`isSponsored: true`).

### Can I scrape Made-in-China supplier contact details?

The Actor returns the supplier's business profile (company name, showroom URL, province, business type, membership tier, audited status, rating and, with details, the audited company facts, business address, payment terms and ports). Contact persons are not included: the search and product pages the Actor reads do not display them (the supplier's showroom has a separate contact page with the sales contact's name and department, which would cost one extra request per supplier). E-mail addresses are not shown on the site. Use `inquiryUrl` or the supplier's showroom to contact them.

### Monitor changes on a schedule

Turn on **Only new or changed items** and the scraper remembers what earlier runs of the same input returned: each run outputs only products that are new or whose price range (`priceMin` / `priceMax`) or minimum order quantity (`moq`) changed. Unchanged products are dropped before anything is saved or any product page is opened, so they are not charged. Save the input as a task (for example one keyword with **Max items** 60: the first 60 results are checked every run), then add a Schedule to it in Apify Console (Schedules → Create new, e.g. daily or weekly). Every output product carries `changeType` (`new` or `changed`), and changed ones carry `previousValues`, e.g. `{"priceMin": 9.2, "moq": 100}`. **Monitoring key** keeps several schedules on the same search separate.

### Integrations and API

Use the run in Zapier, Make, n8n, Google Sheets, or call it from Python/Node with the Apify client. See the **API** tab for ready-made snippets. Schedule it to monitor prices, MOQs or new suppliers for your keywords, and pair it with the [Alibaba Product Scraper](https://apify.com/tortuga/alibaba-scraper) to compare the same keyword across both marketplaces.

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

This Actor collects only data Made-in-China.com shows publicly to signed-out visitors: product listings, prices, MOQs and supplier business information. It does not collect anything behind a login, click-to-reveal values or hidden page data, and the pages it reads do not display contact persons. You are responsible for how you use the data and for complying with Made-in-China.com's terms and applicable law.

### Support

Found a bug or need a field added? Open an issue in the **Issues** tab; it is usually answered within a day.

# Actor input Schema

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

Keywords to search on Made-in-China.com, one per line (e.g. "bluetooth speaker", "stainless steel water bottle"). Each term is searched separately and paginated automatically (30 products per page).

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

Made-in-China URLs to scrape instead of (or in addition to) search terms: keyword search pages (https://www.made-in-china.com/productdirectory.do?word=led+strip), keyword landing pages (https://www.made-in-china.com/products-search/hot-china-products/Bluetooth_Speaker.html), category pages (https://www.made-in-china.com/Computer-Products-Catalog/Portable-Speaker.html) or single product pages (https://<shop>.en.made-in-china.com/product/<id>/<slug>.html, returned with full details).

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

Stop after this many products in total (across all search terms and URLs). Keeps cost predictable.

## `maxPagesPerSearch` (type: `integer`):

How many result pages to open per search term or start URL (30 products each). Broad keywords have hundreds of pages on the site.

## `includeDetails` (type: `boolean`):

Also open every product page to get price tiers by quantity, all product attributes (incl. HS code, packaging, production capacity, lead time), variants, description, video and the audited supplier profile (year established, employees, plant area, payment terms, incoterms, nearest port, main products, certifications, OEM/ODM service, rating). Slower and charged extra per product (see pricing).

## `auditedSuppliersOnly` (type: `boolean`):

Only products from suppliers audited by an independent inspection agency (SGS, BV, TÜV). Applies to search terms and keyword search URLs.

## `securedTradingOnly` (type: `boolean`):

Only products that can be ordered through the platform's Secured Trading Service (payment protection).

## `businessType` (type: `string`):

Restrict to manufacturers/factories or trading companies.

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

Only products whose minimum order quantity is at most this number (e.g. 100).

## `priceMin` (type: `number`):

Only products with a unit price at or above this value.

## `priceMax` (type: `number`):

Only products with a unit price at or below this value.

## `onlyNewOrChanged` (type: `boolean`):

Remember what earlier runs of this search returned and output only new items or items whose price/status changed. Use with a Schedule; unchanged items are not charged. With this on, Max items is the number of products checked each run (the watched window, e.g. the first 100 search results), so a run never digs deeper than the first one. The price range (min / max) and the minimum order quantity are compared; product pages are only opened for new or changed products.

## `monitoringKey` (type: `string`):

Name for this watch, so several schedules on the same search stay separate; defaults to a key derived from the search input.

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

Apify Proxy is recommended. The site sits behind Cloudflare; if the run reports blocked pages in its summary, switch to residential proxies.

## Actor input object example

```json
{
  "searchTerms": [
    "bluetooth speaker"
  ],
  "startUrls": [],
  "maxItems": 100,
  "maxPagesPerSearch": 10,
  "includeDetails": false,
  "auditedSuppliersOnly": false,
  "securedTradingOnly": false,
  "businessType": "any",
  "onlyNewOrChanged": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (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 = {
    "searchTerms": [
        "bluetooth speaker"
    ],
    "startUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("tortuga/made-in-china-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": ["bluetooth speaker"],
    "startUrls": [],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("tortuga/made-in-china-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": [
    "bluetooth speaker"
  ],
  "startUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call tortuga/made-in-china-scraper --silent --output-dataset

```

## MCP server setup

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