# ECHEMI Scraper — Chemical Products, Suppliers & CAS (`crawloop/echemi-scraper`) Actor

Scrape ECHEMI China chemical marketplace offers, CAS encyclopedia, and supplier shops. Export grade, purity, FOB price text, inquiry history, and company profiles — an ECHEMI scraper / API alternative for sourcing and competitive intelligence.

- **URL**: https://apify.com/crawloop/echemi-scraper.md
- **Developed by:** [Andrej Kiva](https://apify.com/crawloop) (community)
- **Categories:** E-commerce, Lead generation, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.55 / 1,000 offer listings

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/platform/actors/running/actors-in-store#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

## ECHEMI Scraper — Chemical Products, Suppliers & CAS

> **China chemical B2B marketplace data** — ECHEMI produce offers, CAS encyclopedia, supplier shops, FOB price text, and inquiry history.

| Actor | Role |
| :--- | :--- |
| **ECHEMI Scraper** ◄── you are here | China chemical offers, suppliers & CAS |
| [Europages Scraper](https://apify.com/crawloop/europages-scraper) | EU B2B company & product discovery |
| [WLW Scraper](https://apify.com/crawloop/wlw-scraper) | DACH industrial supplier leads |

> **Disclaimer:** Unofficial Actor for publicly accessible ECHEMI pages. **ECHEMI** and related names are trademarks of their respective owners. Not affiliated with, sponsored by, or endorsed by ECHEMI / Qingdao ECHEMI Digital Technology Co., Ltd. Provided for informational and research purposes only. You are responsible for complying with applicable laws and ECHEMI terms of use.

Scrape the **ECHEMI** chemical marketplace by **produce URL**, **sale-list URL**, **supplier shop**, **CAS / chemical name**, or **category**. Export **CAS**, **grade**, **purity**, **FOB / unit price text**, **packaging**, **supplier profile**, and **inquiry history** as clean JSON — an **ECHEMI scraper** / **ECHEMI API alternative** for **China sourcing**, **competitive intelligence**, and **MCP** / Python / Node.js pipelines.

***

### When to use this Actor

- Bulk **produce offer** (`/produce/pr…`) URLs — the most reliable path for large result volumes
- **Sale-list** (`/searchGoods/…`) and **category** pages (prefer page 1; deeper pages may be blocked)
- **Supplier shop** storefronts (`/shop-…`)
- **CAS / name** lookup via public indexes (when a matching sale list exists)
- China chemical **sourcing**, **price/grade monitoring**, and **RFQ demand signals**

### When not to use this Actor

- **Official ECHEMI Price Database / Trade Data** subscriptions (paywalled)
- **Live RFQ / inquiry posting** automation
- Keyword URLs like `searchGoods.html?keywords=…` (Aliyun WAF — use SEO sale lists or indexes instead)
- Non-ECHEMI chemical portals — use sibling B2B Actors (e.g. Europages / WLW)

***

### Key Features

- **Produce offers** — `/produce/pr…` with CAS, grade, purity, packaging, price text, seller profile, inquiry history
- **Sale lists** — `/searchGoods/…` and category offer cards (stable on page 1)
- **Encyclopedia** — `/products/…` substance pages with formula, synonyms, recommended offers
- **Supplier shops** — `/shop-…` storefronts with featured products and company fields
- **Bulk-stable ordering** — produce / detail URLs are processed before fragile listing pagination
- **Fast HTTP scraping** — `curl_cffi` + crawler-friendly requests for SEO/detail pages
- **Optional enrich** — upgrade listing rows to full produce details
- **Residential proxy ready** — sticky Apify sessions for cloud / high-volume runs

***

### Use Cases

| Use case | What you get | Why it helps |
| :--- | :--- | :--- |
| **China chemical sourcing** | Offers by CAS / substance + supplier shops | Build procurement shortlists |
| **Price / grade monitoring** | Unit price text, grade, purity, packaging | Track public listing signals over time |
| **Supplier intelligence** | Shop profile, revenue band, employees, main products | Map who sells what on ECHEMI |
| **Demand signals** | Inquiry history (country, quantity, date) | See which markets are requesting the chemical |
| **CAS enrichment** | Encyclopedia attributes + recommended offers | Join marketplace offers to substance identity |
| **AI / MCP pipelines** | Structured JSON for assistants and agents | Automate sourcing research in chat tools |

***

### Input Parameters

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `startUrls` | Array | — | Best for scale: many `/produce/pr…` URLs. Also `searchGoods`, `products`, `shop`, `category` |
| `searchQueries` | Array | — | CAS or chemical name (resolved via public indexes → sale lists) |
| `maxItems` | Integer | `50` | Max successful results (errors are stored but do not count) |
| `maxPages` | Integer | `1` | Max pages per sale list / category — keep `1` for reliability |
| `enrichProducts` | Boolean | `false` | Fetch full produce detail for each listing row |
| `requestDelaySecs` | Number | `0.35` | Delay between HTTP requests |
| `proxyConfiguration` | Object | Residential | Apify Proxy — residential recommended on the platform |

#### Input Example — bulk produce URLs (recommended for large runs)

```json
{
  "startUrls": [
    "https://www.echemi.com/produce/pr23122128410-high-purity-sulfanilic-acid-cas-no121-57-3.html",
    "https://www.echemi.com/searchGoods/pid_Rock6557-cytidylicacid.html"
  ],
  "maxItems": 200,
  "maxPages": 1,
  "enrichProducts": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

#### Input Example — CAS search + enrich

```json
{
  "searchQueries": ["121-57-3"],
  "maxItems": 50,
  "maxPages": 1,
  "enrichProducts": true
}
```

***

### Output

| Field | Type | Description |
| :--- | :--- | :--- |
| `recordType` | String | `listing` | `produce` | `encyclopedia` | `supplier` | `error` |
| `url` | String | Page URL |
| `produceId` / `shopId` | String | Offer or shop id |
| `name` | String | Offer / substance / company name |
| `casNumber` | String | CAS registry number |
| `grade` / `purity` | String | Grade and content / assay |
| `priceText` | String | Visible unit price or “Get Latest Price” |
| `packaging` | String | Packing text |
| `companyName` / `companyUrl` | String | Supplier |
| `companyType` / `location` | String | Business type and geography |
| `inquiryCount` / `inquiries` | Integer / Array | RFQ history on produce pages |
| `molecularFormula` / `ecNumber` / `hsCode` | String | Chem identifiers when present |
| `featuredProducts` | Array | Shop catalog links |

#### Output Example — produce offer

```json
{
  "source": "echemi",
  "recordType": "produce",
  "url": "https://www.echemi.com/produce/pr23122128410-high-purity-sulfanilic-acid-cas-no121-57-3.html",
  "produceId": "pr23122128410-high-purity-sulfanilic-acid-cas-no121-57-3",
  "name": "High purity Sulfanilic acid CAS NO.121-57-3",
  "casNumber": "121-57-3",
  "grade": "Pharmaceutical Grade",
  "purity": "99%",
  "packaging": "1kg/bag,25kg/drum,25kg/bag",
  "priceText": "Get Latest Price",
  "companyName": "Shanghai Lonwin Chemical Co.,Ltd",
  "companyType": "Trader",
  "location": "China",
  "inquiryCount": 11,
  "inquiries": [
    {
      "country": "India",
      "product": "Sulfanilic acid",
      "quantity": "1.00 MT",
      "datePosted": "Jul 13, 2023"
    }
  ]
}
```

***

### Integration examples

#### Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('crawloop/echemi-scraper').call({
  startUrls: [
    'https://www.echemi.com/searchGoods/pid_Rock6557-cytidylicacid.html',
  ],
  maxItems: 50,
  maxPages: 1,
  enrichProducts: true,
  proxyConfiguration: {
    useApifyProxy: true,
    apifyProxyGroups: ['RESIDENTIAL'],
  },
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((i) => i.recordType !== 'error').slice(0, 5));
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("crawloop/echemi-scraper").call(
    run_input={
        "startUrls": [
            "https://www.echemi.com/produce/pr23122128410-high-purity-sulfanilic-acid-cas-no121-57-3.html"
        ],
        "maxItems": 100,
        "maxPages": 1,
        "proxyConfiguration": {
            "useApifyProxy": True,
            "apifyProxyGroups": ["RESIDENTIAL"],
        },
    }
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    if item.get("recordType") == "error":
        continue
    print(item.get("name"), item.get("casNumber"), item.get("companyName"))
```

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/crawloop~echemi-scraper/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startUrls":["https://www.echemi.com/produce/pr23122128410-high-purity-sulfanilic-acid-cas-no121-57-3.html"],"maxItems":20,"proxyConfiguration":{"useApifyProxy":true,"apifyProxyGroups":["RESIDENTIAL"]}}'
```

***

### MCP and AI assistants

Use this Actor from AI tools via [Apify MCP](https://docs.apify.com/platform/integrations/mcp).
Connect your Apify account, then call this Actor by its Store ID `crawloop/echemi-scraper`.

Example prompts:

- "Run ECHEMI Scraper for CAS 121-57-3 and return the top 20 offers as JSON with supplier and price text"
- "Scrape these ECHEMI produce URLs and summarize grade, purity, company, and inquiry history"
- "Chain ECHEMI Scraper then Europages Scraper: China chemical offers by CAS, then EU buyer/supplier discovery for the same chemistry"

***

### Suite next step

After China offer extraction, run [Europages Scraper](https://apify.com/crawloop/europages-scraper) or [WLW Scraper](https://apify.com/crawloop/wlw-scraper) to map European industrial buyers and suppliers for the same chemicals. A Knowde sibling Actor (Western ingredients / TDS-SDS) is planned in the same suite — link it here once Store-public.

***

### FAQ

**How do I scrape large volumes reliably?**\
Pass many `/produce/pr…` URLs (or many page-1 `/searchGoods/…` lists), keep `maxPages: 1`, enable residential proxy, and set a long enough run timeout. Produce pages are the stable bulk path.

**Why not paste `searchGoods.html?keywords=…`?**\
Those keyword URLs are protected by Aliyun WAF for automated clients. Prefer `/searchGoods/{slug}.html` sale lists, category URLs, or CAS/name queries (resolved via public indexes).

**Do all offers show a numeric price?**\
No. Many listings show “Get Latest Price” and require an inquiry. The Actor still returns grade, purity, packaging, supplier fields, and inquiry history when present.

**Is residential proxy required?**\
Recommended on the Apify platform for stable cloud runs. SEO produce / encyclopedia pages often work with bot-friendly requests; residential sticky sessions help when Aliyun WAF challenges datacenter egress.

**What does `maxItems` count?**\
Successful `listing` / `produce` / `supplier` / `encyclopedia` rows only. Error rows may still appear in the dataset but do not stop the run early.

***

### Related Actors

- [Europages Scraper](https://apify.com/crawloop/europages-scraper) — EU B2B products & companies
- [WLW Scraper](https://apify.com/crawloop/wlw-scraper) — DACH industrial supplier directory

# Actor input Schema

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

Chemical name or CAS number. Resolved via ECHEMI alphabetical / CAS indexes into sale-list pages (direct keyword search URLs are WAF-protected). Prefer pasting searchGoods or category URLs in Start URLs when possible.

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

Best for large stable runs: many /produce/pr… offer URLs (or sitemap seeds). Also supports encyclopedia (/products/…), sale lists (/searchGoods/… page 1), shops (/shop-…/index.html), categories (/category/…). Produce URLs are processed first.

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

Stop after this many successful results (listings, produce, suppliers, encyclopedia). Error rows are stored but do not count toward this limit.

## `maxPages` (type: `integer`):

Maximum pages per searchGoods / category listing (≈10 offers per page). Keep at 1 for reliability — page 2+ is often blocked by Aliyun WAF. For large volumes, pass many produce URLs or many page-1 sale-list URLs instead of deep pagination.

## `enrichProducts` (type: `boolean`):

When scraping sale lists, also fetch full produce detail pages (seller profile, inquiry history, chem attributes).

## `requestDelaySecs` (type: `number`):

Pause between HTTP requests on the same session.

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

Apify Proxy. Residential recommended on the Apify platform — datacenter IPs hit Aliyun WAF after a few listing pages.

## Actor input object example

```json
{
  "searchQueries": [
    "121-57-3"
  ],
  "startUrls": [
    "https://www.echemi.com/produce/pr23122128410-high-purity-sulfanilic-acid-cas-no121-57-3.html",
    "https://www.echemi.com/searchGoods/pid_Rock6557-cytidylicacid.html"
  ],
  "maxItems": 50,
  "maxPages": 1,
  "enrichProducts": false,
  "requestDelaySecs": 0.35,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

Default dataset items.

# 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": [
        "121-57-3"
    ],
    "startUrls": [
        "https://www.echemi.com/produce/pr23122128410-high-purity-sulfanilic-acid-cas-no121-57-3.html",
        "https://www.echemi.com/searchGoods/pid_Rock6557-cytidylicacid.html"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawloop/echemi-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": ["121-57-3"],
    "startUrls": [
        "https://www.echemi.com/produce/pr23122128410-high-purity-sulfanilic-acid-cas-no121-57-3.html",
        "https://www.echemi.com/searchGoods/pid_Rock6557-cytidylicacid.html",
    ],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("crawloop/echemi-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": [
    "121-57-3"
  ],
  "startUrls": [
    "https://www.echemi.com/produce/pr23122128410-high-purity-sulfanilic-acid-cas-no121-57-3.html",
    "https://www.echemi.com/searchGoods/pid_Rock6557-cytidylicacid.html"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call crawloop/echemi-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawloop/echemi-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/M2Z5jyxEqhbcb2yVv/builds/rzJcYRtEWXRgzXagJ/openapi.json
