Website Email & Phone Scraper - Contact Details Extractor avatar

Website Email & Phone Scraper - Contact Details Extractor

Pricing

$15.00 / 1,000 site with contacts founds

Go to Apify Store
Website Email & Phone Scraper - Contact Details Extractor

Website Email & Phone Scraper - Contact Details Extractor

Finds emails, phone numbers and social profiles on any website. Decodes obfuscated addresses, refuses to invent ones that are not there, and tells you when a site blocked it instead of returning a blank row. Charges only when contacts are actually found.

Pricing

$15.00 / 1,000 site with contacts founds

Rating

0.0

(0)

Developer

NeverEmpty

NeverEmpty

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

7 hours ago

Last modified

Share

Give it a list of websites. Get back the emails, phone numbers and social profiles that are actually published on them — one row per site, in the order you gave them.

The problem with contact scrapers

Most of them will hand you an address that does not exist.

Here is a real example, produced by this Actor's own first version and then fixed. A page said:

Contact the team at dealer.com for details

A naive "decode obfuscated emails" step turns at into @ and produces team@dealer.com — an address nobody wrote, on a domain that has nothing to do with the site. Send an outreach campaign to a list built that way and you are mailing strangers.

This Actor only decodes what is unambiguously obfuscationinfo [at] acme [dot] com, @ entities, Cloudflare's data-cfemail protection — and leaves ordinary English prose alone.

It also drops, before you ever see them:

  • no-reply@, donotreply@, postmaster@, abuse@, bounce@
  • @example.com, @test.com, @yourdomain.com and other placeholders
  • image filenames that look like addresses (logo@2x.png)
  • Sentry keys and other long hex strings that happen to contain @

What you get

One row per website:

FieldExample
domainwww.debian.org
oktrue — false only when nothing could be read at all
emails["press@debian.org", "events@debian.org", ...]
phones["+4998315050"] — E.164, international form
phonesLocal["8887334281"] — numbers the site declared in a tel: link or schema.org without a country code. Kept exactly as written rather than guessed at, or dropped
socials{"linkedin": [...], "twitter": [...], "github": [...]}
emailCount / phoneCount / phoneLocalCount15 / 2 / 0
pagesScanned4
sourcePagesThe exact URLs the contacts came from — so you can verify every one
reasonWhy a row is empty, when it is

sourcePages matters. Every contact can be traced back to the page it came from. If you doubt a result, you can open the page and look.

It tells you which kind of empty it is

A blank row can mean three completely different things, and most scrapers give you the same blank for all of them:

  • The site blocked usok: false, reason: "The site blocked us: blocked by the site (HTTP 403)", and you are not charged
  • The pages loaded but publish no contact detailsok: true, reason says exactly that, and you are not charged
  • We found contacts → the arrays are filled, and only then does it cost anything

It does not invent phone numbers

Phone validation is not something to hand-write. This Actor uses Google's libphonenumber — the same library your phone uses — to decide what is a phone number and what is not.

A digit sequence on a page is usually not a phone number. Measured against live pages, a naive regex turns all of these into "phone numbers":

What it really isSeen onNaive result
A float in a code sample — 5.666666666666667python.org+1 666 666 666 6667
The Fibonacci sequence — 55 89 144 233python.org+1 558 914 4233
A copyright range — 2001-2026python.org+1 200 120 26
A VAT number — DE811128135bosch.com, hetzner.com+49 811 128 135
A ZIP+4 postal code — 10504-1722ibm.com+1 105 041 722
A template placeholder — tel:111-111-1110docker.com+1 111 111 1110
A fiction-reserved number — +1 415 555 0132anywherelibphonenumber calls this valid; we still drop it

This Actor returns none of them.

It never guesses which country a number belongs to

There is no "default country code" option, and that is deliberate.

suse.com lists its offices with local numbers and no country codes. Stamp one country onto all of them and you get numbers that reach nobody:

On the pageWhat a default country code producesReality
Brussels, Belgium Tel: 31-23-8080010+49 31 238 080 010The number is Dutch
Budapest, Hungary Tel: 361-489-4600+49 361 489 4600and libphonenumber calls it a valid German landlineThe number is Hungarian
Auckland Tel: 0800 569 047+49 800 569 047New Zealand freephone

That last one is the dangerous kind: a fabricated number that passes validation, so the buyer cannot tell it is wrong.

So numbers are split into two columns:

  • phones — the number carried its own country code. Returned in E.164, ready to dial.
  • phonesLocal — the site published it without one. Returned exactly as written, never with a country guessed onto it.

Nothing is thrown away, and nothing is made up. Measured on 2026-08-27 across suse.com, bbva.com, huawei.com, ionos.de, chiyoda.lg.jp and others: 27 numbers in phones, every one of which libphonenumber confirms is valid, and 0 invented.

Two more things it gets right, each found on a real page:

  • + is a plus sign. ibm.com writes +65-6418-1000. Decode it and you have Singapore. Don't, and the +65 is lost.
  • +49 (0)9831 505-0 — the German (0) must be dropped when dialling internationally, and (+33) 01 45 66 22 22 keeps its French trunk 0. Both are handled.

It respects robots.txt

On by default. It reads each site's robots.txt, applies only the rules addressed to * or to this bot (not rules meant for someone else's crawler), honours * and $ patterns, and lets a more specific Allow override a broader Disallow — the standard interpretation.

Where it looks

The page you give it, plus the contact pages it finds from there: contact, about, company, support, and — importantly — impressum, kontakt, imprint, mentions-légales. In German-speaking countries an Impressum is legally required to carry a real address, phone number and email, which makes it the single richest page on a European site. Scrapers that only look for the English word "contact" walk straight past it.

If no such link exists, it tries the common paths directly instead of giving up.

Input

{
"websites": ["acme.com", "https://example-corp.de", "https://another.co.uk"],
"maxPagesPerSite": 5,
"respectRobots": true
}
FieldDefaultMeaning
websites3 sample sitesDomains or URLs. One row out per row in
maxPagesPerSite5Pages read per site (1–20)
respectRobotstrueRead and honour robots.txt
timeoutSecs20Per-page timeout

Pricing

You are charged per site where at least one contact was actually found (the current rate is shown on this page).

Sites that block you, and sites that simply publish no contact details, cost nothing. Compare that with per-row pricing that charges for blanks: the number that matters is the price per usable lead, not the price per row.

Typical uses

  • Building outreach lists from a set of company domains
  • Enriching a CRM with published contact details
  • Finding the right inbox for partnership, press or support enquiries
  • Compliance and due-diligence checks that need a company's published contact information

FAQ

Does it need a proxy? No. It reads ordinary company websites over plain HTTP.

Will it get blocked? Some sites block automated requests. When that happens you are told so explicitly — and not charged.

Can it find personal emails of employees? It reports what a site publishes. It does not guess address patterns, and it does not invent firstname.lastname@ combinations.

How fast is it? Roughly 5 pages per site. Three sites with five pages each took well under a minute when measured.

Other tools by NeverEmpty

Every NeverEmpty Actor follows the same rule: it never returns an empty result to mean two different things, and it only charges for rows that actually carry an answer.

  • domain-lookup - WHOIS, DNS, MX, SPF, DMARC and SSL expiry for a list of domains
  • ats-board-finder - a company domain to the ATS and board name it uses
  • seo-site-audit - technical SEO audit: meta, canonical, robots, headings

Support

Found a wrong address, or a site where a contact exists but was missed? Open an issue on the Issues tab with the domain. sourcePages in the output tells me where to look.