# Trade Show Exhibitor Lists Scraper (`automation-lab/public-exhibitor-directory-scraper`) Actor

Extract normalized exhibitor companies, booths, categories, websites, and displayed contacts from supplied public trade-show directory URLs.

- **URL**: https://apify.com/automation-lab/public-exhibitor-directory-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/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

## Trade Show Exhibitor Lists Scraper

Export normalized **trade show exhibitor lists** from public directory URLs you supply.
The Actor turns supported event directories into one dataset of company names, booth locations, event context, categories, websites, and publicly displayed contact details.

Use the result for event prospecting, supplier research, show planning, CRM imports, and repeatable cross-event analysis.

### What does Trade Show Exhibitor Lists Scraper do?

The Actor detects and extracts several common public exhibitor-directory formats:

- Messe Frankfurt event directories through their public structured data route
- Map Your Show and A2Z public exhibitor lists and eBooth profiles
- the public IFA Berlin exhibitor directory
- conservative JSON-LD or semantic HTML fallback records on other supplied public pages

Every accepted exhibitor becomes the same normalized record shape.
Source and profile URLs remain attached for verification.
The Actor does not guess missing contact details or invent companies.

### Who is this exhibitor list scraper for?

- **Sales teams** building pre-show company and booth prospect lists
- **Event sponsors** mapping participating vendors and categories
- **Procurement teams** identifying suppliers represented at industry events
- **Market researchers** comparing exhibitor mixes across public events
- **Agencies** preparing show-specific outreach or account assignments
- **Event operations teams** exporting public booth context into planning sheets

### Why use a multi-source exhibitor extractor?

Trade show directories use different page layouts and field names.
A company may appear as an exhibitor, brand, vendor, or booth record.
Hall and stand data can live on the list page while websites and contacts live on a profile.

This Actor provides:

- one input for multiple supported public directory URLs;
- normalized fields across supported source platforms;
- an optional public-profile enrichment step for Map Your Show/A2Z;
- a global output cap for predictable tests and integrations;
- optional case-insensitive filtering after normalization;
- explicit failure when no recognizable exhibitor data is found.

### Supported public exhibitor directories

Validated adapters currently cover:

| Platform | Supported public surface | Main extraction route |
|---|---|---|
| Messe Frankfurt | Event exhibitor-search URLs | Public event configuration and paginated JSON |
| Map Your Show / A2Z | `Exhibitors.aspx` and linked `eBooth.aspx` pages | Server-rendered HTML |
| IFA Berlin | Public `/exhibitors` directory | Server-rendered cards |
| Other sites | Pages with exhibitor Organization JSON-LD or clear semantic profile links | Conservative HTML fallback |

A public URL is not automatically compatible.
Login-only pages, challenge pages, expired directories, PDF-only lists, and JavaScript applications without useful public HTML may fail.
The generic fallback is intentionally strict to avoid false records.

### What exhibitor data can you extract?

| Field | Meaning |
|---|---|
| `sourcePlatform` | Detected adapter: Messe Frankfurt, Map Your Show, IFA Berlin, or generic HTML |
| `eventName` | Displayed event or directory name when available |
| `eventUrl` | Supplied public event directory URL |
| `companyName` | Displayed exhibitor or company name |
| `exhibitorId` | Public source identifier when exposed |
| `profileUrl` | Public exhibitor detail page |
| `boothLocations` | Normalized hall and stand pairs |
| `categories` | Displayed products, services, or show areas |
| `description` | Public exhibitor description |
| `website` | Displayed company website |
| `email` | Displayed public email, when present |
| `phone` | Displayed public phone, when present |
| `address`, `city`, `postalCode`, `country` | Displayed location fields |
| `socialLinks` | Displayed public social profile links |
| `logoUrl` | Public exhibitor logo URL |
| `sourceUrl` | Exact source page for verification |
| `scrapedAt` | ISO timestamp for the extraction |

Unavailable fields are returned as `null` or empty arrays.

### How to extract a trade show exhibitor list

1. Open a current public exhibitor directory.
2. Copy its exhibitor-list URL.
3. Add the URL to `startUrls`.
4. Set `maxItems` to a small test value such as 10 or 25.
5. Keep `includeDetails` on if you want Map Your Show/A2Z profile enrichment.
6. Optionally enter a `query` such as a category, country, or company term.
7. Run the Actor.
8. Inspect and export the default dataset as JSON, CSV, Excel, or XML.

For recurring prospecting, save the working input as an Apify Task and schedule it.

### Input parameters

#### `startUrls`

Required array of public exhibitor list, directory, or profile URLs.
You can combine supported platforms in one run.
The Actor divides the result budget across URLs so one large directory does not starve later sources.

#### `maxItems`

Maximum records saved across all URLs.
The range is 1 to 10,000 and the default is 100.
Use a low limit while validating a new directory.

#### `includeDetails`

