
Website Contact Scraper
hipersoft/website-contact-scraper
Extract business emails, phone numbers and social media profiles from any list of websites. De-obfuscates emails, reads Organization schema, and optionally crawls contact/about pages. Bulk-ready.
Total users
69Monthly users
3Total runs
1,576Per website scraped
$0.0024Last rebuilt
Oct 27, 2026Overview
Turn a list of websites into a clean contact sheet. Give the Actor any set of domains or URLs and it returns emails, phone numbers, and social media profiles for each one — ready for lead lists, CRM enrichment, or outreach.
No login, no API key. Bulk-ready: feed it thousands of sites at once.

What it extracts
| Field | Notes |
|---|---|
emails |
From mailto: links, page text, and de-obfuscated forms (name [at] site [dot] com). Junk/placeholder addresses filtered out. |
phones |
Real declared numbers only — from tel: links and Organization schema — normalized (kept in E.164-ish form). We deliberately skip loose page digits so you never get dates/IDs masquerading as phones. |
socials |
Classified links: LinkedIn, Twitter/X, Facebook, Instagram, YouTube, TikTok, Pinterest, GitHub, Telegram, WhatsApp. Share/intent URLs excluded. |
companyName |
From the site's Organization/LocalBusiness JSON-LD when present. |
address |
Postal address from structured data when present. |
domain, url |
Canonical domain and the final URL after redirects. |
pagesCrawled |
How many pages were read for this site. |
Why it's more complete
Unlike a homepage-only scraper, it optionally crawls the contact/about/imprint pages on the same site, reads JSON-LD structured data (which many sites use to publish their real email, phone, address and social links), and de-obfuscates emails that are deliberately hidden from naive scrapers.
Input
{
"websites": ["apify.com", "stripe.com", "https://example.org"],
"deepCrawl": true,
"maxPagesPerSite": 5,
"maxConcurrency": 10
}
- websites — domains or URLs, one per line. (Or use startUrls for a request list.)
- deepCrawl — follow contact/about pages for more results (default on). Turn off for one request per site.
- maxPagesPerSite — cap pages fetched per site (default 5).
- maxConcurrency — sites processed in parallel (default 10).
- maxItems — cap total sites (0 = all).
- proxyConfiguration — optional; enable if you hit blocks.
Output (one record per website)

