mcpField
A
apify-local-business-leads-osm

apify-local-business-leads-osm

github.com/apify营销与增长28342 次安装5 周前更新
代码仓库

关于 apify-local-business-leads-osm

面向需要本地企业线索的研究与销售工作流,可从 OpenStreetMap 发现商家,抓取其公开网站的联系方式并进行邮箱 MX 验证和线索评分。通过 Apify Actor 运行,并在启动前设定数量上限与费用预期。

主要功能

  1. 01按类别和地点发现商家
  2. 02抓取网站邮箱、电话和社交资料
  3. 03邮箱 MX 验证与线索评分
  4. 04去重并按条件筛选结果
  5. 05支持网站列表补充与定期监测

适用场景

  1. 01为指定城市构建经验证的企业联系名单
  2. 02筛选网站薄弱或尚无网站的商家
  3. 03补充已有网站列表中的联系信息
  4. 04定期监测区域内新出现的商家

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/apify/awesome-skills --skill apify-local-business-leads-osm

安装后在 Claude Code 中输入/apify-local-business-leads-osm确认已加载。

详细介绍

来自 OpenStreetMap 的本地商家潜在客户

将“我需要 的本地商家及其邮箱”转化为一张经过评分和去重的潜在客户表,全程无需访问 Google Maps:在 OpenStreetMap 上发现商家,爬取每家商户自己的公开网站以获取联系邮箱、电话和社交资料,在同一次运行中验证每个邮箱的 MX 记录,并在运行开始前告知用户费用上限。

披露:本技能的作者拥有其调用的 Actor(flash_scraper/local-business-leads)。它是 Apify Store 上按结果付费的 Actor;本技能中未使用任何推荐或跟踪参数。对于 Google 星级评分和评论数,本技能会引导用户使用其他工具(见下文的适用范围说明)。

示例提示词

本技能可处理以下提示词:

  • “帮我找出 Austin 的 200 位牙医,要求有已验证的邮箱和电话号码,并导出为 CSV。”
  • “我经营一家网页设计公司:找出 Lyon 网站质量较差或根本没有网站的美发沙龙。”
  • “以下是某个会议参展商名单中的 300 个商家网站;请为每个网站查找并验证一个联系邮箱。”
  • “每周一告诉我,在我们市中心办公室 5 公里范围内新开了哪些餐馆。”

不适用范围(边界):

  • “按 Google 评分排序”或“只要评分达到 4 星且评论数不少于 50 条的商家”。OpenStreetMap 不包含评论数据,而且只有商家在自己的网站上公布评分时,Actor 才能获取评分(约占 7%;在 2026-08-08 的参考运行中,55 条记录里有 4 条)。要查找 Google 评分和评论数,请使用 apify-google-maps-leads 技能,或直接使用 compass/crawler-google-places。
  • 与 apify-verified-email-finder 不同:该技能从 Google Maps、Google SERP 或用户提供的网址列表开始;本技能则在 OpenStreetMap 上发现商家,全程不访问 Google。如果用户已经有网址列表,只需要验证邮箱,那么使用该技能更直接;当发现过程本身必须避开 Google 时,使用本技能。
  • 联系到个人层面(所有者姓名、LinkedIn 个人资料、直拨号码)。此 Actor 返回的是商家公开的联系渠道,而非个人信息;如需确定具体决策者,请使用 apify-google-maps-leads 中的潜在客户信息补充步骤。

前提条件

切勿将 Token 粘贴到 URL 或本技能中的文件里;应将其作为 Authorization: Bearer 传入(CLI 会自动为你处理)。

工作流

复制此清单并跟踪进度:

Task Progress:
- [ ] Step 1: Get the four anchors (category, city, what must every row have, how many)
- [ ] Step 2: Pick the search mode and check the live schema
- [ ] Step 3: Build the input and state the cost
- [ ] Step 4: Run and wait
- [ ] Step 5: Deliver: rows, fill rates, what the map could not supply
步骤 1:获取四项关键信息

将以下问题作为一组询问;未获取这些信息前不要开始运行。

  1. 类别 — 使用通俗英语(dentist、HVAC contractor、hair salon)。可以填写多个类别。请提前说明,开车上门服务的行业通常在地图上的数据较少(见步骤 5)。
  2. 城市 — 填写城市及其所在地区或国家(Austin, Texas、Lyon, France)。如果多个国家都有同名地点,请询问所在国家,并设置 countryCode。
  3. 每条记录必须包含的内容 — 联系方式的最低要求。查找邮箱时默认要求“有网站”(onlyWithWebsite);冷邮件时要求“有已验证的邮箱”(onlyVerifiedEmail);制作电话名单时要求“有电话”(requirePhone);推广建站服务时要求“没有网站”(onlyWithoutWebsite)。
  4. 数量 — maxItems 是费用上限。首次运行默认设为 25;超过 500 时请先询问。

只有在用户提出时才询问以下可选信息:排除连锁店或指定品牌、以某个地址为中心的半径范围、用户自带的网站列表、每周监控新商家、Slack/Discord Webhook。