When enabled, linked public Map Your Show/A2Z profiles are opened for displayed categories, website, contacts, and location context.
It does not bypass a login or access restriction.

#### `query`

Optional case-insensitive text filter applied to the complete normalized record.
For example, `Germany`, `lighting`, or a company name can match any populated field.

#### `proxyConfiguration`

Optional Apify Proxy or custom proxy configuration.
Direct HTTP is the default and is sufficient for the validated examples.
A proxy does not make an unsupported or private page supported.

### Output example

A current Messe Frankfurt record is normalized like this:

```json
{
  "sourcePlatform": "messe-frankfurt",
  "eventName": "Ambiente 2026",
  "eventUrl": "https://ambiente.messefrankfurt.com/frankfurt/en/exhibitor-search.html",
  "companyName": "Budapest Select",
  "exhibitorId": "mf_1_0012639526~mf_1_10000001202601_0012639526_477437",
  "profileUrl": "https://ambiente.messefrankfurt.com/frankfurt/en/exhibitor-search.detail.html/mediator-group-reklmuegynoeksg-kft",
  "boothLocations": [{ "hall": "3.0", "stand": "G32" }],
  "categories": ["Interior Design", "Home concepts"],
  "website": null,
  "email": null,
  "country": "Hungary",
  "sourceUrl": "https://ambiente.messefrankfurt.com/frankfurt/en/exhibitor-search.html",
  "scrapedAt": "2026-08-11T12:30:00.000Z"
}
```

Displayed data changes between events and exhibitors, so treat every optional field as nullable.

### How much does it cost to extract trade show exhibitor lists?

The Actor uses pay-per-event pricing: one small start event per run plus one `item` event for each saved exhibitor.
All profile, booth, category, and displayed contact fields included in an exhibitor row are covered by that item event; there is no separate enrichment charge.

Your exact total is:

`$0.005 start + (saved exhibitors × your item tier price)`

| Store tier | Price per saved exhibitor |
|---|---:|
| Free | $0.00414 |
| Bronze | $0.0036 |
| Silver | $0.002808 |
| Gold | $0.00216 |
| Platinum | $0.00144 |
| Diamond | $0.001008 |

At the Bronze tier, 10 saved exhibitors cost **$0.041**, 25 cost **$0.095**, and 100 cost **$0.365**, including the start event.
The Actor page shows the applicable tier before a run.
Set `maxItems` to control the maximum number of records and estimate the run before scaling.
Proxy transfer, if you explicitly enable a paid proxy mode, is platform usage in addition to Actor events.

### Multi-event prospecting workflow

A practical recurring workflow is:

1. Add several current event directory URLs to one Task.
2. Run a small validation sample.
3. Schedule the Task weekly while exhibitor lists change.
4. Export the dataset into a warehouse or spreadsheet.
5. Match records by website, exhibitor ID, or normalized company name.
6. Flag newly added companies or changed booth locations.
7. Assign those changes to account owners before the event.

The Actor returns snapshots.
It does not itself compare previous runs, send alerts, or modify your CRM.
Use Apify schedules, integrations, or your own downstream process for those steps.

### Integrations and exports

Use the default dataset with:

- Google Sheets for event account planning;
- HubSpot, Salesforce, or Pipedrive through Apify integrations;
- Make or Zapier for workflow routing;
- webhooks for post-run processing;
- Python, JavaScript, SQL, or notebooks for category analysis;
- CSV or Excel exports for show-floor planning.

Stable source URLs make it possible to audit each row later.

### Run with the Apify API

#### JavaScript

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/public-exhibitor-directory-scraper').call({
  startUrls: [
    { url: 'https://ambiente.messefrankfurt.com/frankfurt/en/exhibitor-search.html' }
  ],
  maxItems: 25,
  includeDetails: false
});
console.log(run.defaultDatasetId);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient('YOUR_APIFY_TOKEN')
run = client.actor('automation-lab/public-exhibitor-directory-scraper').call(run_input={
    'startUrls': [
        {'url': 'https://www.ifa-berlin.com/exhibitors'}
    ],
    'maxItems': 25,
    'includeDetails': False,
})
print(run['defaultDatasetId'])
```

#### cURL

```bash
curl -X POST \
  'https://api.apify.com/v2/acts/automation-lab~public-exhibitor-directory-scraper/runs?token=YOUR_APIFY_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "startUrls": [{"url":"https://antique.a2zinc.net/OMBAS2026/Public/Exhibitors.aspx?Index=All"}],
    "maxItems": 10,
    "includeDetails": true
  }'
```

Never commit an Apify token into source code.

### Use through Apify MCP

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/public-exhibitor-directory-scraper"
```

#### Claude Desktop

