mcpField
S
search-console

search-console

github.com/openclaudia营销与增长722524 次安装1 周前更新
代码仓库

关于 search-console

面向 SEO 分析的 Claude skill,可通过 Google Search Console API 查询搜索表现、索引覆盖和站点地图信息,并支持组织审计流程。

主要功能

  1. 01查询词、页面及搜索指标
  2. 02按日期跟踪趋势
  3. 03检查 URL 索引状态
  4. 04列出并提交站点地图
  5. 05识别 SEO 机会与关键词蚕食

适用场景

  1. 01查看点击、展示、点击率和排名
  2. 02跟踪查询词与页面表现变化
  3. 03检查索引及站点地图状态
  4. 04发现低点击率查询词和竞争页面

安装

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

$npx skills add https://github.com/openclaudia/openclaudia-skills --skill search-console

安装后在 Claude Code 中输入/search-console确认已加载。

详细介绍

Google Search Console

从 Google Search Console API 获取搜索效果数据、索引覆盖情况和 Core Web Vitals。

前提条件

需要 Google OAuth 凭据:

  • GOOGLE_CLIENT_ID
  • GOOGLE_CLIENT_SECRET
  • 具有 https://www.googleapis.com/auth/webmasters.readonly 范围的有效 OAuth 访问令牌

在 .env、.env.local 或 ~/.claude/.env.global 中设置凭据。

获取访问令牌
# Step 1: Authorization URL (user visits in browser)
echo "https://accounts.google.com/o/oauth2/v2/auth?client_id=${GOOGLE_CLIENT_ID}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/webmasters.readonly&response_type=code&access_type=offline"

# Step 2: Exchange code for tokens
curl -s -X POST "https://oauth2.googleapis.com/token" \
  -d "code={AUTH_CODE}" \
  -d "client_id=${GOOGLE_CLIENT_ID}" \
  -d "client_secret=${GOOGLE_CLIENT_SECRET}" \
  -d "redirect_uri=urn:ietf:wg:oauth:2.0:oob" \
  -d "grant_type=authorization_code"

# Step 3: Refresh expired token
curl -s -X POST "https://oauth2.googleapis.com/token" \
  -d "refresh_token={REFRESH_TOKEN}" \
  -d "client_id=${GOOGLE_CLIENT_ID}" \
  -d "client_secret=${GOOGLE_CLIENT_SECRET}" \
  -d "grant_type=refresh_token"
列出可用网站
curl -s -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
  "https://www.googleapis.com/webmasters/v3/sites" \
  | python3 -c "
import json, sys
data = json.load(sys.stdin)
for site in data.get('siteEntry', []):
    print(f\"{site['siteUrl']}  |  Permission: {site['permissionLevel']}\")
"

网站 URL 格式可以是 https://example.com/(URL 前缀)或 sc-domain:example.com(网域资源)。


1. 搜索效果报告

核心报告:查询、页面、点击次数、展示次数、CTR 和平均排名。

API 端点
POST https://www.googleapis.com/webmasters/v3/sites/{siteUrl}/searchAnalytics/query

注意:{siteUrl} 必须经过 URL 编码(例如,https%3A%2F%2Fexample.com%2F 或 sc-domain%3Aexample.com)。

热门查询
curl -s -X POST \
  "https://www.googleapis.com/webmasters/v3/sites/sc-domain%3Aexample.com/searchAnalytics/query" \
  -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "startDate": "2024-01-01",
    "endDate": "2024-03-31",
    "dimensions": ["query"],
    "rowLimit": 50,
    "startRow": 0
  }'
热门页面
curl -s -X POST \
  "https://www.googleapis.com/webmasters/v3/sites/sc-domain%3Aexample.com/searchAnalytics/query" \
  -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "startDate": "2024-01-01",
    "endDate": "2024-03-31",
    "dimensions": ["page"],
    "rowLimit": 50
  }'
查询与页面组合
curl -s -X POST \
  "https://www.googleapis.com/webmasters/v3/sites/sc-domain%3Aexample.com/searchAnalytics/query" \
  -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "startDate": "2024-01-01",
    "endDate": "2024-03-31",
    "dimensions": ["query", "page"],
    "rowLimit": 100,
    "dimensionFilterGroups": [{
      "filters": [{
        "dimension": "page",
        "operator": "contains",
        "expression": "/blog/"
      }]
    }]
  }'
