Contact Details Scraper - Emails, Phones & Socials avatar

Contact Details Scraper - Emails, Phones & Socials

Pricing

$1.50 / 1,000 websites

Go to Apify Store
Contact Details Scraper - Emails, Phones & Socials

Contact Details Scraper - Emails, Phones & Socials

Contact details are rarely on the homepage. They live on /contact, /about, and the /impressum German law requires carry a real email. A short crawl of them returns emails ([at] obfuscation included), phones, addresses, contact forms and 10 socials. $1.50 per 1,000 sites, flat.

Pricing

$1.50 / 1,000 websites

Rating

0.0

(0)

Developer

Dami's Studio

Dami's Studio

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

2 days ago

Last modified

Share

Contact Details Scraper

§5 of Germany's Digitale-Dienste-Gesetz makes a company publish a working email address on its Impressum page, and says a contact form on its own does not satisfy it. Sites elsewhere keep their details on the same kinds of pages without being made to. One row per website, carrying whatever public contact details that site publishes: email addresses, phone numbers, postal addresses, social profiles, and any contact forms it has, down to the field names those forms expect.

It doesn't stop at the homepage. Each site gets a short crawl weighted towards the pages that usually hold the details: contact, about, team, legal, imprint.

What you get

One row per website:

{
"siteUrl": "https://apify.com/about",
"requestedUrl": "https://www.apify.com/",
"domain": "apify.com",
"title": "Apify: The largest marketplace of trusted tools for AI",
"description": "Thousands of tools to automate your business...",
"emails": [
{ "email": "hello@apify.com", "sourcePages": ["https://apify.com/contact"] }
],
"phones": [],
"socialLinks": [
{ "platform": "linkedin", "url": "http://linkedin.com/company/apify/",
"sourcePages": ["https://apify.com/", "https://apify.com/contact", "https://apify.com/about"] },
{ "platform": "x", "url": "https://x.com/apify", "sourcePages": ["https://apify.com/"] },
{ "platform": "github", "url": "https://github.com/apify", "sourcePages": ["https://apify.com/"] }
],
"addresses": [],
"contactForms": [
{
"action": "https://apify.com/contact-sales#",
"method": "GET",
"fields": [
{ "name": "firstName", "type": "text" },
{ "name": "email", "type": "email" },
{ "name": "demoRequirements", "type": "textarea" }
],
"hasMessageField": true,
"hasEmailField": true,
"hasPhoneField": false,
"sourcePage": "https://apify.com/contact-sales"
}
],
"jsonLdOrganizations": [],
"jsonLdPeople": [],
"crawledPages": ["https://apify.com/", "https://apify.com/contact", "https://apify.com/about"],
"pagesCrawled": 4
}

Every finding carries sourcePages. That's the part that saves you time later. When a rep asks where an email came from, you point at the exact page instead of re-checking it by hand.

contactForms is worth a look if a site publishes no email at all, which is increasingly normal. You get the form's action URL and its field names, which is what you need to reach them programmatically.

jsonLdOrganizations and jsonLdPeople come from the site's own structured data, where it has any. Named people with roles turn up here more often than you'd expect.

Social networks it recognises

Ten, and these exactly: LinkedIn, Facebook, Instagram, X/Twitter, YouTube, TikTok, Pinterest, GitHub, Threads, Bluesky. Anything else lands as a plain link and isn't classified.

Email obfuscation

hello [at] example [dot] com and similar dodges are decoded. Emails embedded in images are not, because that would need OCR. Images are the one obfuscation that still works against this.

Input

{
"websites": ["apify.com", "https://stripe.com", "example.co.uk"],
"maxPagesPerSite": 8,
"defaultCountry": "US"
}
  • websites — domains or full URLs, one per line. A value without a scheme gets HTTPS.
  • startUrls — the Apify request-list format, if that's what you already have. Combine it with websites freely.
  • maxPagesPerSite — default 6, ceiling 20. More pages finds more, takes longer, and does not change your bill. See billing.
  • defaultCountry — ISO code like US, GB, CA. Used to normalise local phone numbers written without a country code.
  • maxConcurrency — how many sites at once. Default 5, ceiling 20. Each individual site is crawled sequentially.
  • respectRobotsTxt — on by default. Pages disallowed for this actor's user agent are skipped.
  • maxResponseSizeKb — default 1536. Oversized pages are skipped, and skipping one doesn't charge you.
  • proxyConfiguration — off by default, because most business websites answer direct HTTP fine. Turn it on for sites that block cloud IPs.

Limits

  • HTML only. No JavaScript. Contact details injected by a client-side script won't be seen. Most business sites render them server-side, but a React app that fetches its footer from an API is a genuine miss.
  • 20 pages per site is the ceiling. This is a targeted crawl of likely contact pages, not a full site spider.
  • Some sites publish no contact details anywhere. emails: [] and phones: [] is a real, common result rather than an error.
  • respectRobotsTxt defaults to on, so a site that disallows crawling will return little. That's deliberate.
  • Phone number normalisation depends on defaultCountry when the number is written locally. Get it wrong and you'll get an oddly-formatted number back.

Billing

$1.50 per 1,000 websites, and there is no run-start fee.

You're billed per website, not per page. A site where the actor reads 20 pages costs exactly the same as one where it reads a single page. Raise maxPagesPerSite to find more without paying more. The only cost is wall-clock time.

Charged only for a website that was successfully crawled. Sites that failed to load, and pages skipped for size or robots.txt, aren't charged.