牙科診所零美元潛在客戶開發實測:34 間診所、9 個電郵地址、1 個 A 級潛在客戶
34 dental clinics, 9 emails, 1 A-tier: the honest math of a $0 lead-gen run
作者以自有的五個 Python 腳本取代每月 $49–$299 的潛在客戶開發工具組,並在 Tucson 的 34 間牙科診所進行零美元實測,找到 9 個電郵地址,只有 1 個列為 A 級。9 個地址中,1 個來自診所網站、1 個來自網域搜尋,7 個只是未核實的格式推測;另有 3 間診所沒有找到電郵。
34 dental clinics, 9 emails, 1 A-tier: the honest math of a $0 lead-gen run
I replaced a $49–$299-a-month lead-gen stack with five small Python scripts I own outright. That part was easy. The part nobody tells you about is what happens when you actually run them: most of what you scrape is not a lead. Most of what you find is not an email. And most of the emails you find are guesses.
Last week I ran the whole stack end to end on real businesses — dental clinics in Tucson, Arizona, pulled from OpenStreetMap. Thirty-four businesses went in. Nine email addresses came out. One of them was worth writing to today.
Why does that matter? Because:
- The scrape is the easy 10%. The list you send to is the other 90%.
- Every dead address you mail is a small vote against your own domain.
- A "lead" that was never verified is not a lead. It is a row in a spreadsheet.
Cold outreach is not a volume game. It is a verification game, and the scoreboard is public: 34 → 12 → 9 → 1.
Every prospect gets a grade before it gets an email
The system has one rule: nothing gets sent until it has been graded. The grade is a tier, A to D, and the tier is decided by three questions.
1. Found — does the business exist, with a real site and a real address?
A name from a directory is not a prospect. A prospect has a website, a phone, a street address — things you can check in thirty seconds. If you cannot find the business, you cannot write to it, and it does not go on the list.
2. Reachable — is there an email, and where did it come from?
Not all emails are equal. One pulled from the business's own website is worth ten guessed from a pattern. My enricher tags every address with its source: website-scrape, domain-scrape, pattern-guess, or none. The source is the confidence. A pattern guess is a hypothesis, not an address.
3. Worth the send — is this the decision-maker, with one real fact about them?
An email to info@ with nothing personal is a flyer. A tier-A lead is a verified address, a decision-maker, and one real fact found in two minutes of looking. That fact is the whole email. Without it, the send is noise.
The tiers, in plain words:
- A — verified, decision-maker, one real fact found. Send today.
- B — verified, decision-maker, fact still to find. Two minutes of looking turns a B into an A.
- C — verified, but the wrong person, or no angle. Park it.
- D — dead or risky. Never send. Every D you mail is a vote against your own domain.
The tier is not a label. It is the send order. A goes first, D never goes at all.
The five scripts, in the order a campaign runs
1. scrape_maps.py — builds the list. Niche times city, from free OpenStreetMap data, no API key. Names, sites, phones, addresses. The pain it kills: "I don't have a list." You don't need a list to start. You need thirty businesses that look like your last client.
2. enrich_emails.py — finds the address, and tags where it came from. It pulls emails from business websites and marks the source honestly — website, domain, pattern guess, or none. The pain it kills: mailing a list you never checked. What you get is a list you can defend.
3. dedupe_score.py — dedupes and grades. Same business twice, same email twice — one survives. Then every row gets a score and a tier. The pain it kills: sending twice to the same clinic and looking like a bot. What you get is a send order.
4. write_opener.py — drafts the first line from one real fact. Not a template with the name swapped in. A draft built from something true about that business. The pain it kills: the blank page. What you get is a draft you can finish in two minutes instead of a template you send to everyone.
5. send_track.py — sends from your own SMTP, with tracking. Your server, your domain, unsubscribes honored, every send logged in SQLite. The pain it kills: paying a subscription to press "send" on your own words. What you get is a campaign you own.
Around the scripts sit four SOPs and twenty prompts. Requirements are boring on purpose: Python 3.10+, an email account, 90 minutes a week.
The run: 34 clinics in Tucson, line by line
Niche: dental. City: Tucson, Arizona. Source: OpenStreetMap via Overpass, bounding box 32.05,-111.00 to 32.28,-110.82. The run happened on my own VM — my sandbox couldn't reach Overpass through its proxy, so the real run went where the network works. That is a lesson, not a footnote: a tool is only as good as the machine it runs on.
Here is the whole run, with nothing rounded:
- 34 businesses scraped. Thirty-four dental clinics with names, sites, phones, addresses.
-
12 enriched. The enrich step was capped at twelve fetches (
--max-fetch 12), so twelve rows went through the gate. - 9 of 12 had an email address. Nine rows came back with something to send to. Three came back with nothing.
- Tiers of the 12: A:1, B:2, C:5, D:4. One A, two Bs, five Cs, four Ds. That is the whole campaign in one line.
- 9 personal drafts written. One draft per address found, each built from a real fact about that clinic.
And here is the part most "lead-gen" posts leave out — where the nine emails actually came from:
- 1 from the website itself (confidence 85). The A-tier clinic, OrthoPros: info@ pulled straight from its own site. This is the only address in the run I would bet on.
- 1 from a domain scrape (confidence 70). Swan Dental: a real address found on the domain, not guessed.
- 7 pattern guesses (confidence 35 each). firstname@, info@, contact@ — the standard patterns, unconfirmed. Seven of nine. That is the honest shape of a scraped list.
- 3 with no email at all (confidence 0). Enriched, graded D, never sent.
The A-tier draft, verbatim from the run:
Hi,
noticed OrthoPros in Tucson: quick question about missed calls after hours turning into lost bookings.
We build an AI receptionist that answers every call, books directly into your calendar, and follows up no-shows.
Hiring for this takes 3-6 months; we deliver working in ~30 days, fixed price.
Worth a 15-min look? I can show you exactly how it would work for OrthoPros.
Nur
P.S. Reply STOP and I won't email again.
One fact (missed calls after hours), one cost of inaction (lost bookings), one offer, one question. Sixty seconds to write once the fact was found.
Now the arithmetic nobody wants to do. Nine addresses, at the honest reply rate of 3–8% on a clean list, is zero to one replies. Not ten. Not "a flood of leads". Zero to one. And that is the point: one batch of 34 scraped businesses is not a campaign. It is a Tuesday. The system works when you run it every week — 34 becomes 340, 9 becomes 90, and 3–8% of 90 is a pipeline.
Side note: if I were starting from zero, I would run the smallest possible batch first — ten businesses, not a hundred — and read every bounce and every silence before scaling. The list teaches you; volume just amplifies whatever the list already is.
What doesn't work
- Treating pattern guesses as verified addresses. Seven of my nine emails were guesses at 35/100 confidence. Mail them all and you are gambling with your domain's reputation, not doing outreach.
- Skipping the tier step and blasting the whole list. The four D-tier rows in this run had no email or no angle. Sending to them anyway would have been four votes against my own domain for zero possible replies.
- Judging the system on one batch. Thirty-four businesses is a test, not a result. The honest math says one batch gives you zero to one replies. The system earns its keep at ten batches.
- Buying lists instead. Half the addresses are dead, every send teaches the inbox to ignore your domain, and you paid for the privilege.
- Running it where the network doesn't reach. My sandbox couldn't touch Overpass, so the run moved to the VM. A tool you can't run is a tool you don't have — check the environment before you blame the script.
- Cold mail from your main domain. One burned domain and your real business email starts landing in spam too. Separate domain, warm it slowly, keep volumes small.
And the honest bottom line: $0 in revenue from this run so far. The scripts are free, the list is free, and the first sale is still ahead of me. I am not writing this as a victory lap. I am writing it because the math above is the math most lead-gen content hides — and it is the only math that tells you what to do next.
TLDR
Thirty-four dental clinics scraped, twelve enriched, nine emails found, tiers A:1/B:2/C:5/D:4, nine drafts written. Only one email came straight from a website; seven were pattern guesses. At a 3–8% reply rate, one batch is zero to one replies — so you run it weekly, you grade before you send, and you never mail a D. The scrape is the easy 10%. Verification is the campaign.
Try it free
The free starter is the email-gate SOP plus three opener prompts — the two pieces above, ready to run on one of your real campaigns tonight: https://nyzza.online/leadgen/?utm_source=devto&utm_medium=social&utm_campaign=leadgen-funnel&utm_content=tucson-34-clinics
The full kit around the scripts — 5 scripts, 4 SOPs, 20 prompts, $27 one-time, 30-day guarantee — is linked from that page. The tool itself needs no purchase to run.
來源:DEV Community · dev.to