关于 apify-link-prospecting-outreach
用于 SEO 外链推广的营销技能,可从搜索结果中筛选潜在合作网站,并生成分层名单、切入理由和邮件草稿。适合需要推广指定页面的营销团队;结合 Ahrefs 指标评估潜在对象。
主要功能
- 01按关键词发现搜索结果潜客
- 02使用 Ahrefs 指标评分并分层
- 03筛除不合适或已联系域名
- 04为潜客匹配切入理由和邮件
- 05生成可复制的链接 размещ置内容
适用场景
- 01为品牌提及未加链接的页面拟定联系名单
- 02寻找替换竞争对手链接的机会
- 03为指定页面规划主题相关外链
- 04按域名筛选并整理外联邮件
MCP 相关
技能通过 Ahrefs MCP 工具获取潜客评分所需的指标。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ apify/ awesome-skills --skill apify-link-prospecting-outreach安装后在 Claude Code 中输入/apify-link-prospecting-outreach确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
campaign.json.exampleexamples/example-email-abc.mdexample-email-resource-page.mdexample-input.mdreference/apify-actor-usage.mdemail-templates.mdoutput-formats.mdtroubleshooting.mdscripts/build_prospects.pyenrich_prospects.pyfetch_run_artifacts.jsfetch_subactors_from_log.jsmerge_subagent_outputs.pypackage.jsonrun_actor.jswrite_xlsx.py详细介绍
链接开发外联
将目标 + 目标关键词 + 用户想推广的网址,转化为分级且可直接发送的外联名单:在 SERP 中排名的潜在对象及其 Ahrefs 评分的权威度、针对每个潜在对象的最佳推介角度、与外联类型匹配的邮件草稿,以及可直接复制粘贴的链接植入内容。
前提条件
(无需预先检查)
.env文件中包含APIFY_TOKEN- 可使用 Ahrefs MCP(此技能会调用
mcp__claude_ai_Ahrefs__*工具为潜在对象评分) - Node.js 20.6+(支持原生
--env-file) - 在技能的
scripts/文件夹中进行一次性设置:npm install
辅助脚本(一个配置,四个步骤)
收集完步骤 1–2 的输入后,将其写入单个 campaign.json(架构见 campaign.json.example)。之后的每个脚本都会读取 --config campaign.json,因此 Agent 无需为每个营销活动创建单独副本。执行顺序:
# 1. Run the Actor (writes {base}.json + sub-Actor sidecars when --fetch-sub-datasets)
node --env-file=.env scripts/run_actor.js --actor "apify/link-prospecting-tool" --input '<json>' --timeout 1800 --fetch-sub-datasets --output {base}.json --format json
# 2. Build unified prospect table from the sidecars
python3 scripts/build_prospects.py --config campaign.json
# 3. (After Step 5 Ahrefs MCP calls → save to {base}_ahrefs_domain.json + {base}_ahrefs_page.json)
python3 scripts/enrich_prospects.py --config campaign.json
# 4. (After Step 8 sub-agents write outputs to /tmp/placement_outputs/row_*.json)
python3 scripts/merge_subagent_outputs.py --config campaign.json --outputs-dir /tmp/placement_outputs
# 5. Write the final xlsx + metadata sidecar
python3 scripts/write_xlsx.py --config campaign.json
如果运行器的客户端等待时间已到,但 Actor 仍在 Apify 上运行,请使用 scripts/fetch_run_artifacts.js --run-id <id> --output {base}.json,而不是重新启动。如果父级运行缺少 SUB_ACTOR_RESULTS(2026-05-20 之后的 Actor 架构),scripts/fetch_subactors_from_log.js 会从父级日志中解析子 Actor 的 runId。
工作流
复制此清单并跟踪进度:
Task Progress:
- [ ] Step 1: Collect required anchor inputs incl. goal (block on these)
- [ ] Step 2: Collect brand voice, partnership type, output format
- [ ] Step 3: Run apify/link-prospecting-tool
- [ ] Step 4: Pull leads, mentions, authors, and sub-Actor datasets
- [ ] Step 5: Enrich every domain with Ahrefs metrics, assign Prospect Tier
- [ ] Step 6: Run skip pass — flag rows to drop before drafting
- [ ] Step 7: Compute "Why This Prospect" tag per surviving row
- [ ] Step 8: Compose per-row 3-artifact placement + outreach-type-aware email
- [ ] Step 9: Render output in chosen format
步骤 1:必需的锚文本输入(首先询问,先于其他所有内容)
在每项必需输入都得到回答前,不要继续步骤 2。首次交互时就提出这些问题。去重输入(#7)为可选项,但仍必须明确询问。
-
本次营销活动的具体目标 — 选择一个预设,或提供自定义文本。目标决定跳过筛选、外联类型模板选择以及潜在对象等级阈值。必填。
预设 下游影响 Recover unlinked brand mentions跳过筛选会删除所有 brand_mentioned_in_source为false的行。默认外联类型 =unlinked-mention-claim。Replace competitor links跳过筛选会删除所有未标记为 Links to competitor的行。默认外联类型 =competitor-link-replacement。Topical authority links to specific URL不筛选。等级阈值收紧(A 级 DR ≥ 50)。默认外联类型按行从 Why This Prospect中选择。Maximum link volume from any relevant site不筛选。等级阈值放宽(A 级 DR ≥ 30)。默认外联类型按行选择。 Custom用户提供的段落;会影响邮件语气和等级权重。不进行自动跳过筛选。 -
目标关键词 — 用户希望其链接出现在相邻位置的一个或多个关键词。该技能会针对每个关键词检索 SERP。至少需要一个。
-
品牌名称 — 用户的品牌或产品名称。没有此项,Actor 将无法运行(它是
brand输入字段)。 -
产品/类别描述 — 用一到两个句子描述用户销售的产品、目标客户,以及产品所属类别。示例:“Apify — 可作为 API 运行无服务器爬虫的网页抓取平台。我们的客户是需要抓取数据、但不想管理基础设施的开发者和数据团队。” 必填。在步骤 6(主题契合度门槛)和步骤 7(对抗性提及检测)中使用,以识别与用户属于同一产品类别的潜在合作对象——无论推介内容如何,这些对象都不会添加链接。如果没有此项,该技能就无法区分真正的编辑合作机会和竞争对手的博客。
-
要添加链接的内容 URL — 将插入合作伙伴文章中的目标 URL。必填。
-
竞争对手 — 用户产品类别中可能会在自己的网站上发布“我们 vs 他们”对比页面的任何公司。请明确这样提出问题:“列出所有会撰写‘X vs YourBrand’对比页面的公司。无论如何,这些公司都不会为你添加链接——小型竞争对手也算。” 鼓励用户列出 10 家以上;大多数用户通常只列出 3–5 家显而易见的公司,因此会漏掉长尾竞争对手。映射到 Actor 中的
competitorDomains,并在步骤 6(跳过对抗性提及)和步骤 7(Links to competitor原因标签)中重复使用。用户回答后,询问是否要从 Ahrefs 自动提取自然搜索竞争对手(不要强行推荐):“要我从 Ahrefs 提取你排名最高的自然搜索竞争对手并添加到此列表中吗?这会增加约 50 个 API 单位的用量,并找出你可能遗漏的小型竞争对手。” 如果用户同意且 Ahrefs MCP 可用,则对用户的域名(从输入 #5 中提取)调用
mcp__claude_ai_Ahrefs__site-explorer-organic-competitors,并将结果合并到competitorDomains。如果 Ahrefs 不可用或用户拒绝,则仅使用用户提供的列表继续。 -
已推介过的域名(可选) — 用户在以往活动中联系过的域名。接受逗号分隔的列表、CSV/Sheet 路径,或“无”。该技能会在跳过阶段过滤这些域名,避免用户重复推介。非必填。
-
每个关键词的自然搜索结果数量 — 针对每个关键词检索多少条 Google 自然搜索 SERP 结果。若用户不确定,默认值为 10,但要提出此问题,让用户知道可以调整此项。映射到
organicResult。 -
要跟踪的大模型来源 — 多选。每个启用的引擎都会查询一个额外的 AI 搜索/聊天界面,并增加每条抓取结果对应的 Google Search Scraper 子 Actor 费用。默认值:全部启用。映射到 Actor 输入标志:
选项 Actor 标志 费用影响 ChatGPT Search enableChatGpt按结果计收 Google Search Scraper 费用 Gemini enableGemini按结果计收 Google Search Scraper 费用 Copilot(Microsoft / Bing) enableCopilot按结果计收 Google Search Scraper 费用 Perplexity enablePerplexity按结果计收 Google Search Scraper 费用 Google AI Mode enableAiMode按结果计收 Google Search Scraper 费用 Google AI Overviews enableAiOverviews免费 — 从已抓取的 SERP 中解析。无论预算如何,都应保持启用。 向用户展示多选项,默认勾选全部六项。禁用单个引擎是除放弃 organicResult之外主要的节省成本手段——建议至少保留 ChatGPT + Gemini(它们在 2026 年占据了由大模型驱动的发现流量中的最大份额)。 -
运行邮箱验证?——布尔值。默认值:
yes。映射到 Actor 上的enableEmailVerification。启用后,Actor 会验证 Contact Details Scraper 子 Actor 返回的每个邮箱,并为每条潜在客户记录添加验证状态标签(verified/catch-all/risky/invalid/unknown)。该技能会在步骤 6 中使用此状态(无效邮箱会自动跳过),并在输出中将其显示为Email Verification列。仅在用户的验证配额受到速率限制,或运行成本紧张的冒烟测试时才禁用。
完成 1–6 和 8–10 项的收集后(第 7 项可选),继续下一步。
步骤 2:次要输入项
接下来询问:
-
品牌信息和语气——简短介绍产品/品牌,并说明外联沟通的语气(例如“轻松友好”“正式的 B2B 风格”“创始人主导”)。每封生成的邮件都会原样使用这些信息。
-
合作类型——用户愿意提供的方案。决定每行邮件中替换的方案段落。外联类型模板会在步骤 8 中单独按行选择。
选项 提供内容 ABC 链接互换 三方链接互换:合作方链接到用户,用户链接到第三方,第三方链接到合作方。 直接 A B 链接互换 双方链接互换:合作方链接到用户,用户链接到合作方。 纳入资源页面 / 列表 请求将用户添加到现有的精选列表或汇总中。不提供互惠链接。 单方面请求(不提供互惠) 用户请求获得链接,但不提供任何回报——适用于未链接提及认领和失效链接替换。 其他 用户自行输入方案(付费展示、免费产品、联合创作内容等)。 -
输出格式:
格式 行为 xlsxrun_actor.js将带样式的电子表格写入磁盘。markdownAgent 在聊天中直接呈现表格,并在每行下方附上邮件草稿。
步骤 3:运行 Actor
Actor ID 为 apify/link-prospecting-tool。完整的输入架构位于 reference/apify-actor-usage.md。
此技能推荐的调用载荷(默认设置适用于优先拓展客户的工作流):
{
"queries": "<keyword 1>\n<keyword 2>",
"brand": "<user's brand name>",
"ownDomains": ["<user-domain.com>"],
"competitorDomains": [],
"ignoreDomains": [
"wikipedia.org", "github.com", "stackoverflow.com", "stackexchange.com",
"reddit.com", "quora.com", "youtube.com", "twitter.com", "x.com",
"linkedin.com", "facebook.com", "medium.com", "archive.org",
"chromewebstore.google.com", "addons.mozilla.org", "apps.apple.com",
"play.google.com", "microsoftedge.microsoft.com", "marketplace.visualstudio.com"
],
"organicResult": 10,
"maxContactsPerDomain": 3,
"department": ["marketing"],
"searchAuthorName": true,
"includeMention": true,
"enableChatGpt": true,
"enableGemini": true,
"enableCopilot": true,
"enablePerplexity": true,
"enableAiMode": true,
"enableAiOverviews": true,
"enableEmailVerification": true
}
六个 enable* LLM 来源标志与用户在步骤 1 输入项 #9 中的多选项一一对应。对于用户取消选择的引擎,传入 false。enableEmailVerification 对应步骤 1 输入项 #10。
ignoreDomains 默认值包含两组网站:
- 大型网站和 UGC(wikipedia、github、stackoverflow、reddit 等)——范围太广,不适合作为内容合作伙伴来推介。
- 应用 / 扩展程序市场(Chrome Web Store、Firefox Add-ons、Apple/Google Play、VS Code Marketplace 等)——这些是产品目录列表,没有内容编辑决策者。
不要自动将以下网站添加到 ignoreDomains(由用户决定):
kaggle.com、dev.to、substack.com、producthunt.com、g2.com、capterra.com、trustpilot.com等 UGC/社区网站——有些用户向这些网站推介确实能获得实际价值。rapidapi.com、programmableweb.com、publicapis.dev等 API 目录——对某些产品(尤其是开发者工具品牌)很相关,对另一些则无关。仅当用户希望添加时,才将这些网站列为候选项。
步骤 6 中的 URL 模式跳过规则可过滤逐行噪声(子域名前缀、路径模式),这是 ignoreDomains 无法做到的。
department 默认仅为 ["marketing"]。在组合行数据时,此技能会优先选择返回的 marketing 部门中偏向内容编辑的联系人(见步骤 8)。只有当用户明确希望推介类似业务拓展的合作方案时,才添加 sales。只有当潜在客户的域名对应非常小的团队(1–5 人),且创始人可能同时担任编辑时,才添加 c_suite。
调用运行脚本:
node --env-file=.env ${CLAUDE_PLUGIN_ROOT}/scripts/run_actor.js \
--actor "apify/link-prospecting-tool" \
--input 'JSON_INPUT' \
--timeout 1800 \
--fetch-sub-datasets \
--output YYYY-MM-DD_outreach.json \
--format json
注意:
- 建议将
--timeout 1800设为客户端等待时长。Actor 本身会运行 15–50 多分钟,具体取决于关键词数量、LLM 引擎的并行扇出以及enableEmailVerification。以往的校准运行耗时为 20–55 分钟。调高默认值可避免运行器提前放弃、但 Actor 仍在继续运行而导致结果不完整。 - 如果客户端等待时间仍然耗尽,而 Actor 仍在 Apify 上运行(运行器退出时状态为
RUNNING或READY),不要重新启动 Actor。使用scripts/fetch_run_artifacts.js --run-id <id> --output <file>轮询现有运行并下载所有产物——输出格式与run_actor.js --fetch-sub-datasets相同。 --fetch-sub-datasets会将同级文件与主输出一并下载:*_mentions.json、*_authors.json、*_serp.json、*_wcc.json。要填充所有输出列,需要这些文件。
第 4 步:访问所有数据集
Actor 的输出架构于 2026-05-20 或之前发生了变化。build_prospects 脚本必须处理新的结构;使用单独的 MENTIONS 数据集进行关联的旧版 skill 已无法正常运行。
当前架构(已于 2026-05-20 验证):
| runner / fetcher 写入的文件 | 来源 | 填充字段 |
|---|---|---|
*_output.json(主文件) | “All leads” 数据集 | Contact Full Name、Contact Job Title、Department、Seniority、Contact Email、Email Verification(当 enableEmailVerification: true 时)、Contact LinkedIn、Company、Domain。每个 lead 的 source_url[] 数组包含产生该联系人的文章 URL,每个 URL 都带有一个 brand_mentioned_in_source 布尔值——这是单个(URL、联系人)提及数据的新存储位置。 |
*_serp.json | Google Search Results Scraper 子 Actor(每个 (query × engine) 组合对应一项) | SERP Position、Article Title、Publish Date(通过 organicResults[]),以及每个 URL 的引擎归属(Google Organic、ChatGPT、Gemini、Copilot、Perplexity、Google AI Mode),通过关联 aiModeResult.sources[]、perplexitySearchResult.sources[]、chatGptSearchResult.sources[]、geminiSearchResult.sources[]、copilotSearchResult.sources[] 获取。ChatGPT 返回的 URL 带有 ?utm_source=chatgpt.com 查询后缀——关联之前请规范化 URL(去除跟踪参数)。 |
*_wcc.json | Website Content Crawler 子 Actor | Placement Source Sentence、Placement With Link、Placement New Insertion、用于交叉核对的 Article Author、出站链接检查(用于添加 Links to competitor 和 Resource / roundup page 标签)。用于构建行的规范 URL 列表——每个经过正文抓取的 URL 都会出现在此处,包括未产生 lead 的 URL。 |
*_authors.json | AI Web Scraper 子 Actor(当 searchAuthorName: true 时) | Article Author、Author Source(设为 searchAuthorName)。注意:此子 Actor 经常在默认的 300s 时限内超时——仍会保存部分结果。 |
变化内容(与 2026-05-20 之前的运行相比):
- 不再有名为
MENTIONS/AUTHORS/DOMAINS_WITH_LEADS的独立数据集——提及信息已并入main_leads[i].source_url[]。 - 父运行的键值存储中不再有
SUB_ACTOR_RESULTS记录。现在只能通过父运行日志中的正则表达式\[apify\.<slug> runId:([A-Za-z0-9]+)\]查找子 Actor 的 runId。如果缺少 KV 索引,runner 脚本的--fetch-sub-datasets标志现在会改为解析日志;独立脚本scripts/fetch_subactors_from_log.js对于 runner 已退出的运行也会执行相同操作。 - 提及数据架构已精简:
source_url[i]仅包含{domain, brand_mentioned_in_source, url}——不再包含旧版ChatGPT_mention/Perplexity_mention等按引擎划分的标志。必须根据 SERP 子数据集的 LLM 结果子字段重建引擎归属(见上方 SERP 行)。
如果某列缺少来源,请填写 "Not found",并在 Notes 中添加手动查询提示。切勿捏造信息。
第 5 步:Ahrefs 数据补充与潜在对象分级
对于每个通过 Actor 筛选的唯一域名,通过 Ahrefs MCP 获取权威度和流量指标。针对每个域名并行调用全部三个工具(也要跨域名批量并行处理,以确保典型的 20–50 个潜在对象列表能在一分钟内完成此步骤):
| Ahrefs 工具 | 用途 | 填充的列 |
|---|---|---|
mcp__claude_ai_Ahrefs__site-explorer-domain-rating(target = domain) | 域名评分 | Domain DR |
mcp__claude_ai_Ahrefs__site-explorer-metrics(target = article URL,mode = exact) | 页面级自然流量(过去 30 天) | Page Traffic |
mcp__claude_ai_Ahrefs__site-explorer-backlinks-stats(target = domain) | 引用域名数量 | Referring Domains |
如果 Ahrefs 没有返回数据(域名尚未被索引,或页面发布时间太短),将该列设为 "-",并在 Notes 中添加提示 "Ahrefs has no data — verify manually before pitching"。不要编造数值。
根据用户的目标和对应的阈值设置 Prospect Tier:
| 目标 | A 级 | B 级 | C 级 |
|---|---|---|---|
指向特定 URL 的主题权威链接 | DR ≥ 50 且 Page Traffic ≥ 300/月 | DR 30–49 或 Page Traffic 50–299 | 低于以上阈值 |
从任何相关网站获取尽可能多的链接 | DR ≥ 30 且 Page Traffic ≥ 100/月 | DR 15–29 或 Page Traffic 20–99 | 低于以上阈值 |
找回未加链接的品牌提及 | 不适用——每次提及都值得争取;仅按 DR 分级(≥ 40 = A,20–39 = B,< 20 = C) | ||
替换竞争对手链接 | 按 DR 分级(≥ 50 = A,30–49 = B,< 30 = C) | ||
自定义 | 使用 主题权威 阈值 |
在第 8 步之前向用户展示各级别的数量分布,并让他们确认是为所有级别还是仅 A/B 级起草邮件。
第 6 步:跳过检查
起草任何邮件之前,逐行检查并应用跳过规则。被跳过的行应将 Outreach Status = "Skip",在 Notes 中写明一行原因,且不生成邮件或链接位置(节省 token 和用户审核时间)。
跳过规则(按顺序):
-
目标不匹配。 如果目标是
Recover unlinked brand mentions,且该行的 Mentions 数据显示brand_mentioned_in_source: false,则跳过。如果目标是Replace competitor links,且该行的 WCC 正文没有指向任何competitorDomains条目的出站链接,则跳过。 -
已联系过。 如果该行的域名与 Step 1 输入 #7 中可选的已联系名单里的某个条目匹配,则跳过。
-
自有域名/竞争对手域名泄漏。 Actor 应已过滤这些内容,但请再次检查——如果该行的域名与
ownDomains或competitorDomains匹配,则跳过。 -
内容过时。 如果
Publish Date距今超过 5 年,则跳过(编辑更新帖子的可能性较低)。 -
按 URL 模式跳过。 跳过 URL 匹配以下任一模式的行:
- 子域名前缀:
developers.*、docs.*、support.*、helpcenter.*、legacy.*、dsarequests.*、connectivity.*、community.*、dev.*(用作文档子域名时,例如dev.example.com/api/)、api.*仅当后面跟着明显属于文档的路径时(/reference/、/docs/、/spec/)。不要仅凭此规则跳过rapidapi.com或其他 API 目录域名——api.*是子域名检查,而非子字符串检查。 - 路径模式:
/api-docs/、/reference/、/marketplace/、/extensions/、/profile/、/users/、/free-tools/、/spec/、/content/privacy、/content/terms、/content/dma、/content/how_we_work、/legal/、/_redirects、/sitemap。 - 供应商产品页面模式:URL 以
-scraper.php结尾、包含-scraping.php、包含-data-scraper.、包含-data-scraping.、包含/bots/、/extension/、/detail/(扩展详情页)。
- 子域名前缀:
-
非编辑类页面。 检查 WCC 页面正文。跳过供应商产品页、定价页、登录墙、注册页、条款/法律页面,以及正文少于 400 词的页面。少于 400 词即达到跳过阈值——大多数编辑类文章都在 800 词以上。
-
漏网的 UGC。 如果页面 URL 包含
/forum/、/thread/、/comments/、/answers/、/q/、/topic/、/discussion/,或 WCC 正文采用讨论回复的结构,则跳过。 -
类别匹配门槛(宽松)。 从用户的产品描述(Step 1 输入 #4)中提取 4–6 个类别关键词——这些词描述的是产品类别,而非用户 URL 的具体主题。网页抓取产品的关键词示例:
scrape、scraping、scraper、crawl、extract、data extraction。CMS 产品的关键词示例:cms、headless、content、editorial。该行的 WCC 正文必须包含这些类别关键词中的至少 1 个。否则,以原因Article isn't in user's product category (no '<kw>' match)跳过——这会筛掉经 SERP 过滤后仍漏网的食谱博客、金融文章等类别不符的内容。对于非英语营销活动,类别词集需包含源语言和英语关键词——许多捷克语/德语/法语文章会在文中引用英文品牌名称和产品类别。捷克水过滤品牌的关键词示例:
{filtr, filtrace, vod, voda, filter, filtration, water}。纯捷克语关键词集会漏掉由捷克作者撰写、混合使用捷克语和英语的文章。 此规则无法识别的已知漏判(第 8 步的逐行子 Agent 必须识别这些情况):- 销售完全相同产品类别的本地电商竞争对手。 过去的活动中,有多家区域性网店通过了机械筛选——通常是基于平台搭建的商店(例如 Shoptet、Shopify),文章正文中嵌有“加入购物车”按钮。子 Agent 正确地跳过了它们,但浪费计算资源是个隐患。此规则的未来版本应检测平台特征(平台资源包 URL、本地化的“加入购物车”字符串、
/eshop/、正文中嵌有价格的产品卡片),并提前跳过。 - 类别名称同形异义。 捷克语中的“filtr”也有摄影或咖啡领域中“滤镜/过滤器”的意思——咖啡滤纸或相机滤镜博客会通过此关,但并不真正匹配。子 Agent 会通过阅读正文上下文识别这些情况。
类别关卡有意设置得较宽松。 这是类别检查,而非主题检查——更细致地判断“这篇具体文章是否适合我的这个具体 URL”由第 8 步的逐行子 Agent 负责。例如:如果用户的 URL 专门介绍如何爬取某个旅游网站,那么一篇从未提及该旅游网站的通用“python 网页爬取”指南会通过此关,因为它属于用户的类别。接下来,第 8 步的子 Agent 会决定是起草一条推荐植入内容(例如,添加一句点名该旅游网站的话),还是建议因内容不符而跳过。
在第 6 步开始时向用户展示提取出的类别关键词列表,并让用户在筛选运行前添加或删除关键词。
- 销售完全相同产品类别的本地电商竞争对手。 过去的活动中,有多家区域性网店通过了机械筛选——通常是基于平台搭建的商店(例如 Shoptet、Shopify),文章正文中嵌有“加入购物车”按钮。子 Agent 正确地跳过了它们,但浪费计算资源是个隐患。此规则的未来版本应检测平台特征(平台资源包 URL、本地化的“加入购物车”字符串、
-
检测对抗性提及。 当
brand_mentioned_in_source: true时,扫描 WCC 正文中品牌提及前后 ±100 个字符的范围,查找负面语境词:vs、versus、alternative to、alternatives to、compared to、compared with、instead of、better than、worse than、pros and cons、comparison、review of。如果范围内出现任何一个词,则跳过,原因设为Adversarial mention (likely competitor comparison page) — won't link。这可以识别“ScrapeHero vs Apify”页脚提及、“YourBrand 的替代品”榜单文章,以及类似的非链接语境。至关重要——没有此规则,unlinked-mention-claim外联类型会触发数十个误报。 -
既无联系人,也无编辑联系途径。 如果
Contact Email = "Not found",且没有Article Author,WCC 外链中也没有找到域名级别的联系页面,则跳过——没有可联系的人。 -
无效电子邮件(来自验证结果)。 如果运行了
enableEmailVerification: true,请检查每行的Email Verification状态。如果主要联系人的状态为invalid,则在跳过该行前,先尝试备用联系人——过去的运行曾因主要联系人的电子邮件无效、但同一域名下存在已验证的备用联系人而漏掉 A 级候选对象。只有在没有任何备用联系人拥有已验证或未经检查的电子邮件时,才以原因Email failed verification (invalid address)跳过。catch-all、risky、unknown状态仅供参考(不会自动跳过)——在Email Verification列中显示。verified状态照常保留。如果本次活动未运行验证,则该列显示-,且此规则不生效。
绝不要在 Notes 中建议使用外部查询服务或替代工具——例如 hunter.io、LinkedIn search、第三方验证服务。此技能的职责是如实展示我们找到的信息。信息缺失时(没有电子邮件、没有作者等),说明缺失之处并停止。用户知道该去哪里查;把他们自己的工具推荐回去既居高临下,也会让输出变得臃肿。
以上任一规则不通过的行都会在第 7 步之前跳过。跳过的行仍会出现在最终输出中(以便用户查看筛除了哪些内容),但植入内容和电子邮件单元格为空,且 Outreach Status = "Skip",并在 Notes 中注明原因。
第 7 步:“为什么选择这位潜在客户”标签
为每个保留的行计算一个或两个 Why This Prospect 标签,并按最有说服力的角度优先排序。这些标签用于驱动第 8 步中的外联类型模板选择。
| 标签 | 触发条件 | 权威来源 |
|---|---|---|
提及品牌,但没有反向链接 | Mentions 数据集中的 brand_mentioned_in_source: true 且 backlink_in_source: false | Mentions 数据集 |
链接到竞争对手 [domain] | WCC 页面正文包含出站链接,且其主机名与任意 competitorDomains 条目匹配 | WCC 数据集 |
[keyword] 的 SERP 前 3 名 | 任意关键词的 SERP Position 为 1、2 或 3 | Google Search Scraper 子数据集 |
资源/汇总页面 | WCC 页面正文包含 10 个或更多出站链接,且页面标题或 H1 匹配 /(best|top|list|roundup|tools|resources|guide to)/i | WCC 数据集 |
内容过时 | Publish Date 早于 24 个月但晚于 5 年(5 年及以上的内容已跳过) | Google Search Scraper/WCC |
每行最多可带两个标签。按说服力从强到弱排序,优先级如下:提及品牌,但没有反向链接 > 链接到竞争对手 > 资源/汇总页面 > SERP 前 3 名 > 内容过时。如果没有匹配的标签,将该列留为 "-" — 该行仍会纳入外联,只是没有特别切入角度。
第 8 步:为每行撰写植入方案和邮件
每个保留的行都需要生成三项植入材料和一份邮件草稿。务必遵守以下质量规则:
-
不得捏造信息。 如果文章作者或联系邮箱未知,将字段设为
"Not found",并留下一条简短的事实说明(例如,"未找到此联系人的邮箱"或"未检测到作者")。不要在 Notes 中建议使用外部查找工具或变通方法 — 原因见第 6 步规则 11。只陈述事实即可。 -
优先选择偏编辑类联系人。 如果 All leads 数据集为同一域名返回了多个联系人,优先选择
jobTitle匹配/editor|content|writer|managing|editorial|blog|copy/i的联系人;除非公司只有 1–5 人,否则将jobTitle匹配/ceo|cfo|cto|founder|chief|vp\b|president/i的联系人列为次选。在该行中显示选定的联系人;在Notes中保留其他联系人,格式为"备用联系人:<name1>(<title>)、<name2>(<title>)"。 -
三种植入方式 — 按以下优先级顺序尝试。 使用 WCC 子数据集中的页面文本。按顺序尝试策略 1 → 2 → 3;遇到第一个能自然契合的策略时即停止。将所用策略写在
Notes字段开头:Placement: drop-in/Placement: additive/Placement: new insertion。策略 1 — 直接植入(优先)。 在文章中找到一个句子,使用户的 URL 能添加到现有词语上,且无需更改周围的任何文字。链接需添加到作者已写好的现有词语或短语上。输出:
Placement Source Sentence= 文章中的原句,逐字照录。Placement With Link= 在现有词语/短语上添加链接后的同一句子。不添加新文字、不改写、不删减。 示例:原句 ="Tools like Octoparse and BeautifulSoup work well for hotel data."→ 添加链接后 ="Tools like Octoparse and **[BeautifulSoup](URL)** work well for hotel data."(将链接添加到现有词语上)。编辑无需审核任何新文字 — 只需添加超链接。Placement New Insertion="-"。
当文章中已经提到与用户 URL 适配的品牌、工具或技术时,适合采用直接植入。这是所有外联方式中阻力最小的请求:“能否给您已经写好的词语添加一个超链接?” 策略 2 — 添加式(次选)。 如果没有可直接替换的目标,但文章中有一句话适合自然地承接用户的 URL,则保留原句不变,并在其后添加一句新句子。新句子应引出文章尚未涵盖、且用户的 URL 能满足的相关读者需求。输出:
Placement Source Sentence= 原文中的完整句子。Placement With Link= 原句保持不变,后接→和一句包含链接的补充句。例如:source ="By integrating with Acme Travel's APIs, developers can enrich their platforms with hotel data."→ with-link ="By integrating with Acme Travel's APIs, developers can enrich their platforms with hotel data. → ...with hotel data. In need of competitor pricing data the API doesn't expose? Then you need a [hotel-data scraper](URL)."保持原句不变;补充句是唯一新增的文案。Placement New Insertion="-"。
补充句必须:(a) 提出原句未涉及的读者需求;(b) 将该需求与用户的 URL 联系起来;(c) 只有一句,不超过 25 个单词,并采用文章的语气。
策略 3 — 新增插入(最后手段)。 只有在直接替换和添加式方案都不可行时(例如,文章正文中没有相关句子),才起草一段全新的 1–2 句内容,并精确说明插入位置:
Placement Source Sentence="-"。Placement With Link="-"。Placement New Insertion= 起草的段落 + 精确位置说明("在 H2 'Y' 下的章节中,紧接以 '…X.' 结尾的句子后,作为新段落插入。")。
如果连新增插入也无法起草(文章主题与用户的 URL 不匹配),则设定
Outreach Status = "Skip",并添加Notes: "No natural placement — article topic mismatch"。但是,第 6 步规则 8 中的主题匹配门槛本应已筛出这种情况;如果某行进入第 8 步后仍无法安排插入位置,这说明门槛需要补充更多关键词。每一条未筛除的记录都必须交由子 Agent 处理,而不只是 Tier A/B/仅提及的记录。机械式跳过筛查(第 6 步)会剔除明显不合格的潜在对象(竞争对手域名、文档子域名、政策页面、联系人失效的记录、类别不符的文章)。所有通过筛查的对象都值得认真考虑,子 Agent 会做出最终匹配判断:阅读文章,尝试安排插入(直接替换 → 添加式 → 新增插入),然后起草邮件,或返回
placement_strategy = "skip"并附上与内容相关的原因。最终草稿不得使用 Python 模板、正则表达式或关键词评分——这些方法会生成生硬的机械式拼接内容,放在上下文中读起来不自然(我们在真实推广活动中已见过这种失败案例)。并行启动子 Agent:每条未筛除的记录对应一个子 Agent,并向其提供 WCC 文本、用户 URL 上下文、联系人信息、品牌语气和合作邀约。输出架构(插入策略、三个插入列的值、邮件主题 + 正文、跳过建议、备注)将合并回电子表格对应行。
如果子 Agent 在审阅内容后决定跳过某条记录,则设定
Outreach Status = "Skip",并在 Notes 中填写 Agent 给出的原因——格式与第 6 步机械式跳过相同,只是理由更加细致。 -
根据
Why This Prospect标签和用户目标,逐行确定Outreach Type:触发条件 Outreach Type存在标签 Mentions brand, no backlinkunlinked-mention-claim存在标签 Links to competitorcompetitor-link-replacement存在标签 Resource / roundup pageresource-page-inclusion存在标签 Outdated contentoutdated-content-replacement以上均不符合,或仅有 Top-3 SERP标签topical-niche-edit从 reference/email-templates.md中提取匹配的模板。用户在步骤 2 中给出的Partnership type答案会代入模板中的{{offer_paragraph}}占位符——外联类型决定结构和开场切入点,合作类型决定提议内容。 -
Suggested Email Copy必须使用用户的品牌语气。 根据reference/email-templates.md中的语气替换规则,逐字应用语气段落。如果用户跳过了语气输入,则使用通用专业语气作为默认值,并在Notes中注明。
5a. 邮件必须包含确切的放置文案——逐字呈现。 收件人不应需要追问“您建议使用什么措辞?”或点击另一个单元格来查看提议文案。请直接在邮件中嵌入提议内容:
- 对于 drop-in:内嵌引用来源句子和添加链接后的版本。示例:
"在您的句子 'Tools like X and Y work well for Z' 中,您愿意将 'Y' 改成指向 <URL> 的超链接吗?" - 对于 additive:逐字引用锚点句子,并附上您建议添加的确切后续句子。示例:
"紧接在您的句子 'X happens because Y.' 后面,您愿意添加:'For the Z case specifically, see <URL>.'吗?" - 对于 new insertion:引用新段落应接在其后的锚点句子,然后内嵌完整的拟议段落。示例:
"在 'Honorable mentions' 部分中,紧接在 'each platform has its own trade-offs.' 后面,您愿意添加这段内容吗:'<full paragraph with link>'?"
邮件本身就是提议。如果措辞没有出现在邮件中,提议就不完整。像“很乐意帮您起草”/“很乐意提供确切措辞”/“添加一个包含链接的后续句子”等模糊表达,都是内容技能缺陷——务必改写为包含逐字呈现的提议文案。
-
字数上限:邮件不超过 150 个单词(主题 + 正文)。
-
必须进行个性化。 每封邮件都必须以对特定文章的具体引用开头(标题 + 一句话概述文章内容)。不要使用“我很喜欢您的文章”这类通用开场白。
步骤 9:呈现输出
Markdown 格式——Agent 在聊天中直接呈现:
- 一行标题,包含 Apify 运行 ID 和分级统计(
A: 8, B: 15, C: 7, Skipped: 12)。 - 每位潜在客户一行 Markdown 表格,包含最具行动价值的列(分级、原因、联系人、放置摘要)。已跳过的行在底部单独的折叠区域中呈现。
- 表格下方,每条未跳过的记录对应一个围栏代码块,包含邮件草稿(主题 + 正文),并标注行索引、分级和外联类型。
xlsx 格式——步骤 5–8 完成后,scripts/write_xlsx.py --config campaign.json 会生成一个包含 2 个工作表的工作簿。
xlsx 文件包含两个工作表:
Outreach——仅包含有效记录,包含全部 30 列。这是可直接用于发送的交付文件。按Prospect Tier升序排列(A 优先),然后按Domain DR降序排列,再按SERP Position升序排列。Skipped——已跳过的记录,包含精简列:Domain、Article URL、Article Title、Skip Reason(从 Notes 中提取)、Source Engines、Why This Prospect。此工作表便于审查被筛除的记录,同时避免主视图杂乱。这里不会显示缺失的 Ahrefs 列,因此不会再让人困惑为何数据为空。
用户打开文件后,默认进入 Outreach——只显示可采取行动的潜在客户。用户可以切换到 Skipped 进行审查。此模式取代了旧版将跳过记录标红、全部放在单个工作表中的做法。
两种格式都会另外生成一个 run_metadata.json 文件:{ runId, actorId, startedAt, finishedAt, inputs, datasetIds, tierCounts, skipCounts }。将其放在主输出文件旁边。
输出行架构(30 列)
SERP Position、Source Engines、Keyword、Article Title、Article URL、Domain、Domain DR、Page Traffic、Referring Domains、Prospect Tier、Why This Prospect、Article Author、Author Source、Publish Date、Contact Full Name、Contact Job Title、Department、Seniority、Contact Email、Email Verification(取值为 verified / catch-all / risky / invalid / unknown / -)、Contact LinkedIn、Company、Outreach Type、Partnership Offer、Placement Source Sentence、Placement With Link、Placement New Insertion、Suggested Email Copy、Outreach Status(默认值为 "Not started",跳过的行使用 "Skip")、Notes(自动标记 + 跳过原因 + 手动提示 + 其他联系人)。
包含各列类型和来源数据集的完整架构见 reference/output-formats.md。
错误处理
| 错误 / 症状 | 处理方法 |
|---|---|
APIFY_TOKEN not found | 请用户创建包含 APIFY_TOKEN=your_token 的 .env 文件。在 console.apify.com/account/integrations 获取令牌。 |
| Ahrefs MCP 不可用 | 跳过步骤 5。将 Domain DR、Page Traffic、Referring Domains、Prospect Tier 设为 "-",并在输出标题中添加一行说明,解释未计算层级。继续执行工作流的其余部分。 |
Cannot find module 'xlsx' | 在技能的 scripts/ 文件夹内运行 npm install。 |
Error: 'brand' is required | 用户跳过了步骤 1 的锚点 #3。重新询问品牌名称。 |
Actor 运行 TIMED-OUT(客户端超时,Actor 仍在 Apify 上运行) | 不要重新启动。使用 node --env-file=.env scripts/fetch_run_artifacts.js --run-id <runId> --output YYYY-MM-DD_outreach.json --timeout 1800 轮询现有运行,并在其终止时下载所有数据集。输出结构与运行器相同。 |
Actor 运行 TIMED-OUT(Actor 自身运行时间超过其 timeoutSecs) | 参阅 reference/troubleshooting.md。降低 organicResult、减少关键词,或停用部分 LLM 引擎。这几乎不是超时原因——通常是客户端等待超时。 |
Author = Not found | 对于约 30% 没有署名信息的页面,这是预期情况。技能会写入 "Not found",并在 Notes 中添加手动查找提示。不得捏造信息。AI Web Scraper 子 Actor 经常会在默认的 300s 时限内爬取过程中超时(以往的活动中,曾因此一次丢失约 7 个高 DR 网站的作者数据);发生这种情况时,_authors.json 数据集仍包含超时前已完成的部分结果。写入 "Not found" 前,Agent 应尝试使用 WCC metadata.author / openGraph article:author / JSON-LD Person.name 作为备用来源。 |
缺少子 Actor 数据集(运行 --fetch-sub-datasets 后没有 _mentions.json / _authors.json / _serp.json / _wcc.json) | Actor 的输出架构在 2026-05-20 当日或之前已更改:SUB_ACTOR_RESULTS 不再存储于 KV store 中,名为 MENTIONS / AUTHORS / DOMAINS_WITH_LEADS 的数据集也已移除。运行器脚本现在会自动回退到解析日志;但如果未能回退,请运行 node --env-file=.env scripts/fetch_subactors_from_log.js --run-id <id> --base <prefix>,从父级日志中可见的子 Actor runIds 生成 _serp.json、_wcc.json、_authors.json。提及数据现在嵌入在 main_leads[i].source_url[] 中,而非单独的文件。 |
Contact Email = Not found | Contact Details Scraper 子 Actor 未能从网站找到邮箱。将该字段设为 "Not found",并在 Notes 中留下一行事实说明("No email found for this contact")。不得捏造信息,也不要建议使用外部工具。如果联系人和作者信息都缺失,跳过处理步骤(步骤 6,规则 7)会移除该行。 |
| 目标筛选器跳过了所有行 | 用户的目标相对于 SERP 结果而言过于狭窄。建议放宽目标(例如,使用 Topical authority 代替 Recover unlinked brand mentions),或扩展关键词。 |
0 leads returned | 关键词过于狭窄,或 ownDomains / competitorDomains 筛掉了所有 SERP 结果。扩大关键词范围、缩小排除范围,或提高 organicResult。 |
| 成本高于预期 | 子 Actor 扇出(Google Search Scraper、WCC、Contact Details Scraper、AI Web Scraper)会叠加成本。参阅 reference/apify-actor-usage.md 中的成本部分。要降低成本:移除 searchAuthorName,停用 AI 平台(enableChatGpt: false 等),将 maxContactsPerDomain 降至 1,将 organicResult 降至 5。 |