# Website Tech Stack & Contact Scraper (`glitchbound/website-scraper`) Actor

Analyse any website in bulk: detect the platform (Shopify, WordPress, Wix, Webflow, Magento…), framework, analytics, marketing tools and payment providers, plus the business contact email and social links the site publishes. Filter by platform, e-commerce, or sites running no analytics at all.

- **URL**: https://apify.com/glitchbound/website-scraper.md
- **Developed by:** [Daniel Meshulam](https://apify.com/glitchbound) (community)
- **Categories:** Lead generation, SEO tools, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 1,000 websites

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

## Website Tech Stack & Contact Scraper

Analyse any list of websites in bulk. For each one: **what it's built on**, what tools it runs, and the business contact details it publishes.

### What you get

| Field | Example |
|---|---|
| **`platform`** | `shopify` · `wordpress` · `wix` · `webflow` · `squarespace` · `woocommerce` · `magento` · `bigcommerce` · `drupal` · `ghost` · `framer` … |
| **`isEcommerce`** | `true` |
| `frameworks` | `["nextjs","react"]` |
| `analytics` | `["google-analytics","meta-pixel","hotjar"]` |
| `marketing` | `["klaviyo","intercom"]` |
| `payments` | `["stripe","shoppay"]` |
| `hasAnalytics`, `hasLiveChat`, `isHttps` | |
| `primaryEmail`, `emails` | `bulkorders@allbirds.com` |
| `socialLinks` | `{instagram: …, facebook: …, linkedin: …}` |
| `title`, `description`, `ogTitle`, `ogImage`, `siteName`, `language` | |
| `server`, `poweredBy`, `generator`, `finalUrl` | |

### Detection is structural, not keyword matching

A platform is only reported when a **structural marker** is present, a CDN host, an asset path, a generated class, a JS global. Matching the bare product name flagged `stripe.com` as WooCommerce during testing, purely because their integration docs mention it. That class of false positive is what makes tech-stack data useless for outreach, so it's designed out.

### Filters that build lists

```json
{
  "websites": ["shop-a.com", "shop-b.com"],
  "platformFilter": ["wordpress"],
  "withoutAnalyticsOnly": true
}
```

- **`platformFilter`**: everyone on WordPress, or everyone on Shopify
- **`ecommerceOnly`**: only real storefronts
- **`withEmailOnly`**: drop sites with no published contact
- **`withoutAnalyticsOnly`**: sites running **no analytics tag at all**: a strong signal of an unmaintained site, and a ready-made pitch list

Filtered-out sites are **not charged**.

### Pairs with the Local Business Scraper

Run [Local Business Scraper](https://apify.com/glitchbound/places-scraper) to get businesses in a city, feed the domains in here, and you have a qualified list, who's on which platform, who's running no analytics, who to contact.

### Who this is for

- **Agencies**: find every WordPress site in your market, or every store with no analytics
- **SaaS sales**: territory lists segmented by the tools prospects already run
- **Competitive research**: what your competitors' stack looks like
- **E-commerce**, which platform and payment providers a market uses

### Privacy, role addresses only

This Actor collects **only generic business mailboxes** the company publishes on its own site: `info@`, `sales@`, `support@`, `careers@` and similar. Person-shaped addresses are discarded. During testing it picked up `jane.diaz@stripe.com` from Stripe's own API documentation, exactly the personal data this Actor must not collect, and that filter exists because of it.

It also does **no email pattern guessing**. Inventing `firstname.lastname@company.com` is how spam lists get built, and this Actor will not do it. Only the domain's own pages are fetched, no third-party data brokers.

### Pricing

Pay per result. One row = one website. Sites that fail to load come back as `error` rows and are **not** charged, and neither is anything your filters removed.

### A BuiltWith alternative for the part most people need

Commercial tech-lookup services price their cheapest tier around what a whole
prospecting month costs. If what you need is "which platform is this site on,
is it ecommerce, and who do I email", that is what this does, per site, with no
seat licence and no minimum.

**Website technology detection** here means the served HTML is read for
structural tells: CDN hostnames, generated asset paths, framework globals and
the `<meta name="generator">` tag.

**Platforms and CMS detected**: Shopify, WooCommerce, Magento, BigCommerce,
PrestaShop, Wix, Squarespace, Webflow, WordPress, Drupal, Joomla, Ghost,
HubSpot CMS, Framer, Carrd.

Alongside the platform you get analytics and marketing tags, payment providers,
frameworks, social profiles, contact emails, the server header, HTTPS status and
whether the site is ecommerce.

**What it does not do.** It does not track a technology's history over time, and
it does not report install counts across the web. Those are the things the paid
services build their index for, and no single-site fetch can produce them.

### Notes

- `includeContactPage` follows the site's own contact/about link for details missing from the home page. It costs one extra request per site; turn it off to halve the run time.
- Detection reads the served HTML. Content rendered entirely client-side after load can be missed on heavily JS-driven sites.
- Set a **max charge per run** in the run options for a hard spend ceiling. The Actor honors it and stops cleanly.

# Actor input Schema

## `websites` (type: `array`):

Websites to analyse, one per line: "allbirds.com" or "https://stripe.com" both work. You can paste the URL instead of the identifier, e.g. https://www.allbirds.com/collections/mens works.

## `includeContactPage` (type: `boolean`):

Follow the site's own contact/about link to pick up details not shown on the home page. Costs one extra request per site.

## `platformFilter` (type: `array`):

Only keep sites built on these, e.g. shopify, wordpress, woocommerce, wix, squarespace, webflow, magento, bigcommerce, drupal, ghost, framer.

## `ecommerceOnly` (type: `boolean`):

Only sites running a shopping platform (Shopify, WooCommerce, Magento, BigCommerce, PrestaShop).

## `withEmailOnly` (type: `boolean`):

Drop sites that publish no contact email.

## `withoutAnalyticsOnly` (type: `boolean`):

Sites running no analytics tag at all, a strong signal of an unmaintained site, and a useful pitch list for marketing agencies.

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

Proxy settings. Many sites sit behind Cloudflare and reject datacenter IPs, so residential proxy is the default and is recommended, and changing it will cause HTTP 429 errors on those sites.

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

A hard ceiling on rows for the entire run, across every target. The per-target limits above cap each one separately, so fifty targets at twenty each is still a thousand rows; this caps the total. The run stops cleanly when it is reached and nothing beyond that point is fetched or charged. Leave empty for no ceiling.

## Actor input object example

```json
{
  "websites": [
    "allbirds.com",
    "stripe.com"
  ],
  "includeContactPage": true,
  "ecommerceOnly": false,
  "withEmailOnly": false,
  "withoutAnalyticsOnly": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

Website technology stack, analytics, payments and published contacts.

# 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 = {
    "websites": [
        "allbirds.com",
        "stripe.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("glitchbound/website-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 = { "websites": [
        "allbirds.com",
        "stripe.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("glitchbound/website-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 '{
  "websites": [
    "allbirds.com",
    "stripe.com"
  ]
}' |
apify call glitchbound/website-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/oo1J7mUMF9iaBUApj/builds/zJVlnNmAQlolapt4Z/openapi.json
