关于 apify-lead-scoring-enrichment
此工作流技能将包含公司网址的 CSV 转换为评分并补充联系人信息的潜在客户列表。它结合公司技术栈、网站内容和元数据等可配置信号,并在补充联系人前按门槛筛选。
主要功能
- 01CSV 导入与校验
- 02技术栈、内容和元数据评分
- 03用户自定义评分规则
- 04按资格门槛筛选
- 05补充部门联系人或作者信息
- 06合并生成增强版 CSV
适用场景
- 01按自定义匹配规则排列公司线索优先级
- 02为符合条件的公司查找部门联系人
- 03根据博客作者构建客座文章联系名单
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ apify/ awesome-skills --skill apify-lead-scoring-enrichment安装后在 Claude Code 中输入/apify-lead-scoring-enrichment确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.gitignoreexamples/leads.example.csvscoring-rules.example.mdreferences/actor-index.mdgotchas.mdscripts/apify_client.jsenrich_copywriters.jsenrich_departments.jsfilter_qualified.jsmerge_output.jspackage.jsonrun_scoring.js详细介绍
潜在客户评分与信息补全
将公司网址 CSV 转换为带评分且补全联系人信息的推介名单。Agent 会用通俗易懂的语言询问用户评分规则(“如果使用 Shopify,则 +10 分”,“如果公司规模 <10,则 -5 分”),选择信息补全路径(部门或文案撰写人员),并通过四个辅助脚本编排六个 Apify Actor。
前提条件
- 拥有有效
APIFY_TOKEN的 Apify 账户(控制台 → 设置 → 集成) - Node.js 20.6+(需要原生
--env-file支持) - 技能根目录下有一个
.env文件,其中包含APIFY_TOKEN=apify_api_... - 在
scripts/中一次性运行:npm install(安装csv-parse、csv-stringify)
可选但推荐:Apify CLI(npm i -g apify-cli),用于临时调用 Actor。辅助脚本直接调用 REST API,不需要 CLI。
工作流
复制此清单并跟踪进度:
Task Progress:
- [ ] Step 1: Collect CSV path and validate required column (company_url)
- [ ] Step 2: Collect scoring rules per source (tech / content / metadata)
- [ ] Step 3: Collect enrichment path (departments OR copywriters)
- [ ] Step 4: Run scoring Actors (writes scoring.json)
- [ ] Step 5: Apply scoring rules per lead → assign per-source scores + outreach_hook (writes scored.json)
- [ ] Step 5b: Compute theoretical min/max score, ask user for qualification threshold, filter leads → qualified_leads.csv
- [ ] Step 6: Run enrichment path against qualified_leads.csv (writes enrichment.json)
- [ ] Step 7: Merge scoring + enrichment onto the ORIGINAL CSV → leads.enriched.csv (qualified column marks who made the cut)
第 1 步:CSV 输入
询问用户 CSV 文件路径。必需列:company_url。可识别的可选列会原样传递:company_name、first_name、last_name、role、department。如果缺少 company_url,则拒绝运行。将网址裁剪为纯域名(去掉尾部斜杠,www. 可选),再传给需要域名的下游 Actor。
第 2 步:评分规则(按来源)
每个来源只问一个问题,让用户(以及你在第 5 步)清楚每条规则针对哪些数据。只询问用户希望获取的来源——每个来源在第 4 步都有对应的 --enable-* 标志。
2a. 技术栈规则——针对 scoring.json[url].tech(BuiltWith 输出)应用。仅当用户希望启用 --enable-tech 时才询问。可展示以下规则示例:
- 如果公司使用 Shopify 或 WooCommerce(我们销售 Shopify 集成),则 +10 分。
- 如果技术栈包含 HubSpot、Marketo 或 Segment(营销运营 ICP),则 +5 分。
- 如果未检测到分析工具或 CDP(可能还处于早期阶段),则 -3 分。
2b. 网站内容规则——针对 scoring.json[url].content(Website Content Crawler 的 Markdown/文本)应用。仅当用户希望启用 --enable-content 时才询问。还要在此处询问 maxCrawlDepth(默认值 0 = 仅抓取首页;更高的值 = 成本更高)。规则示例:
- 如果首页介绍的是 SaaS 或平台型业务,则 +8 分。
- 如果首页介绍的是服务型代理机构(不符合我们的 ICP),则 -5 分。
- 如果首页提到“developers”或“API”(技术买家),则 +3 分。
2c. 公司元数据规则——针对 scoring.json[url].metadata(Contact Info Scraper 元数据)应用。仅当用户希望启用 --enable-metadata 时才询问。规则示例:
- 如果行业属于电子商务、零售或 B2C,则 +3 分。
- 如果公司员工人数少于 10 人(规模太小,无法购买),则 -3 分。
- 如果公司在 LinkedIn 上有主页(运营规模较大),则 +5 分。
逐字保存每组规则,并标注其来源。如果用户把元数据规则归入技术栈规则组(例如在技术栈规则下写“如果规模 >50,则 +3 分”),则在第 5 步之前将其移到正确的规则组,并说明原因。
如果用户没有针对某个来源提供规则,也应从第 4 步的 --enable-* 标志中移除该来源——为不会用于评分的信号付费毫无意义。完整的规则集示例:examples/scoring-rules.example.md。
步骤 3:丰富路径(任选其一)
询问:“选择哪种丰富路径?
- (A) 部门联系人——在每家公司指定的团队中查找具名联系人(包括职位和电子邮件)。使用 Contact Info Scraper 的“Business leads enrichment”附加功能;对于未能发现电子邮件的潜在客户,则改用 Bulk Email Finder。
- (B) 文案作者搜寻——针对每个域名,在 Google 中搜索
site:{domain} blog,从热门文章中提取作者姓名,再查找他们的电子邮件。适合用于客座文章拓展。”
对于路径 A,再收集两项输入:
- 部门——从此枚举中选择一个或多个(以逗号分隔):
c_suite、product、engineering_technical、design、education、finance、human_resources、information_technology、legal、marketing、medical_health、operations、sales、consulting。 示例:marketing,sales。 - 每个域名的潜在客户数量上限——整数。对于典型的 SDR 工作,建议填写 3–5。
⚠️ 这是一个成本乘数:5 个潜在客户 × 500 个域名 = 最多 2500
个计费潜在客户。Apify 只会对成功找到的潜在客户收费。如果
max_leads × domain_count > 500,运行前请提醒用户。
对于路径 B,无需额外输入。
步骤 4:运行评分 Actor
node --env-file=.env scripts/run_scoring.js \
--input leads.csv \
--output scoring.json \
--enable-tech --enable-content --enable-metadata \
--content-crawl-depth 0
run_scoring.js 会针对每个已启用的 Actor,将所有 URL 批量合并为一次调用(而不是每个潜在客户调用一次),然后将数据集重塑为按 URL 划分的附属数据,以便 Agent 能通过 company_url 查找每个信号。未通过 --enable-* 启用的 Actor 会被跳过。读取生成的 scoring.json——其结构为 { "https://acme.com": { "tech": {...}, "content": {...}, "metadata": {...} }, ... }。
步骤 5:应用评分规则(按来源分别评分,再求和)
对于 scoring.json 中的每个潜在客户,使用步骤 2 中仅对应其来源的规则,分别对每个来源评分一次。这样可以让评分可审计——如果某个潜在客户的 content_score = -5,但用户原本预期其会转化,你就能准确检查触发了哪条内容规则,而不必重新推导整个计算过程。
为每个潜在客户生成五个字段:
tech_score(数字;如果未启用--enable-tech,则为null)——根据scoring.json[url].tech累加步骤 2a 规则的分值变化。content_score(数字;如果未启用--enable-content,则为null)——根据scoring.json[url].content累加步骤 2b 规则的分值变化。metadata_score(数字;如果未启用--enable-metadata,则为null)——根据scoring.json[url].metadata累加步骤 2c 规则的分值变化。score(数字)——以上三项之和,将null视为0。outreach_hook(字符串,单句)——从所有来源中选出最适合个性化联系的信号:具体的 CMS(“使用 Shopify”)、具名分析工具、行业匹配、文案中的招聘信号等——任何人类销售代表会在邮件开头提及的内容。
null 和 0 的区别很重要:未获取的来源不得与已获取但评分为零的来源混为一谈。下游 CSV 列会将 null 显示为空白,将 0 显示为 "0"。
将评分后的行存储为中间文件 scored.json(由 Agent 直接写入,以规范化的 https://domain 为键),然后在步骤 5b 将其传递给 filter_qualified.js,并在步骤 7 将其传递给 merge_output.js。
Step 5b:资格阈值门控
数据补充是成本高昂的环节——对不符合条件的潜在客户运行补充流程,会白白消耗额度,无法带来投资回报。调用任何数据补充 Actor 之前,先用用户设定的阈值进行筛选。
-
根据用户在 Step 2 中给出的规则,计算理论分数范围。 对每个来源的规则集,将所有正向增量相加,得到
max_source;将所有负向增量相加,得到min_source。然后,min_total = min_tech + min_content + min_metadata,max_total也按同样方式计算。这是一个硬性边界:没有潜在客户的得分会超出此范围。 -
还要根据
scored.json计算实际范围——即所有潜在客户score值的实际最小值和最大值。实际范围通常远窄于理论范围。 -
向用户同时展示这两个范围,并提供粗略的分层建议:
“理论范围:{min_total} 至 {max_total}。你的列表中的实际范围:{observed_min} 至 {observed_max},共 {n_leads} 条潜在客户。分布:达到第 75 百分位数 / 第 50 百分位数 / 第 25 百分位数阈值的数量分别为 {count above 75th percentile} / {count above 50th percentile} / {count above 25th percentile}。你想设定什么阈值?得分达到或超过阈值的潜在客户将进入数据补充流程;低于阈值的所有条目都会在最终 CSV 中标记为
qualified=false,并跳过补充流程。”如果用户不确定,建议从第 75 百分位数的得分开始——数据补充成本可降低约 75%,同时保留漏斗顶部的潜在客户。如果用户选择的阈值会导致 0 条潜在客户符合条件,或导致全部潜在客户都符合条件(没有筛选),请发出警告。
-
根据所选阈值,在
scored.json的每一行标记qualified: true|false(写回文件),然后运行:node scripts/filter_qualified.js \ --leads leads.csv \ --scores scored.json \ --output qualified_leads.csvfilter_qualified.js是一个纯 Node.js CSV 筛选器——它读取scored.json,仅保留qualified === true的行,并将其写入qualified_leads.csv,保留所有原始列。完整的潜在客户列表(包括不符合条件的条目)仍保存在原始的leads.csv中——Step 7 的合并操作会以此作为连接基准。
Step 6:运行数据补充流程(仅处理符合条件的潜在客户)
将 Step 5b 生成的 qualified_leads.csv 输入数据补充脚本,而不是原始的 leads.csv。这正是阈值门控发挥作用的地方。
路径 A — 部门联系人:
node --env-file=.env scripts/enrich_departments.js \
--input qualified_leads.csv \
--department marketing,sales \
--max-leads 5 \
--output enrichment.json
添加 --verify-emails,还可验证每个返回的邮箱(每个已验证/无效/一次性邮箱结果会产生少量额外费用;根据 Actor 文档,全部兜底和未知结果均免费)。
路径 B — 文案撰写者搜索:
node --env-file=.env scripts/enrich_copywriters.js \
--input qualified_leads.csv \
--output enrichment.json
路径 A 会调用 vdrmota/contact-info-scraper,并启用 Business leads enrichment 附加功能(maximumLeadsEnrichmentRecords + leadsEnrichmentDepartments),让 Actor 返回各域名下的真实联系人——姓名、职位、工作邮箱和 LinkedIn。对于返回结果中没有已解析邮箱的潜在客户,脚本会将 (firstName, lastName, domain) 三元组传给 scalelist/email-finder 作为后备方案。路径 B 则串联运行 apify/google-search-scraper → apify/ai-web-scraper(使用 get-author-name-from-blog-post 示例输入)→ scalelist/email-finder。
步骤 7:合并
node scripts/merge_output.js \
--leads leads.csv \
--scoring scoring.json \
--enrichment enrichment.json \
--scores scored.json \
--output leads.enriched.csv
请注意,--leads 指的是原始 leads.csv,而不是
qualified_leads.csv。这样,所有输入线索都会出现在最终
CSV 中——未通过筛选的线索只会有空白的丰富信息列,并且
qualified=false。这样可以保留审计记录:你可以查看哪些
线索的评分低于阈值,以及原因。
merge_output.js 是纯 Node 脚本(不会调用 Actor)。它按
company_url 执行左连接,并生成 leads.enriched.csv,其中包含原始列,以及:
tech_summary、content_summary、company_size、industry、
tech_score、content_score、metadata_score、score(总和)、
qualified(true / false——与步骤 5b 的阈值相符)、outreach_hook、
leads(通过路径 A 找到的各域名人员的完整 JSON)、
lead_names 和 lead_titles(以分号分隔的摘要,便于阅读 CSV)、
emails(以分号分隔),以及 authors(路径 B)。
Actor 路由
| 用户意图 | Actor | 层级 | 备注 |
|---|---|---|---|
| 检测技术栈 | builtwith/builtwith-official-technology-scraper | 社区 | 输入:{ "startDomains": ["acme.com", ...] }(裸域名,不含协议)。CMS、分析工具和托管服务有助于生成外联切入点。 |
| 网站内容分类 | apify/website-content-crawler | apify | 将 maxCrawlDepth: 0 设为仅抓取首页;值越高,费用越高。 |
| 公司元数据(评分路径) | vdrmota/contact-info-scraper | 社区 | 附加组件设为 OFF。从 About/Contact 页面返回电子邮件、电话、社交账号及公司元数据。 |
| 部门专属线索(路径 A 丰富信息) | vdrmota/contact-info-scraper | 社区 | 通过 maximumLeadsEnrichmentRecords 和 leadsEnrichmentDepartments(枚举)将附加组件设为 ON。返回实际人员的信息:姓名、职位、工作电子邮件、LinkedIn。 |
| 发现博客 | apify/google-search-scraper | apify | 查询 site:{domain} blog,并设置 resultsPerPage: 5。 |
| 提取博客作者 | apify/ai-web-scraper | apify | 使用示例 get-author-name-from-blog-post。 |
| 电子邮件查找备用方案 | scalelist/email-finder | 社区 | 输入:{ "leads": [{ "first_name", "last_name", "company_domain" }] }。仅对有姓名但没有电子邮件的线索调用。 |
完整的输入架构和注意事项:references/actor-index.md。
调用 Actor——CLI 用法
每次 apify CLI 调用都必须包含三个标志(由 CI 强制检查):
apify actors call ACTOR_ID \
-i 'JSON_INPUT' \
--user-agent apify-awesome-skills/apify-lead-scoring-enrichment \
--json 2>/dev/null
apify actors info ACTOR_ID --input \
--user-agent apify-awesome-skills/apify-lead-scoring-enrichment \
--json 2>/dev/null
apify datasets get-items DATASET_ID \
--user-agent apify-awesome-skills/apify-lead-scoring-enrichment \
--format json 2>/dev/null
辅助脚本直接使用 REST API,并在每个请求中设置相同的
apify-awesome-skills/apify-lead-scoring-enrichment user-agent 标头,因此,无论使用 CLI 还是脚本,都能保持一致的来源归属。
替代接口
- Apify MCP connector — https://mcp.apify.com(文档)。跳过辅助脚本;由 Agent 将 Actor 作为 MCP 工具调用。
- mcpc — 独立的 MCP 客户端,https://github.com/apify/mcpc。
即使跳过辅助脚本,你仍需自行应用步骤 5 的评分逻辑并生成最终 CSV。
故障排查
APIFY_TOKEN not set— 脚本通过node --env-file=.env从.env读取该变量。确保.env位于你执行cd进入的目录中,而不是 skill 目录中。使用绝对路径会更方便:node --env-file=/abs/path/.env scripts/...。- Node <20.6 时出现
fetch failed—--env-file需要 Node 20.6 或更高版本。检查node --version。升级 Node,或在 shell 中手动导出APIFY_TOKEN。 - BuiltWith 对某个 URL 返回空结果 — 该域名无法访问、被 WAF 拦截,或是新域名(没有历史检测记录)。输入裸域名(
acme.com),不要输入完整 URL,并且只重试失败的行。 - Contact Info Scraper 对某个域名返回 0 条潜在客户信息 — 该域名被 Actor 内置的排除列表过滤(大型连锁企业、社交平台、零售巨头、外卖服务),或者该网站在所请求的部门中没有可发现的员工。尝试选择更宽泛的部门(例如在
marketing之外再添加c_suite),或者针对该细分领域改用文案撰写路径。 - 潜在客户有姓名但没有电子邮件地址 — Business-Leads 附加组件无法找到对应地址。路径 A 会自动回退到
scalelist/email-finder,并使用(firstName, lastName, domain)进行查询。如果回退查询也没有结果,则该人员的电子邮件地址确实不在 Scalelist 的索引中 — 可尝试手动使用 LinkedIn Sales Navigator,或删除该行。 - Copywriter 路径对某个域名返回 0 位作者 — 该域名没有博客,或者博客文章没有显示作者署名。跳过该行;客座文章推广不适合该域名。
- 运行过程中 Apify 积分用尽 —
run_scoring.jsv1 不支持部分恢复。请使用较小的 CSV 切片重新运行。有关每个 Actor 的费用估算,请参阅 references/gotchas.md。