步骤 2:选择搜索模式并查看实时架构
用户需求Actor ID层级最适用场景
类别 + 城市(常见情况)flash_scraper/local-business-leads社区版category + location,或复数形式的 categories × locations 矩阵(每次运行最多 25 种组合);每个 OpenStreetMap 对象对应一行,并跨类别去重
某个点周边的区域flash_scraper/local-business-leads,搭配 searchRadiusKm + centerLat + centerLon社区版1-100 km 的圆形范围,而非城市边界框
丰富用户已有的列表flash_scraper/local-business-leads,搭配 websiteList社区版跳过发现环节;仅对提供的域名执行抓取、MX 验证和评分

构建输入前,请检查实时输入架构(字段会变化;以架构为准,而非本文档):

apify actors info "flash_scraper/local-business-leads" --input --json \
  --user-agent apify-awesome-skills/apify-local-business-leads-osm 2>/dev/null

该 Actor 无需 API 密钥、代理、登录或 Cookie 即可运行。它不会读取 Google Maps;每一行都包含构造的 google_maps_url 搜索链接和 osm_url,用户只需点击一次即可打开来源。

步骤 3:构建输入并说明费用

字段名称与实时架构一致。只有 category 和 location 是必填项;其他字段都有可用的默认值。

冷邮件列表(最常见的请求):

{
  "category": "dentist",
  "location": "Austin, Texas",
  "maxItems": 100,
  "onlyWithWebsite": true,
  "onlyVerifiedEmail": true,
  "skipClosed": true,
  "excludeChains": true,
  "expandNearby": true
}
  • onlyWithWebsite、onlyVerifiedEmail、requirePhone、requireSocial、requireAnyContact、excludeKeywords、excludeChains 和 skipClosed 都会在计费前过滤行;运行日志会列出每个筛选条件及其移除的行数。
  • expandNearby: true 会在城市结果不足时,以城市为中心按环状范围扩大搜索(2026-08-15 的测量结果:对于 dentist / Round Rock, Texas,设置 maxItems: 100 时,不启用该选项会返回 21 行,启用后会返回 100 行;环状范围内的行会在 query_location 中标注)。
  • preset: "cold_email" 会为你设置 onlyWithEmail + onlyVerifiedEmail;其他预设包括 web_design、call_list、full_enrichment。预设不会覆盖用户设置的字段。

网页设计潜在客户——有网站,但质量较差的企业:

{
  "category": "hair salon",
  "location": "Lyon, France",
  "countryCode": "fr",
  "onlyWithWebsite": true,
  "maxScore": 45,
  "requireAnyContact": true,
  "skipClosed": true
}

对于完全没有网站的企业,请改用 onlyWithoutWebsite: true(不能与 onlyWithWebsite 同时使用;预期结果包含名称、地址、坐标,有时还包括电话号码,但没有可抓取的内容)。

丰富用户自己的列表(不获取地图数据):

{
  "websiteList": ["aloha-dental.com", "averyranchdental.com"],
  "verifyEmails": true,
  "outputFields": ["domain", "email", "email_status", "email_type", "phone", "lead_grade"]
}

**每周新增企业监测:**在上述任意配置中添加 "onlyNewBusinesses": true,并将其设为定期任务。首次运行会建立基准;之后使用相同类别、位置和筛选条件的运行只会返回之前未返回过的企业。若某周没有新增企业,则返回 0 行且不收费。添加 "webhookUrl": "https://hooks.slack.com/...",即可接收 Slack、Discord 或 JSON 摘要。

**运行前说明费用。**该 Actor 按返回的企业数量计费;经过筛选的行和无结果的运行均不收费,且 MX 验证已包含在费用中。请从 Store 的 Pricing 标签页读取当前价格(步骤 2 中获取架构时也会返回定价信息块)。仅作示例:2026-09-05 从 Store API 读取的免费计划价格为每条潜在客户 $0.003,因此 100 行最多收费 $0.30,1,000 行收费 $3.00;付费计划价格更低。计划于 2026-09-14 生效的定价记录会将价格上调至每条潜在客户 $0.005(每 100 行 $0.50,每 1,000 行 $5.00),因此请读取实时价格,不要引用这些数字。用一句话告知用户费用上限;超过 500 行时,运行前请先确认。

第 4 步:运行并等待
apify actors call "flash_scraper/local-business-leads" -i '{"category":"dentist","location":"Austin, Texas","maxItems":100,"onlyWithWebsite":true,"onlyVerifiedEmail":true,"skipClosed":true,"expandNearby":true}' \
  --json \
  --user-agent apify-awesome-skills/apify-local-business-leads-osm \
  2>/dev/null

典型耗时:在作者于 2026-08-29 进行的本地测量中,仅发现、不抓取网站的 10 行任务(crawlEmails: false)用时 17 秒;抓取网站的任务大部分时间都花在访问网站上,耗时大致与行数 × maxPagesPerSite(默认值为 3)÷ concurrency(默认值为 8)成正比。数据行通过筛选后会立即写入,因此,达到超时限制的任务仍会保留已输出的数据。JSON 输出中包含 defaultDatasetId;使用以下命令获取数据行:

