跳到正文
DEV Community· Gio Rich·· 3 小時前AI 評分39

如何用 Python 根據 YellowPages.ca 資料尋找需要市場推廣支援的加拿大商戶

Finding Canadian businesses that need marketing help, using YellowPages.ca data in Python

AI 導讀

YellowPages.ca Scraper 可把 YellowPages.ca 搜尋結果整理成每間商戶一列的 JSON 資料,協助加拿大小型網頁、SEO 或廣告代理商尋找潛在客戶。商戶的付費廣告位置、廣告級別、評分、社交連結及營業時間等資料,可用來整理兩類推銷名單:已有付費廣告的商戶,以及免費刊登但網上資訊不足的商戶。工具收費為每 1,000 間商戶 $0.50。

正文

I built this actor; it's a paid tool on Apify with a free trial credit.

If you run a small web, SEO or ads agency in Canada, the hard part of prospecting is not finding businesses, it's finding the right ones. YellowPages.ca quietly tells you a lot about that: which listings are paid placements, which advertising tier each business is on, whether it has reviews, social profiles or published hours.

I built YellowPages.ca Scraper to turn a search like "electrician in Toronto ON" into one JSON row per business, over plain HTTP with no browser. This post shows how to call it from Python and Node, what the ad-signal fields mean, and a small script that splits a city's businesses into two pitch lists.

Calling it from Python

from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")

run = client.actor("rel8ble/yellowpages-ca-scraper").call(run_input={
    "searchTerms": ["electrician", "roofing"],
    "locations": ["Toronto ON", "Ottawa ON"],
    "maxResultsPerSearch": 100,
    "scrapeDetails": True,   # hours, coordinates, social links, languages
})

rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())
print(len(rows), "businesses")

Terms can be English or French (avocat, plombier work), and locations are City PROVINCE. Every term runs in every location, and each row keeps searchKeyword, searchLocation, position and totalInSearch so you know where it came from.

The same from Node, starting from a search URL instead:

import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('rel8ble/yellowpages-ca-scraper').call({
    startUrls: ['https://www.yellowpages.ca/search/si/1/dentist/Vancouver+BC'],
    maxResultsPerSearch: 50,
    requireWebsite: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((b) => `${b.name} | ${b.phone} | ${b.website}`).join('\n'));

What a row looks like

A real row from an "electrician / Toronto ON" run on 27 Oct 2026, trimmed:

{
    "name": "Expert GTA Electric",
    "category": "Electricians & Electrical Contractors",
    "phone": "647-846-8903",
    "website": "https://expertgta.com/",
    "city": "East York",
    "province": "ON",
    "rating": 5,
    "reviewCount": 11,
    "openingHours": ["Monday 00:00-23:59", "Tuesday 00:00-23:59"],
    "socialLinks": [
        "https://www.facebook.com/ExpertGTAElectric/services/",
        "https://twitter.com/ExpGTAElectric",
        "https://www.instagram.com/expertgtaelectric/"
    ],
    "sponsored": true,
    "listingTier": "GSP",
    "searchKeyword": "electrician",
    "searchLocation": "Toronto ON",
    "totalInSearch": 1634
}

Two fields matter most for prospecting:

  • sponsored is true when the business bought one of the paid slots at the top of the results.
  • listingTier is YellowPages' own advertising tier for the listing (values like GSP, SP, L0-L2, LEGACY, NONE). Paid tiers mean the business already spends money on marketing; LEGACY / NONE means a basic or free listing.

In that 20-business Toronto sample, 10 were sponsored, 17 of 20 had no rating at all, 10 had no social links, 3 had no published hours and 2 had no website. That's the shape of most local trades: plenty of businesses, very little online reputation.

Project: two pitch lists from one run

The idea: a business that already pays for ads is a good prospect for "better results for the money you're spending". A business on a free listing with no reviews and no socials is a prospect for "you're invisible, here's the basics".

PAID_TIERS = {"GSP", "SP", "L0", "L1", "L2"}

def gaps(b):
    out = []
    if not b.get("website"):
        out.append("no website")
    if not b.get("reviewCount"):
        out.append("no reviews")
    if not b.get("socialLinks"):
        out.append("no social")
    if not b.get("openingHours"):
        out.append("no hours")
    return out

spenders = [b for b in rows if b.get("listingTier") in PAID_TIERS]
invisible = [b for b in rows
             if b.get("listingTier") not in PAID_TIERS and len(gaps(b)) >= 2]

print("Already paying for visibility (pitch: better ROI):")
for b in spenders:
    print(f"  {b['name'][:38]:38} {b['listingTier']:4} {b['phone']:14} {', '.join(gaps(b)) or 'solid profile'}")

print("\nFree listing, weak presence (pitch: get found):")
for b in sorted(invisible, key=lambda b: -len(gaps(b))):
    print(f"  {b['name'][:38]:38} {b['phone']:14} {', '.join(gaps(b))}")

On the Toronto electrician sample this gives 10 "spenders" (most with zero reviews despite paying for a top slot, which is a strong opener) and a short list of free-listing businesses missing two or more basics.

Because rows carry coordinates (17 of the 20 here) and serviceAreas, you can also drop both lists onto a map and plan calls by neighbourhood.

Getting emails

YellowPages.ca does not publish email addresses at all, so no scraper of it will give you emails. The practical route is to pass the website column to a site crawler such as my Website Contact Extractor, which reads each company's own site for emails and social profiles.

Pricing and limits

$0.50 per 1,000 businesses, no start fee, same price with or without business pages. Businesses dropped by your filters, duplicate sponsored placements (YellowPages repeats them on every page) and failed requests are not charged. It covers Canada only, up to 100 result pages per term and location (about 2,500 businesses), so split big cities by neighbourhood or postal code. YellowPages widens thin searches to nearby cities, so check the city column. Canada's anti-spam law (CASL) restricts commercial email, so check your outreach rules before you send anything.

Store page: https://apify.com/rel8ble/yellowpages-ca-scraper

Need a custom scraper or a ready dataset? Hire me on Fiverr: https://www.fiverr.com/rel8ble

This article was drafted with AI and published by me.

來源:DEV Community · dev.to