DEV Community

Gio Rich
Gio Rich

Posted on

How to export Yellow Pages business leads to CSV or Google Sheets (no code, API, n8n)

I built this actor; it's a paid tool on Apify ($1.50 per 1,000 businesses) with a free trial credit.

"How do I export Yellow Pages to Excel?" is one of those questions with no good official answer. YellowPages.com has no export button and no public API, copy-paste breaks the address into one messy cell, and the site sits behind Cloudflare, which stops most quick scripts after a page or two.

I wrote an earlier post on the Python side (finding businesses without a website). This one is for the person who just wants the spreadsheet: three ways to get a clean CSV out of Yellow Pages Scraper, from zero code to a weekly automated feed into Google Sheets or a CRM. All numbers are from a real 256-row run on 24 Sep 2026 (plumbers and dentists in Austin and Denver, roofers and pizza in Charlotte).

What ends up in the spreadsheet

One row per business, with the columns a CRM import wants already split:

Column What it is Filled in our run
name, categories Business name and YellowPages categories 256 of 256
phone, phoneE164 (704) 251-9995 and +17042519995 for dialers and SMS tools 256 of 256
street, city, state, zip Address already split all with a street address
website, websiteDomain Full URL and bare domain for dedupe and enrichment 239 of 256
rating, reviewCount, yearsInBusiness Reputation and age when YellowPages shows them
isClaimed Whether the owner claimed the listing all rows
email, services, paymentMethods, socialLinks Only with includeDetails: true (one extra page per business) email on 12 of 21 detail rows

Real rows (roofing contractors, Charlotte NC):

name phone city website yearsInBusiness
Murr And Laney Inc (980) 501-6075 Pineville, NC murrlaney.com 61
JW Services Inc of NC (980) 334-6603 Concord, NC jwservicesofnc.com 22
D&W, Inc. (704) 598-9316 Charlotte, NC dwincnc.localsearch.com 43

A useful pattern from the same run: most local listings are unclaimed. 43 of 56 Austin dentists, 50 of 60 Austin plumbers and 51 of 60 Denver dentists had never claimed their YellowPages page. If you sell local SEO or listing management, that column is your prospect filter.

Way 1: the form (no code, 2 minutes)

  1. Open the actor page and click Try for free.
  2. Search terms: what you'd type in the YellowPages "Find" box, one per line (plumber, hvac contractor).
  3. Locations: City, ST or a ZIP code, one per line (Austin, TX, Denver, CO, 10001). Every term runs in every location.
  4. Max results: per term and location. 100 is a good start; a big metro tops out around 3,000 per search, so split by ZIP for full coverage.
  5. Tick Include details only if you need emails. It opens one page per business, so it's slower; switch the proxy to RESIDENTIAL for those runs.
  6. Click Start, then in Output download CSV or Excel.

Way 2: one HTTP call that returns a CSV

Apify has a "run and wait for the data" endpoint. This returns the CSV directly, which is handy in a shell script, Google Apps Script or anything that can make an HTTP request:

curl -X POST \
  "https://api.apify.com/v2/acts/rel8ble~yellowpages-scraper/run-sync-get-dataset-items?format=csv" \
  -H "Authorization: Bearer <YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"searchTerms":["plumber"],"locations":["Austin, TX"],"maxResults":100}' \
  -o austin_plumbers.csv
Enter fullscreen mode Exit fullscreen mode

The sync endpoint waits up to 5 minutes, which is plenty for a few hundred listings without details. For bigger jobs, start the run, then fetch the dataset when it finishes:

from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("rel8ble/yellowpages-scraper").call(run_input={
    "searchTerms": ["plumber", "electrician", "roofing contractors"],
    "locations": ["Austin, TX", "Denver, CO", "Charlotte, NC"],
    "maxResults": 300,
})
csv_bytes = client.dataset(run["defaultDatasetId"]).get_items_as_bytes(item_format="csv")
open("leads.csv", "wb").write(csv_bytes)
Enter fullscreen mode Exit fullscreen mode

Nine searches, up to 2,700 businesses, in one file.

Way 3: a weekly feed into Google Sheets or your CRM (n8n or Make)

For a territory list that stays fresh, schedule it:

n8n: install the Apify node (Settings > Community nodes, @apify/n8n-nodes-apify), then build Schedule Trigger (weekly) > Apify node: run actor rel8ble/yellowpages-scraper with the input JSON above and wait for it > Apify node: get the run's dataset items > Google Sheets "Append or update row" matched on ypid. Matching on ypid (YellowPages' own ID) keeps the sheet free of duplicates across runs.

Make: Apify "Run an Actor" (wait for finish on) > Apify "Get Dataset Items" > Google Sheets "Add a Row" or your CRM's "Create a Contact" module, mapping name, phoneE164, street, city, state, zip, website.

Zapier: trigger "Finished Actor Run" from the Apify app on a scheduled run, then "Fetch Dataset Items" into Sheets or HubSpot.

If you'd rather not wire anything, Apify's built-in Schedules run the actor weekly on their own, and you download the latest CSV when you need it.

Cleaning tips before you import

  • Drop sponsored cards. includeSponsored is off by default because YellowPages' ad cards are often from other cities.
  • Service-area businesses (isServiceAreaOnly: true) have no street address. Keep them for phone outreach, skip them for mailers.
  • Dedupe across overlapping cities on ypid or phoneE164, since a Pineville roofer shows up in a Charlotte search too.
  • Respect the rules of your channel. These are public business listings; cold calling and emailing still fall under TCPA, CAN-SPAM and your CRM's terms.

Cost

$1.50 per 1,000 businesses, pay per result; failed pages are never charged. The 256-row run above comes to about $0.38 at that price. The Apify free plan's monthly credit covers a few thousand leads.

Store page: https://apify.com/rel8ble/yellowpages-scraper
Python examples (MIT): https://github.com/Rel8ble/yellowpages-scraper-python

This article was drafted with AI and published by me.

Top comments (0)