Add this MCP server in Claude Desktop's JSON configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/public-exhibitor-directory-scraper"
    }
  }
}
```

#### Cursor

Add the same `mcpServers.apify` JSON entry in Cursor's MCP settings, then enable the server for your workspace.

#### VS Code

Add the same Apify MCP URL through your VS Code MCP extension or workspace MCP configuration and enable the `public-exhibitor-directory-scraper` tool.

Example prompts:

- “Export the first 50 exhibitors and booth locations from this public trade show directory.”
- “Combine these IFA Berlin and Map Your Show URLs into one prospect list.”
- “Return exhibitors whose normalized record contains lighting.”

### Reliability, limits, and failure behavior

The Actor validates HTTP(S) inputs and rejects malformed protocols.
Requests use bounded retries for transient network failures.
Challenge or empty-shell pages are treated as failures, not valid empty results.
A source that fails is logged while other supplied sources can still succeed.
The whole run fails if no supplied URL yields a useful record.

`maxItems` is a global accepted-result cap.
Duplicate IDs or profile URLs are removed within the run.
A successful HTTP response does not guarantee that an unfamiliar site uses a supported structure.

### Troubleshooting

#### Why did my URL return no records?

Confirm that it is a current public exhibitor list rather than an event homepage, login page, search landing page, or downloadable PDF.
Try the exact list URL shown after opening the directory.
Run with `maxItems: 5` first.

#### Why are email or website fields null?

The event may not display those fields publicly.
For Map Your Show/A2Z, enable `includeDetails` so linked profiles can be inspected.
The Actor does not infer or purchase hidden contacts.

#### Why did only part of a list appear?

Check `maxItems`.
When multiple URLs are supplied, the Actor reserves a fair share of the remaining cap for each source.
Raise the limit after validating each event.

#### Should I enable a proxy?

Use direct mode first.
Enable a proxy only when the public source requires it and confirm that the result value justifies the transfer cost.
A proxy cannot bypass authentication or change the supported parser.

### Responsible use and legality

Only collect data you are allowed to use.
Follow event-organizer terms, applicable privacy and database laws, and your outreach obligations.
Do not use the Actor to access login-only or restricted pages.
Treat displayed personal contact data carefully, keep only what you need, and provide appropriate opt-out handling.

The Actor extracts public page content supplied by the user; it does not grant rights to republish, resell, or contact every listed party.

### FAQ

#### Can it scrape every trade show website?

No.
It supports the named adapters and conservative structured-HTML fallback.
An unsupported site fails rather than producing misleading rows.

#### Can I submit several event URLs?

Yes.
Results are normalized into one default dataset and deduplicated within the run.

#### Does it scrape trade show displays or booth images?

It extracts displayed booth location context, not physical display products, floor-plan geometry, or image archives.

#### Does it monitor exhibitor changes automatically?

The Actor creates a current snapshot.
Save it as a scheduled Task and compare datasets downstream for monitoring.

#### Does it scrape private contacts?

No.
Only contact fields displayed on the supplied public pages are included.

### Related Automation Lab Actors

For source-specific or downstream workflows, consider:

- [Messe Frankfurt Exhibitor List Scraper](https://apify.com/automation-lab/messe-frankfurt-exhibitor-list-scraper)
- [Messe Berlin Exhibitor List Scraper](https://apify.com/automation-lab/messe-berlin-exhibitor-list-scraper)
- [Nürnberg Messe Exhibitor List Scraper](https://apify.com/automation-lab/nuernberg-messe-exhibitor-list-scraper)
- [Website Contact Scraper](https://apify.com/automation-lab/website-contact-scraper)

Use a source-specific Actor when you only need one supported event ecosystem.
Use this Actor when you need supplied URLs and one cross-platform record format.

### Changelog

See the Actor Changelog tab for customer-facing release notes.

# Actor input Schema

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

Public trade-show exhibitor list, directory, or profile URLs to extract. Multiple supported platforms can be combined in one run.

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

Maximum normalized exhibitor records saved across all supplied URLs.

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

Open linked public Map Your Show/A2Z exhibitor profiles to add displayed website, contact, category, and location fields.

## `query` (type: `string`):

Keep only exhibitors whose normalized record contains this case-insensitive text, such as a country, category, or company keyword.

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

Optional Apify Proxy or custom proxy configuration. Direct HTTP is used by default.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://antique.a2zinc.net/OMBAS2026/Public/Exhibitors.aspx?Index=All"
    }
  ],
  "maxItems": 20,
  "includeDetails": true,
  "query": "",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing all normalized exhibitor records.

# 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://antique.a2zinc.net/OMBAS2026/Public/Exhibitors.aspx?Index=All"
        }
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/public-exhibitor-directory-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://antique.a2zinc.net/OMBAS2026/Public/Exhibitors.aspx?Index=All" }],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/public-exhibitor-directory-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://antique.a2zinc.net/OMBAS2026/Public/Exhibitors.aspx?Index=All"
    }
  ],
  "maxItems": 20
}' |
apify call automation-lab/public-exhibitor-directory-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/public-exhibitor-directory-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/ywMX3SU9ILqGX7FjL/builds/GqbOTOVUm4cyQQccF/openapi.json
