OpenSEO 关键词数据源路由架构解析:DataForSEO Labs 与 Google Ads 的混合供应与 Clickstream 默认关闭策略
OpenSEO 关键词数据源路由架构解析DataForSEO Labs 与 Google Ads 的混合供应与 Clickstream 默认关闭策略【免费下载链接】open-seoOpen source alternative to Semrush and Ahrefs项目地址: https://gitcode.com/GitHub_Trending/op/open-seo本篇技术指南围绕 OpenSEO 的设计决策文档 specs/0004-keyword-data-source-routing.md 展开深入剖析开源 SEO 平台 OpenSEO 如何解决关键词研究Keyword Research的全球覆盖缺口当 DataForSEO Labs 仅支持 94 个国家时如何通过每国家单一数据源、按功能路由的混合架构接入 Google Ads 关键词数据并以 Clickstream 精细化默认关闭的方式控制这一最高成本功能的花费。读完本文你将掌握getKeywordDataProvider的路由逻辑、Labs 与 Google Ads 两类端点在 OpenSEO 源码中的真实实现、Clickstream 开关在前端 URL 参数与 MCP 工具层面的传递链路以及其成本模型与缓存设计。背景94 国覆盖缺口与三个候选数据源关键词研究是 OpenSEO 用户最大的积分credit消耗项而覆盖范围存在硬缺口DataForSEO Labs 只支持 94 个国家这意味着一个位于冰岛location 2352的用户完全无法执行关键词研究。在采纳本决策前团队评估了三个数据源候选数据源定价模式覆盖附加能力核心限制DataForSEO Labs现有来源按行计费$0.01/task $0.0001/row94 国关键词难度keyword difficulty、搜索意图search intent、SERP 特性上下文include_clickstream_data标志可产出精细化流量数据但请求成本翻倍国家覆盖有限DataForSEO Keywords DataGoogle Ads 端点每次实时请求固定 $0.075search_volume最多 1,000 个关键词keywords_for_keywords最多 20 个种子词217 国含冰岛无难度/意图/SERP 数据流量以桶bucket形式聚合近似变体数据维度少直接对接 Google Ads API免费全量无政策上不可行Google Targeting-data 政策禁止为创建或管理 Google Ads 广告系列之外的任何目的收集关键词规划器数据向用户展示还需完整的 Required Minimum Functionality一套广告系列管理套件无活跃广告支出的流量以桶呈现关于第三个选项决策文档明确结论直接对接 Google Ads API 被拒绝是政策原因而非工程难度只有当 OpenSEO 未来上线广告系列管理功能时才有重新评估的意义。决策每个国家恰好一个关键词数据提供方由getKeywordDataProvider解析核心决策是不存在用户可见的数据源选择——每个受支持国家有且只有一个关键词数据提供方由getKeywordDataProvider(locationCode)决定该函数定义在 src/shared/keyword-locations.tsexport function getKeywordDataProvider( locationCode: number, ): KeywordDataProvider { return LOCATION_CODES.has(locationCode) !LABS_LOCATION_CODES.has(locationCode) ? google_ads : labs; }其背后的数据模型是 src/shared/keyword-locations.ts 中的LOCATION_OPTIONS常量表。表中的每个条目都包含codeDataForSEO location_code、label、shortLabelISO 3166-1 alpha-2 国家码和languageCode凡 Labs 不覆盖的国家都会额外打上googleAdsOnly: true标记例如冰岛{ code: 2352, label: Iceland, shortLabel: IS, languageCode: is, googleAdsOnly: true },据此Labs 是默认提供方。LOCATION_OPTIONS中被标记googleAdsOnly的国家由 Keywords Data Google Ads 端点服务未知的 location code 回退到 Labs由 Labs 自身以报错的方式拒绝行为对任意 code 保持不变。按功能路由。不同功能对同一国家的数据源映射如下决策文档原文表功能Labs 国家仅 Google Ads 国家如冰岛关键词研究UI research_keywordsLabs related → suggestions → ideaskeywords_for_keywords单一来源get_keyword_metrics、排名追踪指标刷新Labs keyword_overviewsearch_volumeSERP 分析、get_serp_results、排名追踪SERP APISERP API支持所有国家域名概览、排名关键词、SERP 竞争者Labs不可用——选择器被过滤为仅 Labs 国家MCP 工具返回明确的校验错误Google Ads 来源的行没有关键词难度或意图keywordDifficulty: null、intent: unknown。研究页面与 MCP 工具描述会在此类国家被选中时明确说明这一点。Clickstream 精细化按调用 opt-in默认关闭适用于 Labs 研究端点related/suggestions/ideas与 keyword overview。用户通过研究页面上的复选框URL 参数cs按关键词标签页传递对 Google Ads 独有国家隐藏或 MCP 工具的includeClickstreamData参数开启标签与工具描述必须说明 2× 积分成本。该标志是研究缓存键的组成部分。Google Ads 独有国家的语言码必须同时存在于 Google Ads 与 SERP 语言列表中——国家选择器与排名追踪共享而排名追踪走 SERP API。中国被排除在外其 Ads 语言码zh_CN与 SERP 格式zh-CN冲突且 Google 搜索在中国大陆并不实质运营。计费逻辑不变。keywords_data/*任务成本与 Labs 调用走同一套 envelope → markup → Autumn 流水线映射到keyword_research积分功能排名追踪覆盖为rank_tracking参见 src/shared/billing-credit-features.ts。googleAdsOnly标记还派生出一个关键的导出常量LABS_LOCATION_OPTIONS LOCATION_OPTIONS.filter((option) !option.googleAdsOnly)src/shared/keyword-locations.ts。域名概览、排名关键词等 Labs 专属功能的选择器正是用这个过滤后的列表从 UI 层面杜绝了选到不可服务国家。源码级实现研究服务如何按 provider 分流路由决策在 src/server/features/keywords/services/research/research.ts 的research()主入口落地。该函数先对种子词做归一化与去重随后const provider getKeywordDataProvider(input.locationCode); // Labs source modes and clickstream refinement dont exist for // Google-Ads-served countries; collapse both so equivalent requests share // one cache entry. const effectiveInput: ResolvedResearchKeywordsInput provider google_ads ? { ...input, mode: auto, clickstream: false } : input;这段代码有两点值得注意的工程细节Google Ads 国家强制mode: auto且关闭 clickstream——Labs 专属的三种来源模式related/suggestions/ideas和 clickstream 精细化在这类国家不存在把它们坍缩掉可以让等价请求共享同一缓存条目。缓存键包含 clickstream 标志。buildResearchCacheKeyresearch.ts在kw:research命名空间下组合organizationId、projectId、keywords、locationCode、languageCode、resultLimit、mode、depth: 3与clickstream确保精细化前后的数据绝不互相污染。随后按 provider 分流Google Ads 国家走fetchGoogleAdsRowsLabs 国家在 auto 模式下按related → suggestions → ideas顺序尝试fetchAutoRows直到非种子词数量满足MIN_NON_SEED_FOR_AUTO阈值。Google Ads 行无难度、无意图Google Ads 路径的数据获取在 research-data.ts 的fetchGoogleAdsResearchRows它调用dataforseo.keywords.adsIdeas即keywords_for_keywords端点后经mapAdsKeywordItems映射。对比 Labs 行的映射差异一目了然research-data.tsrows.push({ keyword: normalized, searchVolume: item.search_volume ?? null, trend: ..., cpc: item.cpc ?? null, competition: item.competition_index ! null ? item.competition_index / 100 : null, keywordDifficulty: null, // 无关键词难度 intent: unknown, // 无搜索意图 });注意competition的归一化Google Ads 返回 0–100 的competition_index而应用内部统一存储 0–1 比例因此需要除以 100。Labs 行则从keyword_properties.keyword_difficulty与search_intent_info.main_intent读取这两个字段经normalizeIntent归一为应用枚举。Google Ads 端点与 Labs 端点两个模块、两套计费两个数据源在代码库中分属不同模块src/server/lib/dataforseo/google-ads.ts 与 src/server/lib/dataforseo/labs.ts。Google Ads 端点Keywords Datagoogle-ads.ts封装了两个实时端点fetchAdsSearchVolume→POST /v3/keywords_data/google_ads/search_volume/livegoogle-ads.ts。一次请求可携带最多 1,000 个关键词它还接受可选的locationNameDataForSEO 标准location_name字符串如 Pittsburgh,Pennsylvania,United States从而把流量/CPC/竞争度限定到城市或地区而非整个国家——这是 Google Ads 独有的子国家粒度能力。fetchAdsKeywordIdeas→POST /v3/keywords_data/google_ads/keywords_for_keywords/livegoogle-ads.ts。请求体内显式设置sort_by: search_volume该端点没有 limit 参数一次平费请求可能返回数千甚至 2 万条建议因此代码在拿到结果后自行slice(0, input.limit)截断到调用方需要的数量。Labs 端点labs.ts封装了研究链路的核心端点fetchRelatedKeywordsrelated_keywords、fetchKeywordSuggestionskeyword_suggestions、fetchKeywordIdeaskeyword_ideas与fetchKeywordOverviewkeyword_overview。它们的请求体中都带有一个关键标志// Clickstream-refined volumes DOUBLE the request cost, so they are // opt-in — see specs/0004-keyword-data-source-routing.md. include_clickstream_data: input.includeClickstreamData ?? false,见 labs.ts 的fetchRelatedKeywordssuggestions/ideas/overview 三个端点同样如此。这就是Clickstream 默认关闭在 HTTP 层的最小实现一个显式默认为false的布尔字段。决策文档也指出若未来要整体回滚该默认值只需在labs.ts的每个 fetcher 中做一行修改opt-in 的整套管线参数传递、缓存键、UI可以原样保留。指标刷新批量上限 700 与本地粒度合并get_keyword_metrics与排名追踪的指标刷新走 src/server/lib/dataforseo/keyword-metrics.ts 的fetchKeywordMetricsForList它按KEYWORD_METRICS_BATCH_SIZE 700分批调用DataForSEO 批量指标端点每请求约 700 个关键词的上限同样以getKeywordDataProvider(params.locationCode)决定走adsSearchVolume还是keywordOverviewkeyword-metrics.ts。该模块还实现了一个精妙的混合场景当请求指定了子国家locationName且国家由 Labs 服务时同时发起 Google Ads 本地流量调用与 Labs 国家级 keyword_overview 调用再通过mergeLocalAndNationalRows合并——本地流量/CPC 来自 Google Ads国家级难度/意图来自 Labs。合并时有一条严格的数据诚实原则Google Ads 偶尔会把近似关键词折叠为一个条目那些被折叠的关键词宁可保留难度/意图而让 volume/CPC 为 null也绝不展示具有误导性的国家级数字keyword-metrics.ts。Clickstream 精细化2× 成本的按需开关Clickstream 数据的作用是拆解 Google Ads 聚合的近似变体流量复数形式、拼写错误等给出更精细的搜索量。但它会使请求成本翻倍而唯一收益只是让 volume 数字更精确——标准keyword_info.search_volume本就是各大主流工具展示的同一份 Google Ads 衍生流量。因此决策是默认关闭按调用开启并把成本写进标签。在 OpenSEO 中这条 opt-in 链路贯穿三层UI 层研究页面提供带标签的复选框URL 参数为cs按关键词标签页tab独立携带Google Ads 独有国家自动隐藏。参数定义与传递见 src/client/features/keywords/keywordSearchParams.ts 与 src/client/features/keywords/page/KeywordResearchPage.tsx。MCP 工具层research_keywords工具接受可选的includeClickstreamData布尔参数其 schema 描述明确标注会使每个种子的积分成本翻倍默认 false标准 Google Ads 衍生流量对 Google Ads 数据服务的国家无效果src/server/mcp/tools/research-keywords.ts。工具描述还直接写明了成本区间每个种子约 30–100 积分因数据源而异Google Ads 数据服务的国家固定约 96 积分且无难度/意图。服务层research()中clickstream: input.clickstream既进入缓存键也原样传给 Labs fetcher 的include_clickstream_data字段。缓存版本同步升级决策落地时研究缓存版本号从 2 升到 3research.ts中const CACHE_VERSION 3并注释v3: research volumes are no longer clickstream-refined, and Google-Ads-only locations route to keywords_for_keywords确保变更前按 Clickstream 价格计量的旧缓存不会与标准流量的新结果混用。语言码约束共享选择器下的双边校验由于国家选择器被关键词研究与排名追踪SERP API共享Google Ads 独有国家条目的languageCode必须同时存在于 Google Ads 语言列表与 SERP 语言列表。为此 src/shared/keyword-locations.ts 维护了权威的SERP_LANGUAGE_OPTIONS主表即 SERP Google 语言端点/v3/serp/google/languages的清洗版剔除了废弃的iw希伯来别名与冗余的no挪威统一用nb并配套多个校验与解析函数getLanguageOptions(locationCode)通过MULTI_LANGUAGE_LOCATIONS表把语言选项裁剪为该国真正支持的子集如加拿大[en, fr]、新加坡[en, zh-CN]避免选择器堆满无关语言resolveKeywordDataLanguage(locationCode, languageCode)SERP 在任何国家都服务任何语言但关键词数据 API 只服务该国自己的语言、否则以已计费的 Invalid Field: language_code 报错——该函数负责把为 SERP 选择的语言回落/转换为该国的关键词数据语言keyword-locations.tsisSupportedLanguageCodeMCP 工具传入任意language_code前先在此校验0 成本避免 DataForSEO 以不透明的已计费报错拒绝resolveMarket/resolveLabsMarket市场解析的辅助函数前者保证只覆盖 location 会连带把语言切成该地默认语言越南项目查德国时不能默认越南语后者把 Labs 独有工具中不可服务的项目默认市场替换为美国调用方从没选过该市场硬传只会让积分花在必败的任务上。中国的排除正是这条约束的直接产物其 Ads 语言码zh_CN与 SERP 格式zh-CN冲突且 Google 搜索在该市场无实质运营。成本模型为什么混合优于一刀切决策文档给出了默认配置下的完整成本核算研究默认 150 行/种子积分 USD × 1.28 markup × 1000调用Labs开启 ClickstreamLabs默认Google Adsresearch150 行$0.050 → 64 积分$0.025 → 32 积分$0.075 → 96 积分research500 行$0.120 → 154 积分$0.060 → 77 积分$0.075 → 96 积分metrics100 关键词$0.020 → 26 积分相同$0.075 → 96 积分metrics700 关键词$0.080 → 103 积分相同$0.075 → 96 积分三个关键推论全线切换到 Google Ads 数据反而更贵典型调用会从 32 积分涨到 96 积分同时丢失难度与意图而仅靠bulk_keyword_difficulty$0.11/1k复刻难度一项就足以抹平任何节省。混合方案在数据存在的地方保留更好的数据在数据缺失的地方补充覆盖。Clickstream 常开等于给第一大消费功能静默翻倍默认关闭使研究默认成本减半每种子约 64 → 32 积分同时把精细化选项以明码标价的方式留给需要的用户。Google Ads 的平费结构天然利于大批量500 行研究仍是 $0.075 平费而 Labs 按行计费涨到 $0.060——对超大批量场景Google Ads 反而成为更划算的选择。后果与边界条件覆盖扩展冰岛及约 47 个其他国家现在可以参与关键词研究与排名追踪一个由 Google Ads 服务的研究或指标调用固定消耗约 96 积分。跨国家数字可比性两个提供方的标准 volume 都源自 Google Ads 数据因此跨国家流量数字保持大致可比。速率限制Google Ads 实时端点每个 DataForSEO 账户限 12 次请求/分钟。研究每次最多扇出 5 个种子单用户不会触顶但若这类国家出现持续的多用户流量请求将排队。keywords_for_keywords无 limit 参数一次平费请求最多可返回 2 万条建议结果由服务端按流量排序应用侧截断到请求的 limit。缓存隔离缓存版本 2→3 保证变更前的 Clickstream 计价流量永不与标准流量混用。回滚成本极低回退 Clickstream 默认值只是 src/server/lib/dataforseo/labs.ts 中每个 fetcher 的一行改动opt-in 管线双向保留。结语specs/0004是一次教科书式的用最少的改动换最大的覆盖设计决策以getKeywordDataProvider为唯一路由入口、以googleAdsOnly标记为数据模型锚点在保持 Labs 优质数据不动的前提下用 Google Ads 平费端点补上约 48 个国家的覆盖缺口同时对第一大积分消耗功能引入默认关闭、明码标价、缓存隔离的 Clickstream 开关把成本控制在可预期区间。如果你想深入实现细节建议依次阅读 src/shared/keyword-locations.ts路由与语言约束、src/server/lib/dataforseo/google-ads.ts 与 src/server/lib/dataforseo/labs.ts两端点实现、src/server/features/keywords/services/research/research.ts分流与缓存以及 src/server/mcp/tools/research-keywords.tsMCP 工具参数面。【免费下载链接】open-seoOpen source alternative to Semrush and Ahrefs项目地址: https://gitcode.com/GitHub_Trending/op/open-seo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →