A B2B lead list is mostly the part you throw away

This is the writeup of a working prospecting pipeline: scrape US businesses from Google Maps, crawl each one’s own website for an email address, then filter the result down to companies that could actually buy the machine being sold. The interesting number is not the 3,426 rows the scraper returned. It is the 1,017 that survived, and the 546 rejections we keep in a separate file so the filter can be audited rather than trusted.

The pipeline exists to sell two CNC machines into the United States — a benchtop selective soldering robot and a 2.2 kW router — so "a prospect" has a precise meaning here: a business that fabricates something. That precision is what makes the filtering tractable. A generic "get me leads in Dallas" has no answer, because there is no rule that separates a good row from a bad one. "Does this business cut, solder or assemble things with its own hands" has an answer, and Google Maps very nearly gives it to you in the category field.

Roughly 35% of what the scraper returns is not a prospect under that definition, and the failures are systematic rather than random. Search "PCB assembly in Dallas TX" and you get electronics retailers, parts distributors, e-waste recyclers and, reliably, at least one HVAC contractor. None of them assemble a board. A distributor sells the components to somebody who does; a recycler takes the board apart. They are adjacent to the industry and useless as prospects, and no amount of enthusiasm in the outreach copy changes that.

So the pipeline is three scripts and one judgement call. The scraper is gosom/google-maps-scraper, an MIT-licensed Go program driving a headless browser against public Maps URLs; it costs nothing and needs no API key. A Python script merges the raw CSVs, deduplicates on Google’s place_id, validates email addresses, and applies a category allowlist and blocklist. The judgement call is which categories mean "makes things" — and getting that wrong in either direction is the difference between a list you can send to and a list you cannot.

Everything below is the detail: how the scrape is run and why concurrency is capped at two, what the category rules actually contain, and the methodology choices that are easy to get backwards — chief among them the sort order, where the obvious answer is precisely wrong.

Frequently asked questions

How many usable leads come out of a Google Maps scrape?

About two thirds, if you are strict about what counts. Ours returned 3,426 raw rows across six scrapes; after deduplication and category filtering, 1,017 were businesses that fabricate something. 251 of those had a verified email address.

Does this use the official Google Places API?

No, and it could not. The Places API never returns email addresses, which is the most valuable column in the dataset, and the Maps Platform terms forbid storing business names, addresses or phone numbers at all — only place_id may be kept indefinitely.

What does the scrape cost?

Nothing. No API key, no account, no quota. The scraper drives a headless browser against public google.com/maps URLs. The only real cost is time: the website email crawl is by far the slowest stage.

Why is the qualified list not sorted by review count?

Because for B2B that inverts quality. A high review count means consumer-facing. Sorting by reviews put a home-security firm with 5,870 reviews above a real contract manufacturer with eleven. See the methodology page.

Is scraping Google Maps legal?

The data is public business information and the scraper holds no Google account, so there is no contract to breach. The constraint that actually binds is on what you do next: US B2B cold email is lawful under CAN-SPAM, cold WhatsApp to the same numbers is not.