Skip to main content

google-search-console

Connect Google Search Console to pull real click, impression, CTR, and ranking position data for keyword research. This skill walks the user through creating a Google Cloud project, authenticating via OAuth, and querying the Search Console API — all from Claude Code.

来源信息

仓库
Bomx/seo-keyword-research
最近来源活动
2026年4月10日 14:30
检测到的 SKILL.md 语言
英语
星标
22
分支
1

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
google-search-console
description
Connect Google Search Console to pull real click, impression, CTR, and ranking position data for keyword research. This skill walks the user through creating a Google Cloud project, authenticating via OAuth, and querying the Search Console API — all from Claude Code.
metadata
{"clawdbot":{"requires":{"env":"[Truncated]"}}}
## FIRST TIME READING THIS SKILL? STOP AND READ THIS SECTION TO THE USER. Before running any commands, explain the following to the user: **What Google Search Console gives you:** Google Search Console (GSC) contains your actual search performance data — every keyword Google shows your site for, how many people clicked, your average position, and which pages rank. This data is free and comes directly from Google. Combining it with keyword research lets you find quick wins (keywords you already rank for but could optimize) and validate which keywords actually drive traffic. **What you need:** A Google Cloud project with OAuth credentials. The project does NOT need to be published or verified by Google — it stays in "Testing" mode. You add your own email as a test user and that's it. No approval process, no review, no fees. **How long it takes:** About 5 minutes to set up the Google Cloud project. After that, you run a one-time auth script and you're done. --- ## Setup: Create a Google Cloud Project Follow these steps to create OAuth credentials. Claude Code cannot do this for you — it requires clicking through the Google Cloud Console UI. ### Step 1: Create the project 1. Go to [console.cloud.google.com](https://console.cloud.google.com) 2. Click the project dropdown at the top and select "New Project" 3. Name it anything (e.g. "SEO Keyword Research") 4. Click "Create" ### Step 2: Enable the Search Console API 1. In your new project, go to **APIs & Services > Library** 2. Search for "Google Search Console API" 3. Click it and press **Enable** ### Step 3: Configure the OAuth consent screen 1. Go to **APIs & Services > OAuth consent screen** 2. Select **External** user type, click Create 3. Fill in the required fields: - App name: anything (e.g. "SEO Research") - User support email: your email - Developer contact email: your email 4. Click **Save and Continue** 5. On the Scopes page, click **Add or Remove Scopes** 6. Search for `webmasters.readonly` and check it 7. Click **Update**, then **Save and Continue** 8. On the Test Users page, click **Add Users** 9. Add your own Google email address (the one that has Search Console access) 10. Click **Save and Continue**, then **Back to Dashboard** The app stays in "Testing" mode. Only the test users you added can authorize it. No verification or approval from Google is needed. ### Step 4: Create OAuth credentials 1. Go to **APIs & Services > Credentials** 2. Click **Create Credentials > OAuth client ID** 3. Application type: **Web application** 4. Name: anything (e.g. "SEO Research Client") 5. Under **Authorized redirect URIs**, add: `http://localhost:8080/callback` 6. Click **Create** 7. Copy the **Client ID** and **Client Secret** ### Step 5: Set environment variables Add these to your `.env` file in the repo root (create it from `.env.example` if you haven't already): ``` GOOGLE_CLIENT_ID=your_client_id_here GOOGLE_CLIENT_SECRET=your_client_secret_here ``` The `.env` file is gitignored — your credentials will never be committed. --- ## Authentication: Get Your Refresh Token After setting the client ID and secret, Claude Code will generate and run a small Python script that opens a browser window for you to authorize access. You click "Allow", and the script captures your refresh token. **Claude Code: generate and run the following script when the user is ready to authenticate.** ```python """ Google Search Console OAuth Flow Run this script once to get a refresh token. After that, store the token as an environment variable and this script is no longer needed. """ import http.server import json import os import sys import urllib.parse import webbrowser try: import requests except ImportError: os.system(f"{sys.executable} -m pip install requests") import requests CLIENT_ID = os.environ.get("GOOGLE_CLIENT_ID") CLIENT_SECRET = os.environ.get("GOOGLE_CLIENT_SECRET") REDIRECT_URI = "http://localhost:8080/callback" SCOPE = "https://www.googleapis.com/auth/webmasters.readonly" AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth" TOKEN_URL = "https://oauth2.googleapis.com/token" if not CLIENT_ID or not CLIENT_SECRET: print("ERROR: Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET environment variables first.") sys.exit(1) auth_params = urllib.parse.urlencode({ "client_id": CLIENT_ID, "redirect_uri": REDIRECT_URI, "response_type": "code", "scope": SCOPE, "access_type": "offline", "prompt": "consent", }) consent_url = f"{AUTH_URL}?{auth_params}" tokens = {} class CallbackHandler(http.server.BaseHTTPRequestHandler): def do_GET(self): query = urllib.parse.urlparse(self.path).query params = urllib.parse.parse_qs(query) if "code" not in params: self.send_response(400) self.end_headers() self.wfile.write(b"No authorization code received.") return code = params["code"][0] resp = requests.post(TOKEN_URL, data={ "code": code, "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "redirect_uri": REDIRECT_URI, "grant_type": "authorization_code", }) data = resp.json() if "refresh_token" not in data: self.send_response(500) self.end_headers() self.wfile.write(f"Token exchange failed: {json.dumps(data)}".encode()) return tokens["access_token"] = data["access_token"] tokens["refresh_token"] = data["refresh_token"] self.send_response(200) self.send_header("Content-Type", "text/html") self.end_headers() self.wfile.write(b"<h1>Success!</h1><p>You can close this tab and go back to your terminal.</p>") def log_message(self, format, *args): pass # Suppress server logs print(f"\nOpening browser for Google authorization...\n") print(f"If the browser doesn't open, visit this URL:\n{consent_url}\n") webbrowser.open(consent_url) server = http.server.HTTPServer(("localhost", 8080), CallbackHandler) server.handle_request() # Handle exactly one request (the callback) server.server_close() if tokens: print("\n" + "=" * 60) print("SUCCESS! Save these environment variables:\n") print(f'export GSC_ACCESS_TOKEN="{tokens["access_token"]}"') print(f'export GSC_REFRESH_TOKEN="{tokens["refresh_token"]}"') print(f'export GOOGLE_CLIENT_ID="{CLIENT_ID}"') print(f'export GOOGLE_CLIENT_SECRET="{CLIENT_SECRET}"') print("\n" + "=" * 60) print("\nAdd these to your .env file in the repo root (it's gitignored).") print("The access token expires in ~1 hour. The refresh token is permanent.") print("Claude Code will automatically refresh the access token when needed.") else: print("\nAuthentication failed. Check the error above and try again.") ``` **After running the script:** The user copies the printed `export` lines into their `.env` file or shell profile. From then on, Claude Code can query GSC using the refresh token. --- ## Token Refresh Access tokens expire after ~1 hour. Use this to refresh: ```bash curl -s -X POST https://oauth2.googleapis.com/token \ -d "client_id=$GOOGLE_CLIENT_ID" \ -d "client_secret=$GOOGLE_CLIENT_SECRET" \ -d "refresh_token=$GSC_REFRESH_TOKEN" \ -d "grant_type=refresh_token" | jq . ``` Returns a new `access_token`. The `refresh_token` does not change. When making API calls, always try the request first. If you get a 401, refresh the token and retry. --- ## API Reference Base URL: `https://www.googleapis.com/webmasters/v3` All requests require: `Authorization: Bearer $GSC_ACCESS_TOKEN` ### List Sites ```bash curl -s -H "Authorization: Bearer $GSC_ACCESS_TOKEN" \ "https://www.googleapis.com/webmasters/v3/sites" | jq . ``` Returns all Search Console properties the user has access to. Use the `siteUrl` value (e.g. `https://example.com/` or `sc-domain:example.com`) in subsequent calls. ### Search Analytics (Top Queries) ```bash SITE_URL="https://example.com/" # URL-encode if needed curl -s -X POST \ -H "Authorization: Bearer $GSC_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ "https://www.googleapis.com/webmasters/v3/sites/$(python3 -c 'import urllib.parse; print(urllib.parse.quote(\"'$SITE_URL'\", safe=\"\"))')/searchAnalytics/query" \ -d '{ "startDate": "'$(date -v-28d +%Y-%m-%d 2>/dev/null || date -d "28 days ago" +%Y-%m-%d)'", "endDate": "'$(date +%Y-%m-%d)'", "dimensions": ["query"], "rowLimit": 50, "dataState": "final" }' | jq . ``` **Response:** ```json { "rows": [ { "keys": ["best seo tool"], "clicks": 142, "impressions": 3200, "ctr": 0.044, "position": 8.2 } ] } ``` Fields: - `keys` -- the search query - `clicks` -- number of clicks from Google search - `impressions` -- how many times the page appeared in results - `ctr` -- click-through rate (clicks / impressions) - `position` -- average ranking position (1 = top) ### Search Analytics (Top Pages) Same endpoint, change dimension to `page`: ```bash curl -s -X POST \ -H "Authorization: Bearer $GSC_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ "https://www.googleapis.com/webmasters/v3/sites/$(python3 -c 'import urllib.parse; print(urllib.parse.quote(\"'$SITE_URL'\", safe=\"\"))')/searchAnalytics/query" \ -d '{ "startDate": "'$(date -v-28d +%Y-%m-%d 2>/dev/null || date -d "28 days ago" +%Y-%m-%d)'", "endDate": "'$(date +%Y-%m-%d)'", "dimensions": ["page"], "rowLimit": 25 }' | jq . ``` ### Search Analytics (Query + Page combined) Get which queries drive traffic to which pages: ```bash curl -s -X POST \ -H "Authorization: Bearer $GSC_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ "https://www.googleapis.com/webmasters/v3/sites/$(python3 -c 'import urllib.parse; print(urllib.parse.quote(\"'$SITE_URL'\", safe=\"\"))')/searchAnalytics/query" \ -d '{ "startDate": "'$(date -v-28d +%Y-%m-%d 2>/dev/null || date -d "28 days ago" +%Y-%m-%d)'", "endDate": "'$(date +%Y-%m-%d)'", "dimensions": ["query", "page"], "rowLimit": 100 }' | jq . ``` ### List Sitemaps ```bash curl -s -H "Authorization: Bearer $GSC_ACCESS_TOKEN" \ "https://www.googleapis.com/webmasters/v3/sites/$(python3 -c 'import urllib.parse; print(urllib.parse.quote(\"'$SITE_URL'\", safe=\"\"))')/sitemaps" | jq . ``` Returns sitemap info including indexed page counts. --- ## How to Use GSC Data in Keyword Research When GSC credentials are available, use the data to enrich keyword research: 1. **Pull top 50 queries** from the last 28 days 2. **Identify quick wins:** keywords where position is 5-20 (page 1-2 but not top 3). These are keywords you already rank for and could push higher with a targeted article. 3. **Validate keyword ideas:** Cross-reference discovered keywords against GSC data. If a keyword already gets impressions, it confirms real search demand. 4. **Find content gaps:** Look for queries with high impressions but low CTR — the page might need a better title/meta description, or a dedicated article. 5. **Prioritize by real data:** Keywords you already rank for are easier to improve than starting from zero. Add a "GSC Insights" section to the HTML dashboard when this data is available: - Table of current rankings with clicks, impressions, CTR, position - Quick wins highlighted (position 5-20 with decent impressions) - Content gaps (high impressions, low CTR) --- ## Rate Limits The Search Console API allows approximately 1,200 queries per minute per project. For keyword research, you'll typically make 2-5 calls total, so rate limits are not a concern. --- ## Troubleshooting | Issue | Solution | |-------|----------| | "Access blocked: This app's request is invalid" | Make sure you added `http://localhost:8080/callback` as an authorized redirect URI |
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看