Website Contact Extractor avatar

Website Contact Extractor

Pricing

from $3.00 / 1,000 domain contacts

Go to Apify Store
Website Contact Extractor

Website Contact Extractor

Extract contact information (emails, phone numbers, social profiles, addresses) from websites by crawling homepage, contact, about, and footer links. One structured result per domain with CSV and Markdown export.

Pricing

from $3.00 / 1,000 domain contacts

Rating

0.0

(0)

Developer

Harsh

Harsh

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Extract emails, phone numbers, social profiles, and addresses from one or more websites.

Website Contact Extractor is an Apify Actor built with TypeScript and Crawlee CheerioCrawler. Point it at company homepages — it crawls the landing page plus contact/about/footer links, deduplicates contacts per domain, and writes a structured dataset plus CSV and Markdown summaries.

Features

  • Email extractionmailto: links, page text regex, schema.org; filters noise (example.com, Sentry, Wixpress, noreply, image extensions)
  • Phone extractiontel: links, international patterns, itemprop="telephone"
  • Social profiles — LinkedIn, Twitter/X, Facebook, Instagram, YouTube, TikTok, GitHub
  • Physical addresses — schema.org PostalAddress, microdata, footer <address> blocks
  • Contact page discovery — follows contact, about, team, support, locations, impressum links
  • Company name — from og:site_name, page title, or JSON-LD Organization
  • Per-domain deduplication — one dataset item per domain with merged contacts
  • Rate limiting & retries — configurable concurrency, delay, and request retries
  • Proxy-ready — optional Apify Proxy configuration
  • ExportsCONTACTS.csv and CONTACTS.md in the default key-value store

Installation

# Clone / open the Actor directory
cd website-contact-extractor
# Install dependencies
npm install
# Run locally (uses storage/key_value_stores/default/INPUT.json or --input)
apify run

On the Apify platform, deploy with apify push or use the published Actor from the Store.

Input

FieldTypeRequiredDefaultDescription
startUrlsobject[]YesHomepage URLs to extract contacts from
maxPagesPerDomainintegerNo10Max pages crawled per domain
maxConcurrencyintegerNo5Parallel request limit
maxRequestRetriesintegerNo3Retries for failed requests
requestDelayMsintegerNo200Delay hint for rate limiting
followContactLinksbooleanNotrueCrawl discovered contact/about links
includeEmailsbooleanNotrueExtract emails
includePhonesbooleanNotrueExtract phones
includeSocialsbooleanNotrueExtract social profiles
includeAddressesbooleanNotrueExtract physical addresses
proxyConfigurationobjectNoProxy offApify Proxy settings

Example input

{
"startUrls": [
{ "url": "https://www.apify.com" },
{ "url": "https://www.shopify.com" },
{ "url": "https://stripe.com" }
],
"maxPagesPerDomain": 5,
"maxConcurrency": 5,
"requestDelayMs": 200,
"followContactLinks": true,
"includeEmails": true,
"includePhones": true,
"includeSocials": true,
"includeAddresses": true
}

See also: examples/input.json

Output

Each dataset item is one domain:

FieldTypeDescription
domainstringNormalized host without www
urlstringStart URL for the domain
companyNamestring | nullDetected company/site name
emailsstring[]Deduplicated emails
phonesstring[]Deduplicated phones
socialsobjectMap of platform → profile URL
addressesstring[]Physical addresses when found
contactPageUrlsstring[]Discovered contact/about URLs
pagesScrapedintegerPages successfully scraped
scrapedAtstringISO timestamp
errorstring | nullPresent if the domain failed entirely

Example output

{
"domain": "apify.com",
"url": "https://www.apify.com",
"companyName": "Apify",
"emails": ["hello@apify.com"],
"phones": [],
"socials": {
"linkedin": "https://www.linkedin.com/company/apifytech",
"twitter": "https://twitter.com/apify",
"github": "https://github.com/apify"
},
"addresses": [],
"contactPageUrls": ["https://apify.com/contact"],
"pagesScraped": 3,
"scrapedAt": "2026-07-13T12:00:00.000Z"
}

Key-value store exports

KeyContent typeDescription
CONTACTS.csvtext/csvFlat CSV summary of all domains
CONTACTS.mdtext/markdownHuman-readable Markdown report
OUTPUTapplication/jsonRun summary stats

See also: examples/output.json

How it works

  1. Start URLs — Each unique domain is queued once (first URL wins as the primary).
  2. Homepage scrape — Cheerio parses the page for emails, phones, socials, addresses, and company name.
  3. Contact link discovery — Same-domain links matching contact/about/team/support/locations patterns are enqueued (up to maxPagesPerDomain).
  4. Merge & dedupe — Contacts from all pages are merged per domain.
  5. Export — One dataset item per domain, plus CONTACTS.csv and CONTACTS.md.

Pricing

$0.003 per domain result using Apify pay-per-event (apify-default-dataset-item). Charged once per domain written to the dataset.

Run locally

npm install
npm run build
npm test
apify run -p -i examples/input.json

Limitations

  • Static HTML only — Uses Cheerio (no browser). Contacts injected purely via client-side JavaScript may be missed.
  • Obfuscated emails — Cloud-encoded or image-only emails are not decoded.
  • Address detection — Best with schema.org / microdata; free-form footer text is heuristic.
  • Phone false positives — Aggressive phone regex can occasionally match non-phone number sequences; noise filters reduce this.
  • Same-domain only — Contact links on other domains are not followed.
  • Rate limits — Aggressive settings may trigger site WAF/bot protection; enable Apify Proxy for production.

FAQ

How many pages are crawled per site?
Up to maxPagesPerDomain (default 10): the start URL plus discovered contact/about links.

Can I extract only emails?
Yes. Set includePhones, includeSocials, and includeAddresses to false.

Does it work without a proxy?
Yes for small local tests. For bulk production runs, enable proxyConfiguration.useApifyProxy.

Where is the CSV?
In the run’s default key-value store under key CONTACTS.csv.

One result or many?
One dataset item per unique domain, regardless of how many pages were scraped on that domain.

Changelog

1.0.0

  • Initial release
  • Email, phone, social, address extraction with CheerioCrawler
  • Contact/about link following and per-domain deduplication
  • CSV and Markdown exports
  • Input flags for selective extraction
  • LEAD_GENERATION + DEVELOPER_TOOLS categories

License

Apache-2.0