# Labexchange Scraper — Used Lab Equipment (`crawloop/labexchange-scraper`) Actor

Scrape Labexchange used laboratory & analytical equipment: autoclaves, chromatographs, centrifuges, spectrometers. Net/gross prices, brand, device status, specs, full-res images, PDFs. Category crawl, search, or product URLs. Listings or details. Fast HTTP via curl\_cffi.

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

## Pricing

from $1.50 / 1,000 scraped details rows

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?

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

## Labexchange Scraper — Used Lab & Analytical Equipment

> **Disclaimer:** Unofficial tool — not affiliated with, sponsored by, or endorsed by Labexchange or Laborgerätebörse GmbH or its affiliates. Data is read from publicly accessible pages only. No login. You are responsible for complying with applicable law (including GDPR where personal data appears) and the site’s terms. No warranty on accuracy or availability. Provided for informational and research use.

> **Crawloop Print & Lab Equipment** — used presses and laboratory inventory.

| PressXchange | PressCity | Labexchange | Surplex | Troostwijk |
| :--- | :--- | :--- | :--- | :--- |
| [PressXchange Scraper](https://apify.com/crawloop/pressxchange-scraper) | [PressCity Scraper](https://apify.com/crawloop/presscity-scraper) | **Labexchange Scraper** ◄── you are here | [Surplex Scraper](https://apify.com/crawloop/surplex-scraper) | [Troostwijk Scraper](https://apify.com/crawloop/troostwijk-scraper) |

Scrape **used laboratory and analytical equipment** into clean structured JSON — autoclaves, chromatographs, centrifuges, incubators, spectrometers, gas generators, and more (Thermo, Agilent, Eppendorf, Waters, Memmert, and similar brands when listed).

Built for **lab equipment dealers**, **procurement teams**, **market comps**, and **CRM / spreadsheet enrichment**. Choose `listings` for fast card-level catalogs or `details` for full product pages with specs, net/gross prices, image galleries, and warranty notes.

Lightweight HTTP extraction with Chrome TLS fingerprinting — no headless browser.

### When to use this Actor

Use the **Labexchange Scraper** when you need:

- **Catalog inventory** across Labor und Analytik, Chromatographie, Life Science, Laboreinrichtung, Spektroskopie, Messgeräte, Verfahrenstechnik, and promotions
- **Commercial fields** — net price, gross price, VAT rate, currency, shipping lead time
- **Stock context** — `Lagergerät` (warehouse), `Anbieter` (partner seller), or `Labprocure`
- **Identity & specs** — object number, ID number, brand/manufacturer, year, technical attribute table
- **Media** — full-resolution gallery images and product PDF downloads when published
- **Keyword discovery** — search by brand or model without hand-building every category URL

Ideal for used-lab-equipment dealers, hospital/university buyers, and data teams tracking European secondary-market lab instruments.

### Data pipeline

```
Input                              Mode                         Output
─────────────────────────         ────────────────────         ──────────────────────────

  Category / search URL      ──►   listings (fast cards)  ──►  title, price, status, IDs
  Keyword search             ──►   details  (full PDP)   ──►  specs, images, prices
  Direct product URL         ──►                           ──►  brand, warranty, PDFs
  categories[] enum

  Join by brand + model      ──►   comps & inventory alerts
```

### Key Features

- **Two extraction modes** — `listings` for card-level stubs; `details` for attribute table, net/gross price, gallery, warranty text.
- **Category shortcuts** — top-level catalog roots when you do not paste filtered URLs.
- **Search** — Magento catalog search via `searchKeyword` (brand or model).
- **Device status filter** — keep warehouse stock, partner offers, Labprocure, or all.
- **Locale** — German (`de`) or English (`en`) storefront paths.
- **Fast concurrent HTTP** — Chrome TLS impersonation and parallel detail fetches; proxy optional for large runs.

### Input Parameters

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `startUrls` | Array | sample autoclaves category | Category, search, or product detail URLs. |
| `categories` | Array | `labor-und-analytik` | Top-level roots when `startUrls` is empty. |
| `searchKeyword` | String | — | Brand/model search (e.g. Eppendorf, Agilent). |
| `language` | String | `"de"` | Storefront locale: `de` or `en`. |
| `runMode` | String | `"details"` | `"listings"` (cards) or `"details"` (full PDP). |
| `deviceStatus` | String | `"all"` | `all`, `Lagergerät`, `Anbieter`, or `Labprocure`. |
| `maxItems` | Integer | `100` | Maximum products (`0` = unlimited). |
| `maxPagesPerUrl` | Integer | `5` | Pagination depth `?p=N` (`0` = until exhausted). |
| `concurrencyLimit` | Integer | `5` | Parallel detail workers (1–20). |
| `proxyConfiguration` | Object | Apify Proxy | Recommended for large full-catalog runs. |

#### Input example — category details

```json
{
  "startUrls": [
    { "url": "https://shop.labexchange.com/de/labor-und-analytik/autoklaven.html" }
  ],
  "runMode": "details",
  "maxItems": 100,
  "maxPagesPerUrl": 5,
  "concurrencyLimit": 5,
  "language": "de",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

#### Input example — brand search

```json
{
  "searchKeyword": "Eppendorf",
  "runMode": "details",
  "maxItems": 50,
  "maxPagesPerUrl": 3,
  "concurrencyLimit": 4,
  "language": "de",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

### Output Format

Each row is pushed to the default dataset.

#### Details mode (enriched)

| Field | Description |
| :--- | :--- |
| `objectNumber`, `idNumber`, `productId` | Labexchange identifiers |
| `url`, `title`, `brand` | Product identity |
| `categories` | Category path / labels |
| `priceNet`, `priceGross`, `regularPrice`, `currency`, `vatRate` | Commercial terms |
| `yearOfManufacture`, `deviceStatus`, `shippingTime`, `availability` | Condition and logistics |
| `description`, `technicalSpecs`, `warrantyInfo` | Text and attribute table |
| `thumbnail`, `images`, `pdfDownloads` | Media assets |
| `scrapedAt` | Scrape timestamp (UTC) |

#### Example record

```json
{
  "objectNumber": "B00049537",
  "idNumber": "49537",
  "title": "Belimed Vapofix 3-3-6",
  "url": "https://shop.labexchange.com/de/belimed-vapofix-3-3-6.html",
  "brand": "Belimed",
  "categories": ["Autoklaven"],
  "priceNet": 4900.0,
  "priceGross": 5831.0,
  "currency": "EUR",
  "vatRate": 19.0,
  "deviceStatus": "Anbieter",
  "shippingTime": "4-6 Wochen",
  "images": [
    "https://shop.labexchange.com/media/catalog/product/cache/.../49537.jpg"
  ],
  "technicalSpecs": {
    "Objektnummer": "B00049537",
    "Marke/Hersteller": "Belimed",
    "Status": "Anbieter"
  },
  "scrapedAt": "2026-07-22T19:55:00Z"
}
```

Storefront list prices are typically **ex VAT** (`priceNet`); `priceGross` is taken from the “inkl. MwSt.” line when shown.

### 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/labexchange-scraper').call({ startUrls: [{ url: "https://www.labexchange.com/en/autoclaves" }], runMode: "details", maxItems: 20, language: "de" });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.slice(0, 5));
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient(token)
run = client.actor("crawloop/labexchange-scraper").call(
    run_input={"startUrls": [{"url": "https://www.labexchange.com/en/autoclaves"}], "runMode": "details", "maxItems": 20, "language": "de"}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item.get("title"), item.get("brand"), item.get("priceNet"))
```

#### cURL

```bash
curl "https://api.apify.com/v2/acts/crawloop~labexchange-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startUrls":[{"url":"https://www.labexchange.com/en/autoclaves"}],"runMode":"details","maxItems":20,"language":"de"}'
```

### 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 `crawloop/labexchange-scraper`.

Example prompts:

- "Run Labexchange Scraper for autoclaves, details mode, max 20, return title, brand, priceNet, yearOfManufacture"
- "Scrape Labexchange used lab equipment and summarize brands"
- "Chain Labexchange then Exapro Scraper for broader industrial inventory"

### Suite next step

For broader industrial inventory, use [Exapro Scraper](https://apify.com/crawloop/exapro-scraper) or [Machineryline Scraper](https://apify.com/crawloop/machineryline-scraper).

### Notes

- Catalog pages are Magento 2 server-rendered HTML — HTTP is enough; no Playwright.
- Prefer concurrency 3–8. Enable proxy for full-catalog crawls (thousands of SKUs).
- Partner listings (`Anbieter`) often have longer lead times than warehouse stock (`Lagergerät`).
- Duplicate products across overlapping categories are deduplicated by object / ID number.

# Actor input Schema

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

Category, search, or product detail URLs on shop.labexchange.com. If empty, categories below (or Labor und Analytik) are used.

## `categories` (type: `array`):

Used when startUrls is empty and no searchKeyword is set.

## `searchKeyword` (type: `string`):

Optional Magento catalog search (brand or model, e.g. Eppendorf, Agilent).

## `language` (type: `string`):

Storefront locale prefix in URLs.

## `runMode` (type: `string`):

listings = fast card-level data from category/search pages. details = visit each product page for full specs, gallery, and prices.

## `deviceStatus` (type: `string`):

Filter by stock location / seller type.

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

Maximum products to return. 0 = unlimited.

## `maxPagesPerUrl` (type: `integer`):

Magento pagination depth (?p=N). Each page has ~24 listings. 0 = until no more pages.

## `concurrencyLimit` (type: `integer`):

Parallel detail-page workers.

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

Optional. Datacenter is usually enough; use residential if you hit rate limits.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://shop.labexchange.com/de/labor-und-analytik/autoklaven.html"
    }
  ],
  "categories": [
    "labor-und-analytik"
  ],
  "language": "de",
  "runMode": "details",
  "deviceStatus": "all",
  "maxItems": 100,
  "maxPagesPerUrl": 5,
  "concurrencyLimit": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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 = {
    "startUrls": [
        {
            "url": "https://shop.labexchange.com/de/labor-und-analytik/autoklaven.html"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawloop/labexchange-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 = { "startUrls": [{ "url": "https://shop.labexchange.com/de/labor-und-analytik/autoklaven.html" }] }

# Run the Actor and wait for it to finish
run = client.actor("crawloop/labexchange-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 '{
  "startUrls": [
    {
      "url": "https://shop.labexchange.com/de/labor-und-analytik/autoklaven.html"
    }
  ]
}' |
apify call crawloop/labexchange-scraper --silent --output-dataset

```

## MCP server setup

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