Skip to the content.

Website Contact Scraper

Company emails, phones and social profiles from any website (role emails only, GDPR-friendly). From $0.003 / website, pay per result, no browser, no login.

▶ Run it on Apify · Python example · All scrapers

Turn a list of websites into a clean list of company contacts. For each website this contact scraper reads the home page and the contact / about / legal pages, then returns the company’s contact emails, phone numbers, social media profiles, postal address, logo and the technologies the site uses — as JSON, CSV or Excel. No browser, so it is fast and costs a fraction of a cent per website.

✅ Company emails (info@, contact@, sales@, reservas@…) — only the addresses a business publishes for customers ✅ Phone numbers from click-to-call links, structured data and the page text, normalized (+351213218100) ✅ Social profiles: Facebook, Instagram, LinkedIn company page, X/Twitter, YouTube, TikTok, Pinterest, GitHub ✅ Postal address, company name and logo from schema.org data ✅ Technologies: WordPress, Shopify, Wix, Squarespace, Webflow, PrestaShop, HubSpot, Google Analytics, Meta Pixel, Stripe… ✅ Contact page URL for each website ✅ Finds contact pages in any language (contact, contactos, kontakt, impressum, sobre-nós, à-propos…) ✅ Pay only for websites where contacts are found — dead or empty websites are free


🛡️ GDPR-friendly by design

This Actor collects business contact details only: role-based mailboxes (info@, sales@, support@…) of the website’s own domain, company phone numbers and company social pages. It does not collect personal email addresses (firstname.lastname@), personal LinkedIn profiles or emails of other websites quoted on the page. That keeps your lead lists cleaner and much easier to use under GDPR and similar laws.


🚀 Why this contact scraper is different

  This Actor Typical contact scrapers
Price $0.003 per website (up to 5 pages included) $0.002 per page (≈ $0.01 per website)
Charged when nothing is found Never Usually
One clean row per website Yes, deduplicated across pages One row per page to merge yourself
Address, logo and technologies Yes Rarely
Personal emails Not collected (GDPR-friendly) Collected
Fake / example numbers filtered Yes No

💡 Use cases


🛠️ How to use it (3 steps)

  1. Paste websites or domains, one per line (from a spreadsheet, Google Maps results, a directory…).
  2. Keep 5 pages per website (home + contact + about + legal pages) or raise it.
  3. Click Start and download your contacts as CSV, Excel or JSON, or fetch them through the API.

📥 Input example

{
  "startUrls": ["hotelavenidapalace.pt", "https://www.apify.com", "example-bakery.de"],
  "maxPagesPerSite": 5,
  "concurrency": 10
}

📤 Output example (real run)

{
  "url": "https://hotelavenidapalace.pt/",
  "domain": "hotelavenidapalace.pt",
  "companyName": "Hotel Avenida Palace",
  "emails": ["reservas@hotelavenidapalace.pt"],
  "phones": ["+351213218100"],
  "socials": {
    "facebook": "https://www.facebook.com/HotelAvenidaPalaceLisboa",
    "instagram": "https://www.instagram.com/hotelavenidapalace"
  },
  "address": { "streetAddress": "Rua 1º Dezembro, 123", "addressLocality": "Lisboa", "postalCode": "1200-359", "addressCountry": "Portugal" },
  "logo": "https://www.hotelavenidapalace.pt/media/hotel-avenida-palace-hotelhotel-avenida-palace-exterior_3.webp",
  "technologies": ["Google Analytics", "Google Tag Manager", "Guestcentric website builder"],
  "contactPage": null,
  "pagesVisited": ["https://www.hotelavenidapalace.pt/", "https://www.hotelavenidapalace.pt/about"]
}

Websites without any contact detail, and unreachable websites, are listed in the run’s RUN_SUMMARY record — and not charged.


⚙️ Input parameters

Field Type Default Description
startUrls array ["https://www.apify.com"] Company websites or domains, one per line (example.com, https://www.example.pt). One result per website, up to 5,000 per run.
maxPagesPerSite integer 5 Home page plus contact, about and legal pages found on it. 5 finds almost everything.
concurrency integer 10 How many websites are processed at the same time.
proxyConfiguration, maxRetries object, integer Apify Proxy, auto Proxy and retries; the defaults work for most runs.

📋 Output fields

Field Type Description
url string Website as given in the input
domain string Domain without www
finalUrl string Home page after redirects
companyName string Company / site name
title string Home page title
description string Meta description
language string Page language
emails array Role emails of the company (info@, contact@, sales@…)
phones array Phone numbers, normalized
socials object Company social profiles by network
address object Postal address from structured data
logo string Logo or share image URL
technologies array CMS, e-commerce, analytics and tools detected
contactPage string Contact page URL
pagesVisited array Pages read on the website

Export as JSON, CSV, Excel, XML or HTML, or read it through the API.


💰 Pricing — pay only for websites with contacts

What you run Cost (free plan)
100 websites $0.30
1,000 websites $3.00
5,000 websites $15.00

Higher Apify plans pay less: $0.0025 (Bronze), $0.002 (Silver), $0.0015 (Gold and above). Platform usage and proxies are included. Set a maximum cost per run and the Actor stops cleanly when it is reached.


🔌 API & integrations

Python

from apify_client import ApifyClient  # pip install "apify-client>=3"

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("victorrodi/website-contact-scraper-api").call(
    run_input={"startUrls": ["hotelavenidapalace.pt", "apify.com"]}
)
for company in client.dataset(run.default_dataset_id).iterate_items():
    print(company["domain"], company["emails"], company["phones"])

JavaScript / Node.js

import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('victorrodi/website-contact-scraper-api').call({ startUrls: ['apify.com'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

cURL

curl -X POST "https://api.apify.com/v2/acts/victorrodi~website-contact-scraper-api/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" \
  -d '{"startUrls": ["apify.com"]}'

Works with Google Sheets, HubSpot, Make, Zapier, n8n, Clay and MCP / AI agents (Claude, ChatGPT, Cursor) through Apify integrations — e.g. “Find the contact email and phone of these 20 hotels’ websites.”


🤖 Use it from AI agents (Claude, ChatGPT, Cursor…)

This Actor is available to AI assistants through the Apify MCP server. Add the server to Claude Desktop, Claude Code, Cursor or any MCP client, then simply ask:

“Find the contact email and phone of these 20 company websites and put them in a table.”

“Use victorrodi/website-contact-scraper-api to get the LinkedIn and Instagram pages of these shops.”

The clean, flat output is designed to be read directly by LLMs.


🛡️ Reliability

More examples and docs for all our Actors: Vicshock/trendpulse-scrapers.


📌 Tips

❓ FAQ

Does it collect personal data? It is built not to: only role-based company mailboxes of the website’s own domain, company phones and company social pages. You remain responsible for how you use the data (GDPR, CAN-SPAM, ePrivacy).

Why is an email I can see on the site missing? It is either a personal address (firstname@…), an address of another domain, or it is only shown inside an image or a contact form.

How many websites per run? Up to 5,000. Split bigger lists into several runs.

💬 Support

Missing a field or found an issue? Open an issue in the Issues tab — it is answered fast.