# Website Contact & Lead Extractor (`meaningful_quarry/website-contact-scraper`) Actor

Extracts email addresses, phone numbers, physical addresses, and social media links (LinkedIn, Twitter/X, Facebook, Instagram, YouTube) from any list of websites. Features customizable crawl depth, per-domain page limits, and proxy configuration.

- **URL**: https://apify.com/meaningful\_quarry/website-contact-scraper.md
- **Developed by:** [Avira](https://apify.com/meaningful_quarry) (community)
- **Categories:** Lead generation, Automation, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $2.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## Website Contact Scraper Apify Actor

A production-ready website contact scraper designed to crawl websites recursively, extract contact information, and output structured data. Perfect for B2B lead generation, CRM enrichment, and automated outreach campaigns.

This Actor extracts:

- **Email addresses** (filtered to remove static assets like image/font files)
- **Phone numbers** (standardized and filtered for false positives)
- **Social Media links** (LinkedIn, Facebook, Instagram, Twitter/X, YouTube, TikTok, GitHub, Pinterest, and Medium profiles)
- **Physical Addresses** (using heuristic text checks and `<address>` tag parsers)

***

### Features

- ⚡ **Extremely Fast**: Built with Crawlee's `CheerioCrawler` to parse raw HTML directly without the overhead of a headless browser.
- 🎯 **Targeted Crawling**: Prioritizes contact, about, team, and help pages if `crawlShortcutLinksOnly` is enabled to save crawl budget.
- ⚙️ **Configurable Limits**: Set max pages per domain and maximum depth to prevent runaway runs on large sites.
- 🔄 **Consolidated Output**: Automatically aggregates and de-duplicates contact information collected across multiple pages of the same domain into a single clean JSON record.
- 🛡️ **Proxy Support**: Fully integrated with Apify Proxy or custom proxies to bypass rate limits and geoblocks.

***

### Input Parameters

The Actor accepts the following inputs (defined in `.actor/input_schema.json`):

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `startUrls` | Array | Yes | | List of site URLs to scan (e.g. `[{"url": "https://crawlee.dev"}]`). |
| `maxDepth` | Integer | No | `2` | Maximum crawl depth. Depth `1` is start URLs only. |
| `maxPagesPerDomain` | Integer | No | `20` | Maximum pages to crawl per start URL domain to limit budget. |
| `crawlShortcutLinksOnly` | Boolean | No | `true` | When true, skips pages that do not match contact-related keywords in their path or title. |
| `proxyConfiguration` | Object | No | `{ "useApifyProxy": true }` | Apify Proxy or custom proxies configuration. |

***

### Example Input JSON

```json
{
  "startUrls": [
    { "url": "https://crawlee.dev" },
    { "url": "https://apify.com" }
  ],
  "maxDepth": 2,
  "maxPagesPerDomain": 15,
  "crawlShortcutLinksOnly": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

***

### Example Output JSON

For each start URL domain, a single merged dataset row is saved:

```json
{
  "domain": "crawlee.dev",
  "startUrl": "https://crawlee.dev",
  "emails": [
    "info@apify.com"
  ],
  "phones": [
    "+1 (234) 567-8900"
  ],
  "socialLinks": {
    "linkedin": [
      "https://linkedin.com/company/apify"
    ],
    "facebook": [
      "https://facebook.com/apifytech"
    ],
    "twitter": [
      "https://twitter.com/apify"
    ],
    "github": [
      "https://github.com/apify"
    ]
  },
  "addresses": [
    "Prague, Czech Republic"
  ],
  "pagesCrawled": 3,
  "crawledUrls": [
    "https://crawlee.dev/",
    "https://crawlee.dev/docs/introduction",
    "https://crawlee.dev/about"
  ]
}
```

# Actor input Schema

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

List of URLs of the websites you want to crawl and extract contacts from.

## `maxDepth` (type: `integer`):

Maximum depth of links to follow. Depth 1 means only start URLs. Depth 2 means start URLs and links found on them.

## `maxPagesPerDomain` (type: `integer`):

Limit of pages to crawl per start URL domain to prevent crawling infinite sites.

## `crawlShortcutLinksOnly` (type: `boolean`):

If enabled, crawler will prioritize links that match contact keywords (e.g. contact, about, info, support, team). Highly recommended to save resources and speed up scraping.

## `maxConcurrency` (type: `integer`):

Maximum number of pages crawled simultaneously. Higher values speed up the run but increase resource usage.

## `maxRequestRetries` (type: `integer`):

Number of times the crawler retries fetching a page if it fails (e.g., due to temporary network timeouts).

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

Specifies whether to use proxies.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://crawlee.dev"
    }
  ],
  "maxDepth": 2,
  "maxPagesPerDomain": 20,
  "crawlShortcutLinksOnly": true,
  "maxConcurrency": 10,
  "maxRequestRetries": 2,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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://crawlee.dev"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("meaningful_quarry/website-contact-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://crawlee.dev" }],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("meaningful_quarry/website-contact-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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://crawlee.dev"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call meaningful_quarry/website-contact-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=meaningful_quarry/website-contact-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/KelP88fHMz86bgcJ1/builds/PuFH7D653icysvwvg/openapi.json