{
"input": "apify.com",
"url": "https://apify.com/",
"domain": "apify.com",
"companyName": "Apify",
"emails": ["[email protected]", "[email protected]"],
"phones": ["+14155551234"],
"socials": {
"linkedin": "https://www.linkedin.com/company/apifytech",
"twitter": "https://twitter.com/apify",
"github": "https://github.com/apify"
},
"address": "...",
"pagesCrawled": 3,
"error": null
}
Sites where nothing was found still return a row, with error describing why
(e.g. a network block) or null when the site simply had no public contacts.
Output schema
| Field | Type | Description |
|---|---|---|
input |
string | The domain or URL you supplied for this record. |
url |
string (URL) | The final URL reached for the site after redirects. |
domain |
string | Canonical domain of the website. |
companyName |
string | Company/organization name from the site's structured data. |
emails |
array | Contact email addresses found on the site. |
phones |
array | Declared phone numbers found on the site. |
socials |
object | Social profile links keyed by network (linkedin, twitter, facebook, etc.). |
address |
string | Postal address from the site's structured data, when present. |
pagesCrawled |
integer | Number of pages read on the site for this record. |
error |
string | Reason no data was found, or null when the site simply had no public contacts. |
Pricing
Pay per website result. No monthly fee — you only pay for what you run.
FAQ
Do I need an API key or login? No. There's no login and no API key — paste your list of domains or URLs and run. It's bulk-ready, so you can feed it thousands of sites at once.
How many leads can I get per run?
One record per website, with no fixed ceiling — cap the total with maxItems (0 = all) and control depth per site with maxPagesPerSite. Feed thousands of domains in a single run.
Is scraping website contact info legal? The Actor extracts only publicly available contact details already published on the target sites. Collecting public data is generally permissible, but you are responsible for using it in line with GDPR, CAN-SPAM and each site's terms.
Does it collect emails and contact info?
Yes. It pulls emails (including de-obfuscated name [at] site [dot] com forms), declared phone numbers, social profiles, company name and postal address from page text and JSON-LD structured data.
What's the output format?
One structured JSON record per website with emails, phones, socials, companyName, address and crawl metadata. Sites with no contacts still return a row. Export as JSON, CSV or Excel.
Can I connect the Website Contact Scraper to other tools? The Website Contact Scraper can be connected with almost any cloud service or web app thanks to integrations on the Apify platform. It works with Make, Zapier, Slack, Airbyte, GitHub, Google Drive and many more, plus the Apify API, JavaScript/Python clients and MCP. Or use webhooks to trigger an action whenever a run finishes.
Combine website enrichment with these lead-generation companions:
- Google Maps Email Extractor — find local businesses on Google Maps and extract their emails and socials in one pass.
- Google Maps Scraper — get business listings with websites to feed into this Actor.
- Clutch.co Agency Scraper — pull B2B agency profiles with ratings and budget signals.
- Website Content Crawler — extract clean page text and metadata from the same sites.
Notes & fair use
Extracts only publicly available contact information already published on the target websites. You are responsible for using the data in line with applicable laws (GDPR/CAN-SPAM etc.) and each site's terms.
Input
| Field | Type | Description |
|---|---|---|
websitesWebsites | array | List of website URLs or domains to extract contacts from (e.g. "stripe.com", "https://apify.com"). One per line. |
startUrlsStart URLs (advanced) | array | Alternative to "Websites": a request list of {"url": "..."} objects, e.g. from a linked dataset or Key-Value store. |
deepCrawlCrawl contact/about pages | boolean | When on, follow up to a few likely contact/about/imprint pages on the same site for more complete results. Turn off for one-request-per-site (cheaper, faster). Default: true |
maxPagesPerSiteMax pages per site | integer | Upper bound on pages fetched per website (homepage + contact pages). Default: 5 |
maxConcurrencyConcurrency | integer | How many websites to process in parallel. Default: 10 |
maxItemsMax websites | integer | Cap on how many input websites to process (0 = no cap, process all). Default: 0 |
proxyConfigurationProxy configuration | object | Proxy configuration. Leave the default — it is tuned for reliable results. Default: {"useApifyProxy": false} |
API
curl -X POST "https://api.apify.com/v2/acts/hipersoft~website-contact-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"websites": [
"apify.com"
]
}'from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("hipersoft/website-contact-scraper").call(run_input={
"websites": [
"apify.com"
]
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('hipersoft/website-contact-scraper').call({
"websites": [
"apify.com"
]
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);Pricing
| Event | Price | Paid plans from |
|---|---|---|
| Website scraped One website processed — business emails, phone numbers and social media profiles extracted | $0.0024 | $0.0012 |
You pay only for what the run returns. Set a maximum cost per run and it stops cleanly at that limit.
Related scrapers
Threads Downloader
Download Threads photos, videos and carousel posts by URL. Paste threads.net or threads.com links and get ready-to-use download links plus direct media URLs, a thumbnail, media type and count — one row per URL as JSON, CSV or Excel. Cheap, bulk, built for creators and n8n.
799 runs · 4 users · $0.003 / post downloadedTikTok Video Downloader
Download TikTok videos without watermark in bulk. Paste video or photo-slideshow URLs and get a clean HD MP4 download link plus full metadata: caption, author, play/like/comment/share counts, sound and cover — one row per post as JSON, CSV or Excel. For creators, research and n8n.
678 runs · 9 users · $0.0035 / video downloadedReddit Scraper
Scrape Reddit posts and comments by subreddit, keyword, author or thread URL. Get titles, self-text, scores, upvote ratio, comment counts, comment trees and permalinks — one clean row per post or comment. Export as JSON, CSV or Excel.
568 runs · 15 users · $0.0034 / post scrapedSpotify Scraper
Search Spotify and scrape public metadata for tracks, artists, albums and playlists: names, artists, popularity, followers, genres, release dates, duration, ISRC, preview URL and more. No Spotify login or API key required. For music research, catalogs and analytics.
478 runs · 9 users · $0.0034 / item scrapedReddit Video, Image & GIF Downloader
Download Reddit videos, images and GIFs by post URL. Paste reddit.com or redd.it links and get ready-to-use download links — videos as a single playable MP4 with audio, images and galleries as direct links — one row per URL as JSON, CSV or Excel. Cheap, bulk, built for creators and n8n.
453 runs · 16 users · $0.003 / item scrapedYouTube Scraper
All-in-one YouTube API: get video metadata, full transcripts, comments with replies, channel data, and search results in a single call. No setup, fast and cheap.
350 runs · 52 users · $0.0032 / video scrapedSend the site and the fields. We build it and you get it first.