可用维度
维度说明
query搜索查询
pageURL
country国家/地区代码(ISO 3166-1 alpha-3)
deviceDESKTOP、MOBILE、TABLET
date单个日期
searchAppearance富媒体搜索结果类型
解析响应
curl -s -X POST "..." | python3 -c "
import json, sys
data = json.load(sys.stdin)
print(f\"{'Query':<50} {'Clicks':>8} {'Impr':>8} {'CTR':>8} {'Pos':>6}\")
print('-' * 82)
for row in data.get('rows', []):
    keys = ' + '.join(row.get('keys', []))
    print(f\"{keys:<50} {row['clicks']:>8} {row['impressions']:>8} {row['ctr']*100:>7.1f}% {row['position']:>6.1f}\")
"

2. 按日期查看搜索效果

跟踪查询和页面的每日趋势。

curl -s -X POST \
  "https://www.googleapis.com/webmasters/v3/sites/sc-domain%3Aexample.com/searchAnalytics/query" \
  -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "startDate": "2024-01-01",
    "endDate": "2024-03-31",
    "dimensions": ["date"],
    "rowLimit": 1000
  }'

若要随时间跟踪特定查询:

curl -s -X POST \
  "https://www.googleapis.com/webmasters/v3/sites/sc-domain%3Aexample.com/searchAnalytics/query" \
  -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "startDate": "2024-01-01",
    "endDate": "2024-03-31",
    "dimensions": ["date"],
    "dimensionFilterGroups": [{
      "filters": [{
        "dimension": "query",
        "operator": "equals",
        "expression": "your target keyword"
      }]
    }]
  }'

3. 索引覆盖情况(URL 检查 API)

检查特定 URL 是否已编入索引。

端点
POST https://searchconsole.googleapis.com/v1/urlInspection/index:inspect
curl 示例
curl -s -X POST \
  "https://searchconsole.googleapis.com/v1/urlInspection/index:inspect" \
  -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "inspectionUrl": "https://example.com/page-to-check",
    "siteUrl": "sc-domain:example.com"
  }'
响应字段
字段说明
inspectionResult.indexStatusResult.coverageStateSubmitted and indexed、Crawled - currently not indexed 等
inspectionResult.indexStatusResult.robotsTxtStateALLOWED 或 DISALLOWED
inspectionResult.indexStatusResult.indexingStateINDEXING_ALLOWED 或 INDEXING_NOT_ALLOWED
inspectionResult.indexStatusResult.lastCrawlTimeGooglebot 上次抓取的时间
inspectionResult.indexStatusResult.crawledAsDESKTOP 或 MOBILE
inspectionResult.mobileUsabilityResult.verdictPASS、FAIL 或 VERDICT_UNSPECIFIED

4. 站点地图

列出站点地图并检查其状态。

列出站点地图
curl -s -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
  "https://www.googleapis.com/webmasters/v3/sites/sc-domain%3Aexample.com/sitemaps" \
  | python3 -c "