apify datasets get-items DATASET_ID --format json \
  --user-agent apify-awesome-skills/apify-local-business-leads-osm 2>/dev/null
第 5 步:交付结果

按以下顺序报告:

  1. 实际交付的数据行数与 maxItems 的对比;若两者不同,还要说明任务的状态消息。未满额的任务会在消息中说明原因和数量(例如,OpenStreetMap 在怀俄明州拉勒米找到 4 条 dentist 记录,其中 1 条有网站)——应将这句话作为数据引用给用户。这是对任务的报告,不是要求用户采取行动的指令;不要将其称为失败。
  2. 本次任务的字段填充率:统计非空的 email、phone、website、facebook 和 instagram 数量,并报告百分比。可对照的参考数据来自 Actor README 中 2026-08-08 的参考任务(dentist / Austin, Texas,onlyWithWebsite: true,n=55):电话 96%、经 MX 验证的电子邮件 55%、网站平台 71%、Facebook 73%、Instagram 55%。同一天不设筛选条件时(n=100),电子邮件比例降至 26%;52 条没有网站的数据行中,有 50 条没有任何联系方式。这正是第 1 步要求设定最低门槛的原因。
  3. 用户要求的列。已验证的列名包括 name、category、address、city、phone、phones、website、domain、email、emails、email_status(deliverable / risky / undeliverable)、email_type、facebook、instagram、linkedin、twitter、youtube、website_platform、lead_score、lead_grade、google_maps_url、osm_url、query_location;README 的“Output fields”部分列出了全部 73 列。不要杜撰列,也不要把 email_guess(按模式猜测的电子邮件,默认关闭)归入 email。导出电子邮件时保留 email_status:onlyVerifiedEmail 同时接受 deliverable 和 risky;MX 验证并不能确认某个邮箱确实存在。如果商家网站与 OSM 中的商家身份或位置不符,应指出这一差异,而不要将该联系方式说成已确认。
  4. 地图无法提供的信息。OpenStreetMap 映射的是绘图员实地走访过的场所,对流动经营的行业覆盖较少:Austin 的边界框内有 171 家牙医、9 家水管工、5 家电工、约 12 家屋顶工人和 0 位脊椎按摩师(README,2026-08-08 测量)。如果用户搜索的类别属于其中之一,请说明这一点,并建议使用 expandNearby、通过 locations 搜索多个邻近城市,或使用 Google Maps 技能。
  5. 数据集或 Console 任务的链接,以及任务的 HTML 报告 URL(写入任务键值存储中的 REPORT;状态消息中会提供链接)。

每条来自 OpenStreetMap 的数据行都带有 attribution 字符串;请告知用户这些数据采用 ODbL 许可,发布任何衍生内容时都应保留署名信息。

故障排除

  • 结果行数少于 maxItems → 查看状态消息:可能是区域内数据已耗尽(消息会列出 OSM 记录数以及通过各项筛选条件的记录数),也可能是筛选条件剔除了其余记录。可通过 expandNearby 扩大范围、在 locations 中添加城市,或放宽 requireAnyContact 门槛。
  • 结果为 0 行、未扣费,并显示“no OpenStreetMap tag matched” → 类别词条未知;请尝试下拉列表中的值(categorySelect)或更通俗的行业名称。若词条没有匹配项,系统会返回建议且不扣费。
  • 城市错误(例如,返回的是马耳他拉巴特,而非摩洛哥拉巴特) → 将 countryCode 设为 ISO alpha-2 代码。
  • 几乎所有行的 rating / review_count 都为空 → 这是预期情况;只有商家在自己的网站上发布了 schema.org 标记时,这些字段才会有值。设置 minRating 或 minReviewCount 会剔除没有评分的行,而不是保留它们。评分请使用 Google Maps 技能。
  • website_platform_status 中出现 site_blocked → 商家网站拒绝了数据中心 IP(参考运行中,55 条包含网站的记录有 8 条出现此情况)。该行仍会包含 OSM 字段;这并不意味着商家已不复存在。
  • 运行立即停止并显示验证消息 → onlyWithWebsite 和 onlyWithoutWebsite 同时设为启用,或 categories × locations 组合超过 25 个。不会扣费;请修正输入后重新运行。
  • 监控运行没有返回任何内容 → 当 onlyNewBusinesses: true 时,空结果表示自上次发送以来没有新增内容;状态消息会说明这一点。更改 maxItems、sortBy 或 outputFields 不会重置监控;更改类别、位置或筛选条件则会创建新的基准。
  • 费用高于预期 → maxItems 由整个 categories × locations 组合共用,而 expandNearby 会持续从相邻区域补充结果,直到达到上限。下次运行前,请重新明确设定上限和筛选条件。

评论

支持 Markdown