关于 local-seo
OpenSEO Local SEO 是一项面向实体门店和服务区域企业的本地搜索研究技能,用于分析 Google Maps 和本地搜索结果中的曝光情况。它比较商家资料、评价与网格排名,并据此整理优先修复事项。
主要功能
- 01定位本地商家及其竞争者
- 02比较类别、评价和资料完整度
- 03检查多个地点的地图排名
- 04汇总优先处理的优化事项
适用场景
- 01查找门店在周边搜索中的排名差距
- 02比较本地竞争者的商家资料与评价
- 03评估连锁业务各地点的本地曝光
MCP 相关
该技能使用 OpenSEO MCP 工具查询附近商家、地图搜索结果、商家资料与评价,以及本地排名网格。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ every-app/ open-seo --skill local-seo安装后在 Claude Code 中输入/local-seo确认已加载。
详细介绍
OpenSEO 本地 SEO
目标
找出商家为何会或不会出现在客户附近的 Google 地图和本地包中,以及应该优先修复哪些问题。
当排名取决于实体位置或服务区域时,请使用此技能。对于全国范围的自然搜索工作,请使用 competitor-analysis 或 keyword-research。
必需输入
projectId- 商家:名称,或
cid/placeId(最可靠) - 坐标(纬度/经度)——从
search_local_businesses/get_local_serp_results结果行中推导;只有在无法明确推导时才询问用户 - 一个到三个客户实际会搜索的关键词(例如“紧急水管工”,而不是品牌名称)
项目背景
项目背景工具免费,可与应用和其他 Agent 共享。
- 首先调用
get_project_context,并以其中的信息为工作依据——商家的业务内容和经营地点决定哪些关键词和半径更重要。 - 此技能需要
business_overview。如果该字段为空,请进行最简内联设置:从网站推断商家的业务内容和所在地,并用一个问题向用户确认;使用update_project_context写入后再继续。切勿一开始就进行完整访谈;请在最后建议使用seo-project-setup完成其余设置。 - 消耗额度前,先检查研究日志。如果相同研究在过去 30 天内运行过,请复用该结果并说明情况,而不是重新购买。
- 完成后,使用
update_project_context写入长期有效的信息——通过addCompetitors添加拥有网站的本地竞争对手(竞争对手行以域名为键,因此跳过没有域名的商家信息页),修正business_overview,并追加一条研究日志:{ appendResearchLog: { summary: "Local SEO: <business> near <area>. Verdict: <conclusion>" } }。
以报告形式交付
通过 seo-report 技能交付,并使用 skill: "local-seo" 保存。如果该技能不可用,请说明并在编写 HTML 前停止。
OpenSEO MCP 工具
search_local_businesses:附近的商家信息页,可按minRating、minReviews和isClaimed筛选——开展潜在客户开发时,使用isClaimed: false查找未认领的商家信息页。使用品牌名称作为query并设置较大的半径调用一次,即可返回连锁品牌所有门店的类别、评分、评论数、认领状态、坐标和cid——通常无需针对每家门店单独调用get_business_profile。get_local_serp_results:坐标附近的 Maps/Local Finder 结果集。结果行包含cid和place_id——收集一次后,在下方所有操作中重复使用。get_business_profile:单个商家的完整资料(营业时间、评分细分),适用于search_local_businesses结果行信息不足的情况。get_business_reviews:评论信息,包含评分、文本以及商家是否回复。排队处理:若响应为processing,会返回taskId——30–60 秒后使用该 ID 再次调用,无需额外费用。get_local_rank_grid:获取坐标周围网格中每个点的排名,以及每个点的结果数量和排名第 1 的商家。3x3 网格需要进行 9 次搜索;只有在服务区域确实很大时,才使用 5x5 网格。get_google_business_questions:商家资料中的问答(接受cid/placeId)。get_business_updates:商家资料中发布的动态及其日期。list_business_categories:search_local_businesses可用的有效类别 slug。
工作流
- 查找商家。仅提供名称或网站时,使用
search_local_businesses(将名称作为query,并设置较大的搜索半径)定位商家信息,获取其cid和坐标。如果返回多个地点,说明该商家是连锁品牌——请参阅下文的多地点商家。 - 在商家坐标附近,针对主要关键词运行
get_local_serp_results。记录排名前 3-5 的竞争对手的cid/place_id,以及用户自己的商家信息。 - 将用户的商家信息与排名前两位的竞争对手进行比较:主要类别、附加类别、评价数、营业时间完整度、照片数和认领状态。
search_local_businesses的结果通常包含这些信息;缺少的信息可通过get_business_profile获取。 - 检查每条商家信息的网站链接(结果中的
url/contact_url):链接应直达项目域名下对应地点的页面,而非主页或过时的域名。如需更全面的页面分析,可交由run_site_audit处理。 - 对用户的商家和最强劲的竞争对手调用
get_business_reviews。查看评价数量、近期评价、平均评分,以及收到商家回复的评价数量。 - 对主要关键词以及用户提供的其他每个关键词运行
get_local_rank_grid(使用相同网格和中心点;先说明费用)。利用网格区分“仅在门店附近排名”和“在服务区域内均有排名”,并根据各点的topResult,指出目标商家未胜出的地点由谁领先。 - 如果商家资料的基本信息已具竞争力,而差距在于互动而非设置,则添加
get_google_business_questions和get_business_updates。 - 根据证据整理出按优先级排序的清单。类别和认领问题始终比发布频率更优先。
多地点商家
始终为整个连锁品牌建立资料快照表——一次 search_local_businesses 调用即可覆盖所有地点。各地点的深入分析(评价、网格、帖子、问答)才会使成本增加:
- 5 个地点或更少:全部深入分析。
- 超过 5 个地点:先提供快照表,再询问用户(AskUserQuestion)要深入分析哪 1-3 个地点。建议合理的默认选择——例如,在竞争最激烈的市场中资料最薄弱的地点。
输出格式
h1:商家名称。
如果适用报告模板(见 seo-report),则以其章节和语气取代此列表。
章节顺序如下:
- 快照——开头用一两句话概述,随后提供类别、评分、评价数和认领状态表。连锁品牌按每个地点各列一行。
- 首要修复项——一项发现。类别和认领问题始终比发布频率更优先。
- 正面对比——列出信号、本商家、最佳竞争对手和差距的表格。涵盖类别、评价(数量、近期评价、商家回复)、营业时间和资料完整度,以及商家信息中的网站链接。
- 地图覆盖范围——按下文“绘制网格”的说明绘制网格,展示四个统计区块,然后说明结果:可见度在哪些地方下降、朝哪个方向下降,以及当地的领先者是谁。
- 问答和发布——仅在基本信息已具竞争力时提供。
- 后续行动——有序列表。
- 报告制作方式——以
seo-report中的技能链接行开头,指向https://openseo.so/docs/skills/local-seo(“OpenSEO 本地 SEO 技能”),随后说明哪些工具返回了什么内容;另需说明,判定网格中某点是否缺少排名时,应依据该点的resultsCount,而不是将其称为不可见。
绘制网格
本地排名跟踪工具(SE Ranking、Local Falcon、BrightLocal)展示的内容都一样:网格中的编号圆圈按排名着色,并标出店铺。请重现这种图示,让熟悉这些工具的读者一眼就能认出来。图中包含两部分:网格数据,供查看器绘制实时 Google Map;以及同一网格的内嵌 SVG 图示,供读者在印刷品、导出的 PDF,以及地图无法加载的情况下查看。
每个点的数值。 只有一个关键词时,数值就是排名。多个关键词时,数值为这些关键词的平均排名,保留一位小数(3.5),与 SE Ranking 将多个关键词汇总到一张地图的方式相同。某个关键词在一个点搜索过但未找到商家(rank 为 null,且没有 error)时,该点的平均值按 21 计算,因此排名 1 和未找到的平均值为 11.0。数值超过 20 时显示为“20+”,这只会在没有任何关键词找到该商家的点上出现。若某个关键词在某点搜索失败(error: true),则该点没有排名:计算该点的数值以及以下各项统计时,都应将其排除。
颜色刻度。 固定不变,不因报告而重新设置:
| 数值 | 填充色 | 数字 |
|---|---|---|
| 1–3 | #3F9D4E | 白色 |
| 大于 3–5 | #8BC34A | 白色 |
| 大于 5–7 | #F2C94C | #2A1E05 |
| 大于 7–10 | #F28C28 | 白色 |
| 大于 10–15 | #E23B3B | 白色 |
| 大于 15–20 | #A31515 | 白色 |
| 未找到 | #A3ADB8 | 白色 |
SVG。 北朝上,西在左;每个网格点绘制一个圆,间距为 120 个单位、半径为 22,因此 3x3 网格使用 viewBox="0 0 360 400",5x5 网格使用 viewBox="0 0 600 640"。3x3 网格的 width 设为 360,5x5 网格设为 480,避免图示拉伸以填满栏宽;模板已将其限制为手机上的最大宽度 100%。在每个圆内打印数值(粗体、15px,居中对齐,使用 text-anchor="middle" 和 dominant-baseline="central")。店铺所在的圆再加一圈:重复绘制同一个圆,设置 fill="none"、2px 深色描边,半径为 27。在顶行上方添加“N”标签,并在底行下方添加间距说明(“点间距为 2 km”)。然后添加一个 figcaption,按阅读顺序以文本列出每个数值,因为图表中的每个数字也必须同时以文字写出。供 Agent 重复使用的 3x3 网格首行示例:
<svg viewBox="0 0 360 400" width="360" role="img" aria-label="Rank grid, 3 by 3, 2 km spacing">
<text x="180" y="18" text-anchor="middle" font-size="12" fill="#8f8f8f">N</text>
<circle cx="60" cy="80" r="22" fill="#3F9D4E"/><text x="60" y="80" text-anchor="middle" dominant-baseline="central" font-size="15" font-weight="700" fill="#fff">3.0</text>
<circle cx="180" cy="80" r="22" fill="#8BC34A"/><text x="180" y="80" text-anchor="middle" dominant-baseline="central" font-size="15" font-weight="700" fill="#fff">3.5</text>
<circle cx="300" cy="80" r="22" fill="#8BC34A"/><text x="300" y="80" text-anchor="middle" dominant-baseline="central" font-size="15" font-weight="700" fill="#fff">3.5</text>
<circle cx="180" cy="200" r="27" fill="none" stroke="#0a0a0a" stroke-width="2"/>
<text x="180" y="372" text-anchor="middle" font-size="12" fill="#8f8f8f">2 km between points</text>
</svg>
figcaption 按阅读顺序列出每个数值:“两个关键词的平均排名。西北 3.0,北 3.5,东北 3.5,西 3.0,店铺 1.5,东 3.5,西南 4.5,南 4.5,东南 3.5。”
四个统计区块,放在图示旁边或下方,每个区块包含一个标题和一个数值或简短列表:
- 平均排名:各点数值的平均值,保留两位小数。
- 排名分布:排名为 3 或更高、超过 3 至 10、超过 10 至 20,以及 20+ 的点数,使用
.bars图表。 - 每个关键词的平均排名:每个关键词占一行,列出其平均排名以及排名进入前三的点数。
- 最常排名第一的商家:统计所有关键词中各点的
topResult,并按占比列出商家。
解读方式。 按罗盘方向和距离说明可见度从哪里开始下降(用户提供地标时,例如“向南 2 km,约在第 75 街附近”;否则只说明方向),并指出该处由谁胜出,依据是 topResult。竞争对手店铺的位置可以解释大多数排名下降;若对手的坐标证实这一点,请说明。
图示。 始终将图示放在 widget figure 中。查看器会将其渲染为适配网格的实时 Google Map,并提供关键词筛选器以及每个点的弹出窗口;地图显示时会隐藏 SVG:
<figure data-widget="rank-grid">
<script type="application/json">{"spacingKm":1,"keywords":[{"keyword":"italian restaurant","points":[{"row":0,"col":0,"lat":41.7918,"lng":-88.1714,"rank":3,"top":"La Sorella di Francesca"}]}]}</script>
<svg …the drawing above…</svg>
<figcaption>…</figcaption>
</figure>
工具返回的每个点都要放进 points:包含其 row 和 col、作为 lat 的 latitude、作为 lng 的 longitude、rank(未找到该商家时为 null),以及作为 top 的 topResult.title。搜索失败(error: true)的点应省略;查看器会在该处将对应关键词显示为“搜索失败”。每个运行过的网格在 keywords 中对应一个条目,所有条目使用相同的中心点和间距。该代码块是数据:不得添加注释、尾随逗号或任何计算内容。
防护措施
- 未事先告知用户费用前,不要运行 5x5 网格或针对多个关键词运行网格——每个点都是一次付费 SERP 调用。
- 如果已有
cid或place_id,请用它匹配商家。按名称匹配会与连锁商家和名称相似的商家混淆。 - 某个网格点未显示排名,表示该商家未出现在该点返回的结果中。结合该点的
resultsCount解读:结果集已满说明排名落后;结果很少则说明 SERP 稀疏,并不能证明该商家不可见。 - 不要根据全国自然搜索指标推断本地结果包的实力。
- 绝不要建议设置评论门槛、伪造评论或在商家名称中堆砌关键词。
- 网格中心位置错误,比不运行网格更糟——花费网格额度前,请确认坐标与店面位置一致。