import json, sys
data = json.load(sys.stdin)
for sm in data.get('sitemap', []):
    print(f\"URL: {sm['path']}\")
    print(f\"  Type: {sm.get('type','')}  |  Submitted: {sm.get('lastSubmitted','')}\")
    print(f\"  URLs discovered: {sm.get('contents',[{}])[0].get('submitted','?')}  |  Indexed: {sm.get('contents',[{}])[0].get('indexed','?')}\")
    print()
"
提交站点地图
curl -s -X PUT -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
  "https://www.googleapis.com/webmasters/v3/sites/sc-domain%3Aexample.com/sitemaps/https%3A%2F%2Fexample.com%2Fsitemap.xml"

5. 发现优化机会

利用 Search Console 数据发现 SEO 优化机会。

易于实现的优化:高展示次数、低 CTR

展示次数较多但 CTR 较低的查询,表明标题/说明需要优化。

# Pull queries, then filter for: impressions > 100 AND ctr < 0.03 AND position < 20
curl -s -X POST \
  "https://www.googleapis.com/webmasters/v3/sites/sc-domain%3Aexample.com/searchAnalytics/query" \
  -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "startDate": "2024-01-01",
    "endDate": "2024-03-31",
    "dimensions": ["query", "page"],
    "rowLimit": 1000
  }' | python3 -c "
import json, sys
data = json.load(sys.stdin)
print('== Low CTR Opportunities (High impressions, low CTR, good position) ==')
print(f\"{'Query':<40} {'Page':<40} {'Impr':>6} {'CTR':>7} {'Pos':>5}\")
for row in data.get('rows', []):
    if row['impressions'] > 100 and row['ctr'] < 0.03 and row['position'] < 20:
        print(f\"{row['keys'][0]:<40} {row['keys'][1][-40:]:<40} {row['impressions']:>6} {row['ctr']*100:>6.1f}% {row['position']:>5.1f}\")
"
有望提升的关键词:排名 5-20

排名在搜索结果第 1-2 页的查询,可通过内容优化提升至前 5 名。

# Filter for position between 5 and 20 with decent impressions
curl -s -X POST "..." | python3 -c "
import json, sys
data = json.load(sys.stdin)
print('== Striking Distance Keywords (Position 5-20) ==')
opps = [r for r in data.get('rows',[]) if 5 <= r['position'] <= 20 and r['impressions'] > 50]
opps.sort(key=lambda x: x['impressions'], reverse=True)
for row in opps[:30]:
    print(f\"{row['keys'][0]:<50} Pos: {row['position']:>5.1f}  Impr: {row['impressions']:>6}  Clicks: {row['clicks']:>4}\")
"
检测关键词蚕食

查找多个页面竞争同一关键词的查询。

# Pull query+page data, then group by query to find duplicates
curl -s -X POST "..." | python3 -c "
import json, sys
from collections import defaultdict
data = json.load(sys.stdin)
query_pages = defaultdict(list)
for row in data.get('rows', []):
    query_pages[row['keys'][0]].append({
        'page': row['keys'][1],
        'clicks': row['clicks'],
        'impressions': row['impressions'],
        'position': row['position']
    })
print('== Keyword Cannibalization (multiple pages for same query) ==')
for query, pages in sorted(query_pages.items(), key=lambda x: -sum(p['impressions'] for p in x[1])):
    if len(pages) > 1:
        total_impr = sum(p['impressions'] for p in pages)
        if total_impr > 100:
            print(f\"\nQuery: {query} ({total_impr} total impressions)\")
            for p in sorted(pages, key=lambda x: -x['impressions']):
                print(f\"  {p['page'][-60:]}  Pos: {p['position']:.1f}  Impr: {p['impressions']}  Clicks: {p['clicks']}\")
"

工作流:完整的搜索效果审计

收到完整 GSC 审计请求时:

  1. 整体指标:过去 90 天与前 90 天的点击总数、展示总数、平均 CTR 和平均排名
  2. 前 30 个查询:按点击次数排序,并列出 CTR 和排名
  3. 前 20 个页面:按点击次数排序,并列出 CTR 和排名
  4. 设备细分:桌面设备与移动设备的效果对比
  5. 易于实现的优化:高展示次数、低 CTR 的机会
  6. 有望提升的关键词:排名 5-20 且有优化潜力的关键词
  7. 关键词蚕食:存在多个竞争页面的查询
  8. 索引覆盖情况:抽查重要 URL
  9. 站点地图健康状况:确认站点地图已提交并编入索引
报告格式
## Search Console Audit: {domain}
### Period: {date range}

### Summary
| Metric | Current | Previous | Change |
|--------|---------|----------|--------|
| Clicks | X | Y | +Z% |
| Impressions | X | Y | +Z% |
| Avg CTR | X% | Y% | +Z pp |
| Avg Position | X | Y | +Z |

### Top Queries
| Query | Clicks | Impressions | CTR | Position |
|-------|--------|-------------|-----|----------|
| ...   | ...    | ...         | ... | ...      |

### Optimization Opportunities

#### Title/Description Optimization (High Impressions, Low CTR)
1. "{query}" - {impressions} impressions, {ctr}% CTR, position {pos}
   - Page: {url}
   - Recommendation: ...

#### Content Optimization (Striking Distance)
1. "{query}" - position {pos}, {impressions} impressions
   - Action: Add {query} to H2, expand section on {topic}

#### Cannibalization Fixes
1. "{query}" appears on {n} pages
   - Consolidate to: {best_url}
   - Redirect/noindex: {other_urls}

速率限制

  • Search Analytics API:每分钟 1,200 次查询
  • URL Inspection API:每个资源每天 2,000 次检查
  • 数据时效性:搜索数据通常会延迟 2-3 天

常见错误

错误原因解决方法
403无权访问此资源在 GSC 中验证所有权
400日期范围无效日期必须在过去 16 个月内
空行没有符合筛选条件的数据扩大日期范围或移除筛选条件

评论

支持 Markdown